【问题标题】:Add Filter to Loop and Filter by month将过滤器添加到循环并按月过滤
【发布时间】:2018-02-05 13:18:38
【问题描述】:

我可以将过滤器添加到过滤月份的日期吗?

我知道我可以使用过滤器 ,但这是针对特定日期的过滤器。我想做的是按月过滤,即 ?

这可能吗?

韦斯利

【问题讨论】:

    标签: silverstripe


    【解决方案1】:

    为了更高级的过滤,我通常在模型上创建一个处理过滤的函数

    /**
     * Courses that take place in given month.
     * 
     * @param   int         $month
     * @return  DataList
     */
    public function CoursesByMonth($month)
    {
        $year   = date('Y');
        $day    = date('d');
        $endDay = cal_days_in_month(CAL_GREGORIAN, $month, $year);
    
        return $this->Courses()->filter(
            [
                'DateTo:GreaterThan' => $year . '-' . $month . '-' . $day . ' 00:00:00',
                'DateTo:LessThan' => $year . '-' . $month . '-' . $endDay . ' 23:59:59',
            ]
        );
    }
    

    然后你可以像这样在你的模板中使用它

    <% loop $CoursesByMonth(2) %>
    

    我还没有实际测试过函数本身,所以很有可能它不起作用,但希望这能让你了解如何实现你想要做的事情。

    【讨论】:

    • 感谢您的帮助 Janne Klouman。我今晚会试试这个。
    【解决方案2】:

    不知怎的,我没有得到这个工作。我认为这与我当前的设置有关。让我给你一些背景知识。

    所以我在 mysite/code 中有 3 个 php 文件(以下文件)。这些文件允许您创建具有不同课程日期的课程。这些课程应该按月分组并显示在主页(HomePage.ss)上,但不知何故我无法完成。所以目前我已经在 html 中添加了一些过滤器,这些过滤器可以部分工作。因此显示月份,但课程不是按月分组,而是按课程名称分组。在这个问题的底部,您将看到我的解决方法。

    我错过了什么或做错了什么?

    1. Courses.php

        <?php
        class Course extends DataObject {
            private static $db = array(
                'DateTo' => 'Date',
                'DateFrom' => 'Date',
            );
            private static $has_one = array(
                'Project' => 'Project'
            );
    
        }
    

    2。项目.php

    <?php
    class Project extends Page {
        private static $has_many = array(
            'Courses' => 'Course'
        );
    
    
    private static $db = array(
            'courses_Check' => 'Boolean(1)',
            'courses_Title' => 'Text',
            'courses_Description' => 'HTMLText',
            'courses_TargetAudience' => 'Text',
            'courses_Goal' => 'Text',
            'courses_Length' => 'Int',
            'courses_Costs' => 'Currency',
            'courses_Content' => 'HTMLText',
            'courses_Learnings' => 'HTMLText',
            'courses_Accreditation' => 'HTMLText',
            'courses_Location' => 'HTMLText',
            'courses_AdditionalInfo' => 'HTMLText',     
    
        );
    
     public function getCMSFields() {
            // Get the fields from the parent implementation
            $fields = parent::getCMSFields();
    
            $fields->addFieldToTab('Root.Main', new TextField('courses_Title','Cursustitel'),'Content');        
            $fields->addFieldToTab('Root.Main', new HTMLEditorField('courses_Description','Cursus beschrijving'),'Content');
            $fields->addFieldToTab('Root.Main', new TextField('courses_TargetAudience','Doelgroep'),'Content');
            $fields->addFieldToTab('Root.Main', new TextField('courses_Goal','Doel'),'Content');
            $fields->addFieldToTab('Root.Main', new NumericField('courses_Length','Cursusduur aantal dagen'),'Content');
            $fields->addFieldToTab('Root.Main', new CurrencyField('courses_Costs','Kosten van de cursus'),'Content');
            $fields->addFieldToTab('Root.Main', new HTMLEditorField('courses_Content','Inhoud Cursus'),'Content');
            $fields->addFieldToTab('Root.Main', new HTMLEditorField('courses_Learnings','Leerdoelen'),'Content');
            $fields->addFieldToTab('Root.Main', new HTMLEditorField('courses_Accreditation','Accreditatie'),'Content');
            $fields->addFieldToTab('Root.Main', new HTMLEditorField('courses_Location','Cursuslocatie'),'Content');
            $fields->addFieldToTab('Root.Main', new HTMLEditorField('courses_AdditionalInfo','Meer informatie'),'Content');
    
            // Create a default configuration for the new GridField, allowing record editing
            $config = GridFieldConfig_RelationEditor::create();
            // Set the names and data for our gridfield columns
            $config->getComponentByType('GridFieldDataColumns')->setDisplayFields(array(
                'DateTo' => 'Datum van',
                'DateFrom' => 'Datum tot',
                'Project.Title'=> 'Cursusnaam' // Retrieve from a has-one relationship
            ));    
            // Create a gridfield to hold the course relationship    
            $studentsField = new GridField(
                'Cursus Data', // Field name
                'Cursus', // Field title
                $this->Courses(), // List of all related students
                $config
            );        
            // Create a tab named "Courses" and add our field to it
            $fields->addFieldToTab('Root.Cursus data', $studentsField);
    
            // Remove Content Field
            $fields->removeFieldFromTab("Root.Main","Content");
            $fields->removeFieldFromTab("Root.Main","Metadata");
    
            return $fields;
    
        }
    

    3。 ProjectHolder.php

    <?php
    class ProjectHolder extends Page {
        private static $allowed_children = array(
            'Project'
        );
    }
    class ProjectHolder_Controller extends Page_Controller {
    }
    

    4.我的解决方法

          <div class="half">
            <% loop $Projects %>
            <% loop $Courses.Limit(1) %>
            <div class="tab">
              <% if DateTo.Month == "January" %>
              <input id="tab-one" type="checkbox" name="tabs">
              <label for="tab-one">January</label>
              <% else_if DateTo.Month == "February" %>
              <input id="tab-two" type="checkbox" name="tabs">
              <label for="tab-two">February</label>
              <% else_if DateTo.Month == "March" %>
              <input id="tab-three" type="checkbox" name="tabs">
              <label for="tab-three">March</label>
              <% else_if DateTo.Month == "April" %>
              <input id="tab-four" type="checkbox" name="tabs">
              <label for="tab-four">April</label>
              <% else_if DateTo.Month == "May" %>
              <input id="tab-five" type="checkbox" name="tabs">
              <label for="tab-five">May</label>
              <% else_if DateTo.Month == "June" %>
              <input id="tab-six" type="checkbox" name="tabs">
              <label for="tab-six">June</label>
              <% else_if DateTo.Month == "July" %>
              <input id="tab-seven" type="checkbox" name="tabs">
              <label for="tab-seven">July</label>
              <% else_if DateTo.Month == "August" %>
              <input id="tab-eight" type="checkbox" name="tabs">
              <label for="tab-eight">August</label>
              <% else_if DateTo.Month == "September" %>
              <input id="tab-nine" type="checkbox" name="tabs">
              <label for="tab-nine">September</label>
              <% else_if DateTo.Month == "October" %>
              <input id="tab-ten" type="checkbox" name="tabs">
              <label for="tab-ten">October</label>
              <% else_if DateTo.Month == "November" %>
              <input id="tab-eleven" type="checkbox" name="tabs">
              <label for="tab-eleven">November</label>
              <% else_if DateTo.Month == "December" %>
              <input id="tab-twelve" type="checkbox" name="tabs">
              <label for="tab-twelve">December</label>
              <% end_if %>
              <% end_loop %>
              <div class="tab-content">
                <ul style="line-height:1.8em; margin:10px 0;">
                  <% loop $Courses.Sort(DateTo, ASC)  %>
                  <li><a href="$URLSegment.Up">$DateTo.DayOfMonth $DateTo.Month $DateTo.ShortMonth - $DateFrom.DayOfMonth $DateFrom.ShortMonth: $Project.Title</a></li>
                  <% end_loop %>
                </ul>
              </div>
            </div>
            <% end_loop %>
          </div>
    

    【讨论】:

    • 将这些添加到问题中,而不是作为答案!
    【解决方案3】:

    模板中的业务逻辑过多 - 您需要简化。 从上面的代码中我不太明白 $Projects 循环的来源,但我的方法如下所示,在 PHP 端移动尽可能多的逻辑。所以将下面的代码添加到 Project 类中:

    public function CoursesByMonth() {
      $months = array();
    
      foreach ($this->Courses() as $course) {
        $month = $course->DateTo->Month();
    
        if (!in_array($month, months)) {
          $months[] = $month
        }
      }
    
      // at this point you have all the distinct months, but the array it's not sorted by month, so let's sort it
    
      $months_sorted = array();
    
      foreach($months as $month) {
        $m = date_parse($month);
        $months_sorted[$m['month']] = $month;
      }
      ksort($months_sorted);
    
      // at this point you have a simple PHP array, with all the distinct months from all the courses, in the proper order
      // but this is useless in Silverstripe templates - so we need to do some other stuff here
    
      $result = new ArrayList();
      foreach ($months_sorted as $month) {
        $courses_for_current_month = $this->Courses()->filter('DateTo.Month' => $month);
        $result->push(new ArrayData(
          'Month'   =>  $month,
          'Courses' =>  $courses_for_current_month;
        ));
      }
    
      return $result;
    }
    

    ...然后在模板中有这样的东西:

    <div class="half">
      <% loop $Projects %>
        <% loop $CoursesByMonth %>
        <div class="tab">
          <input id="tab-{$Pos(1)}" type="checkbox" name="tabs">
          <label for="tab-{$Pos(1)}">$Month</label>
        <% end_loop %>
    
        <div class="tab-content">
          <ul style="line-height:1.8em; margin:10px 0;">
            <% loop $CoursesByMonth.Courses.Sort('DateTo', 'ASC')  %>
            <li><a href="$URLSegment.Up">$DateTo.DayOfMonth $DateTo.Month $DateTo.ShortMonth - $DateFrom.DayOfMonth $DateFrom.ShortMonth: $Project.Title</a></li>
            <% end_loop %>
          </ul>
        </div> <!--/ .tab-content -->
      </div> <!--/ .tab -->
      <% end_loop %>
    </div> <!--/ .half -->
    

    我没有测试所有这些,但据我了解,这是我可以想出的代码。 即使它不起作用,它也会给你一些我很确定的想法。

    【讨论】:

      猜你喜欢
      • 2017-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-22
      • 2016-02-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多