Reputation: 301
i would like to get the month of my etbase item. In the database there is the crdate. I would like to use this and only get the month. My value is always empty.
/**
* @var string
*/
protected $month = '';
/**
* Returns the month
*
* @return string $month
*/
public function getMonth()
{
return $this->month;
}
/**
* Sets the month
*
* @param string $month
* @return void
*/
public function setMonth(string $month)
{
$month = 'dsds';
$this->month = $month;
}
In my TCA if added this:
'month' => [
'config' => [
'type' => 'passthrough',
],
],
How can i get the month of the item? I would like to group it in my fluid template.
EDIT:
Ive tried it with a ViewHelper
<?php
namespace Ext\XY\ViewHelpers;
/* *
* This script belongs to the FLOW3 package "Fluid". *
* *
* It is free software; you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation, either version 3 of the License, or (at your *
* option) any later version. *
* *
* This script is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- *
* TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser *
* General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with the script. *
* If not, see http://www.gnu.org/licenses/lgpl.html *
* *
* The TYPO3 project - inspiring people to share! *
* */
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
use TYPO3Fluid\Fluid\Core\Variables\VariableExtractor;
use TYPO3Fluid\Fluid\Core\ViewHelper;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
/**
* Grouped loop view helper for Datetime values.
* Loops through the specified values
*
* = Examples =
*
* <code title="Simple">
* // $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])
* // );
* <a:groupedForDateTime each="{items}" as="itemsByYear" groupBy="start" format="Y" groupKey="year">
* {year -> f:format.date(format: 'Y')}
* <f:for each="{itemsByYear}" as="item">
* {item.name}
* </f:for>
* </a:groupedForDateTime>
* </code>
*
* 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 AbstractViewHelper
{
use CompileWithRenderStatic;
/**
* @var boolean
*/
protected $escapeOutput = false;
/**
* @return void
*/
public function initializeArguments()
{
parent::initializeArguments();
$this->registerArgument('each', 'array', 'The array or \SplObjectStorage to iterated over', true);
$this->registerArgument('as', 'string', 'The name of the iteration variable', true);
$this->registerArgument('groupBy', 'string', 'Group by this property', true);
$this->registerArgument('format', 'string', 'The format for the datetime', false);
$this->registerArgument('groupKey', 'string', 'The name of the variable to store the current group', false, 'groupKey');
$this->registerArgument('dateTimeKey', 'string', 'dateTimeKey The name of the variable to store the current datetime', false);
}
/**
* @param array $arguments
* @param \Closure $renderChildrenClosure
* @param RenderingContextInterface $renderingContext
* @return mixed
*/
public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
{
$each = $arguments['each'];
$as = $arguments['as'];
$groupBy = $arguments['groupBy'];
$groupKey = $arguments['groupKey'];
$format = $arguments['format'];
$dateTimeKey = $arguments['dateTimeKey'];
$output = '';
if ($each === null) {
return '';
}
if (is_object($each)) {
if (!$each instanceof \Traversable) {
throw new ViewHelper\Exception('GroupedForViewHelper only supports arrays and objects implementing \Traversable interface', 1253108907);
}
$each = iterator_to_array($each);
}
$groups = static::groupElements($each, $groupBy, $format);
$templateVariableContainer = $renderingContext->getVariableProvider();
foreach ($groups['values'] as $currentGroupIndex => $group) {
$templateVariableContainer->add($groupKey, $groups['keys'][$currentGroupIndex]);
$templateVariableContainer->add($as, $group);
$output .= $renderChildrenClosure();
$templateVariableContainer->remove($groupKey);
$templateVariableContainer->remove($as);
}
return $output;
}
/**
* Groups the given array by the specified groupBy property.
*
* @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
* @return array The grouped array in the form array('keys' => array('key1' => [key1value], 'key2' => [key2value], ...), 'values' => array('key1' => array([key1value] => [element1]), ...), ...)
* @throws ViewHelper\Exception
*/
protected static function groupElements(array $elements, $groupBy, $format)
{
$extractor = new VariableExtractor();
$groups = ['keys' => [], 'values' => []];
foreach ($elements as $key => $value) {
if (is_array($value)) {
$currentGroupIndex = isset($value[$groupBy]) ? $value[$groupBy] : null;
} elseif (is_object($value)) {
$currentGroupIndex = $extractor->getByPath($value, $groupBy);
} else {
throw new 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 ($currentGroupIndex instanceof \DateTime) {
//$currentGroupIndex = $currentGroupIndex->format(\DateTime::RFC850);
$formatedDatetime = $currentGroupIndex->format($format);
$groups['dateTimeKeys'][$formatedDatetime] = $currentGroupIndex;
} elseif (is_object($currentGroupIndex)) {
$currentGroupIndex = spl_object_hash($currentGroupIndex);
}
$groups['keys'][$currentGroupIndex] = $currentGroupKeyValue;
$groups['values'][$currentGroupIndex][$key] = $value;
}
return $groups;
}
}
and this in the fluid template
<a:groupedForDateTime each="{items}" as="itemsByYear" groupBy="start" format="Y" groupKey="year">
<a:groupedForDateTime each="{itemsByYear}" as="itemsByMonth" groupBy="start" format="m" dateTimeKey="month">
<div class="yearMonth clearfix">
<div class="timeframe" data-behavior="FixTimeframe">
{month -> f:format.date(format: 'F Y')}
</div>
<f:for each="{itemsByMonth}" as="item">
<div class="item">
<p class="startEnd">
<a:format.duration start="{item.start}" end="{item.end}"/>
</p>
<h2>{item.name}</h2>
<div class="text">
<f:format.html>{item.bodyText}</f:format.html>
</div>
</div>
</f:for>
</div>
</a:groupedForDateTime>
</a:groupedForDateTime>
then ill get this error:
Fluid parse error in template partial_Archive/ListItems_6877ade17ed77be0a2f8660fe2717844ab3400c3, line 25 at character 30. Error: The ViewHelper "<a:format.duration>" could not be resolved. Based on your spelling, the system would load the class "Ext\XY\ViewHelpers\Format\DurationViewHelper", however this class does not exist. (error code 1407060572). Template source chunk: <a:format.duration start="{item.start}" end="{item.end}"/>
Upvotes: 0
Views: 335
Reputation: 1956
Your value is empty because TYPO3 does not know where to map it. If you do not have a month column on your table, TYPO3 wont even try to find something. So if you want to use the $month
as a placeholder for the crdate
you can do it like this in TYPO3 10 and above. I have tested this on TYPO3 11 and it works for TYPO3 10 as well.
Your Domain Model
/**
* @var string
*/
protected string $month = '';
/**
* @return string
*/
public function getMonth(): string
{
return date('F', (int)$this->month);
}
/**
* @param string $month
*/
public function setMonth(string $month): void
{
$this->month = $month;
}
Now TYPO3 needs the configuration of the field and this can be achieved on your TCA. You do not need to add it on your types
or anywhere else. You just need the configuration. So in your TCA:
'crdate' => [
'config' => [
'type' => 'input',
'size' => 10,
'max' => 255,
],
],
Now TYPO3 know how can it display it BUT it doesn't know the source of the information. So you need to tell TYPO3 where the information is coming from. This can be achieved in your Classes.php
. So under your_extension/Configuration/Extbase/Persistence/Classes.php
you need to return the following:
return [
\YourVendor\YourExtension\Domain\Model\YourModel::class => [
'properties' => [
'month' => [
'fieldName' => 'crdate'
]
]
]
]
EDIT
While i was writing this answer, you ve changed the whole concept. Regarding your new Problem, you need to declare the ViewHelper either in your Fluid or globally on your ext_localconf.php
Fluid At the very TOP of your Fluid you can add the namespace with one of the two ways.
First way:
{namespace blog=Ext\XY\ViewHelpers}
Second way:
<html
xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
xmlns:blog="http://typo3.org/ns/Ext/XY/ViewHelpers"
data-namespace-typo3-fluid="true">
You can declare it globally in your ext_localconf.php
as well with the following lines:
$GLOBALS['TYPO3_CONF_VARS']['SYS']['fluid']['namespaces']['blog'] = [
'Ext\XY\ViewHelpers',
];
According to your ViewHelper, you ViewHelper class should be under your_extension/Classes/ViewHelpers/Format/DurationViewHelper
. That is the reason why you get the error
Fluid parse error in template partial_Archive/ListItems_6877ade17ed77be0a2f8660fe2717844ab3400c3, line 25 at character 30. Error: The ViewHelper "<a:format.duration>" could not be resolved. Based on your spelling, the system would load the class "Ext\XY\ViewHelpers\Format\DurationViewHelper", however this class does not exist. (error code 1407060572). Template source chunk: <a:format.duration start="{item.start}" end="{item.end}"/>
If this doesn't resolve your Problem, maybe you should just build the autoload information again. TYPO3 might not be aware of the new class yet
Upvotes: 1
Reputation: 10791
If you have a date/time in a FLUID variable you can use the f:format
viewhelper to access each value individually, even in different formats.
If you want one value more often and want to avoid the repetition of the viewhelper store the value in a new FLUID variable.
<f:variable name="day" value="{mydate->f:format.date(format:'d')}" />
<f:variable name="weekday" value="{mydate->f:format.date(format:'%A')}" />
<f:variable name="month" value="{mydate->f:format.date(format:'m')}" />
<f:variable name="monthname" value="{mydate->f:format.date(format:'%B')}" />
<f:variable name="year" value="{mydate->f:format.date(format:'Y')}" />
See the PHP functions date()
and strftime()
(localized) for appropriate format strings.
Upvotes: 0
Reputation: 2557
You don't need the same information twice. There is another thread "How to use standard fields like crdate and cruser_id with TYPO3 and extbase?" discussing the use of standard fields.
If you only want to use the month of crdate in FLUID, you can use ViewHelpers in the template to format the data according to your needs. In this case, format.data
would help.
Upvotes: 0