Display list of elements grouped by year and by month in TYPO3 Fluid

前端 未结 3 1805
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-12 04:49

I have a model where one field is a date. I want to display elements from that model, grouped by year and by month, like this:

== 2013 ==
=== April ===
* Ele         


        
3条回答
  •  盖世英雄少女心
    2020-12-12 05:21

    Finally, I solved this problem by using a custom ViewHelper, derived from GroupedBy ViewHelper, inspired from https://gist.github.com/daKmoR/1287203, and adapted for extbase.


    Here is the complete code for the ViewHelper, located in MyExt/Classes/ViewHelpers/GropuedForDateTimeViewHelper.php

    
     * // $items = array(
     * //   array('name' => 'apple', 'start' => DateTimeObject[2011-10-13 00:15:00]), 
     * //   array('name' => 'orange', 'start' => DateTimeObject[2011-12-01 00:10:00]),
     * //   array('name' => 'banana', 'start' => DateTimeObject[2008-05-24 00:40:00])
     * // );
     * 
     *   {year -> f:format.date(format: 'Y')}
     *   
     *     {item.name}
     *   
     * 
     * 
     *
     * Output:
     * 2011
     *   apple
     *   orange
     * 2010
     *   banana
     *
     * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
     * @api
     */
    class GroupedForDateTimeViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper {
    
        /**
         * Iterates through elements of $each and renders child nodes
         *
         * @param array $each The array or Tx_Extbase_Persistence_ObjectStorage to iterated over
         * @param string $as The name of the iteration variable
         * @param string $groupBy Group by this property
         * @param string $groupKey The name of the variable to store the current group
         * @param string $format The format for the datetime
         * @param string $dateTimeKey The name of the variable to store the current datetime
         * @throws \TYPO3\CMS\Fluid\Core\ViewHelper\Exception
         * @return string Rendered string
         * @author Bastian Waidelich 
         * @author Thomas Allmer 
         * @api
         */
        public function render($each, $as, $groupBy, $groupKey = 'groupKey', $format = '', $dateTimeKey = 'dateTimeKey') {
            $output = '';
            if ($each === NULL) {
                return '';
            }
    
            if (is_object($each)) {
                if (!$each instanceof \Traversable) {
                    throw new \TYPO3\CMS\Fluid\Core\ViewHelper\Exception('GroupedForViewHelper only supports arrays and objects implementing Traversable interface' , 1253108907);
                }
                $each = iterator_to_array($each);
            }
    
            $groups = $this->groupElements($each, $groupBy, $format);
    
            foreach ($groups['values'] as $currentGroupIndex => $group) {
                $this->templateVariableContainer->add($groupKey, $groups['keys'][$currentGroupIndex]);
                $this->templateVariableContainer->add($dateTimeKey, $groups['dateTimeKeys'][$currentGroupIndex]);
                $this->templateVariableContainer->add($as, $group);
                $output .= $this->renderChildren();
                $this->templateVariableContainer->remove($groupKey);
                $this->templateVariableContainer->remove($dateTimeKey);
                $this->templateVariableContainer->remove($as);
            }
            return $output;
        }
    
        /**
         * Groups the given array by the specified groupBy property and format for the datetime.
         *
         * @param array $elements The array / traversable object to be grouped
         * @param string $groupBy Group by this property
         * @param string $format The format for the datetime
         * @throws \TYPO3\CMS\Fluid\Core\ViewHelper\Exception
         * @return array The grouped array in the form array('keys' => array('key1' => [key1value], 'key2' => [key2value], ...), 'values' => array('key1' => array([key1value] => [element1]), ...), ...)
         * @author Bastian Waidelich 
         */
        protected function groupElements(array $elements, $groupBy, $format) {
            $groups = array('keys' => array(), 'values' => array());
            foreach ($elements as $key => $value) {
                if (is_array($value)) {
                    $currentGroupIndex = isset($value[$groupBy]) ? $value[$groupBy] : NULL;
                } elseif (is_object($value)) {
                    $currentGroupIndex = \TYPO3\CMS\Extbase\Reflection\ObjectAccess::getPropertyPath($value, $groupBy);
                } else {
                    throw new \TYPO3\CMS\Fluid\Core\ViewHelper\Exception('GroupedForViewHelper only supports multi-dimensional arrays and objects' , 1253120365);
                }
                if (strpos($format, '%') !== FALSE) {
                    $formatedDatetime = strftime($format, $currentGroupIndex->format('U'));
                } else {
                    $formatedDatetime = $currentGroupIndex->format($format);
                }
                $groups['dateTimeKeys'][$formatedDatetime] = $currentGroupIndex;
    
                if (strpos($format, '%') !== FALSE) {
                    $currentGroupIndex = strftime($format, $currentGroupIndex->format('U'));
                } else {
                    $currentGroupIndex = $currentGroupIndex->format($format);
                }
    
                $currentGroupKeyValue = $currentGroupIndex;
                if (is_object($currentGroupIndex)) {
                    $currentGroupIndex = spl_object_hash($currentGroupIndex);
                }
                $groups['keys'][$currentGroupIndex] = $currentGroupKeyValue;
                $groups['values'][$currentGroupIndex][$key] = $value;
            }
            return $groups;
        }
    }
    
    ?>
    

    And here is an example of a template using it:

    {namespace m=vendor\MyExt\ViewHelpers}
    
    
    
        
            

    {year}

    {month}

    • {myitem}

提交回复
热议问题