Giter Club home page Giter Club logo

fluid's Introduction

TYPO3 CMS

TYPO3 is an open source PHP based web content management system released under the GNU GPL. TYPO3 is copyright © 1999-2024 by Kasper Skårhøj.

This document provides a basic introduction to TYPO3.

Getting Started

TYPO3 requires a web server with PHP and a database. The backend is accessed via a supported browser.

Please see the Installation Guide in order to set up a basic TYPO3 installation on your web server.

What is TYPO3?

TYPO3 is a free and open source Content Management Framework. It is released under the GNU General Public License. It can run on several web servers, such as Apache, nginx or IIS, on top of many operating systems, among them Linux, Microsoft Windows, FreeBSD or macOS.

TYPO3 was initially authored by Kasper Skårhøj and is now further developed by a community of contributors and the TYPO3 Core Development Team.

To get more info about the GPL license, visit https://opensource.org/licenses/gpl-license

What is a Content Management Framework?

A Content Management Framework is more than just a content management system, due to the separation of the streamlined core and optional plugins (extensions). TYPO3 has an open API that allows you to extend the frontend (website) and/or backend (administration) functionality.

The concept of extensions makes TYPO3 capable of being developed and used in almost any way you can imagine, either by using any of the many extensions which are available for download, or by writing your own.

TYPO3 System requirements

TYPO3 is based upon PHP and uses a database management system like MySQL.

For more specific information regarding requirements see the file INSTALL.md in this folder.

TYPO3 resources

Here is an overview of the most important TYPO3 resources to help you get started:

Get more information

  • https://typo3.org/ is the main project website. It provides up-to-date official news, information about events and the TYPO3 community.

  • https://docs.typo3.org/: TYPO3 is one of the most thoroughly documented OpenSource products around, with manuals covering basic tutorials, TypoScript, administration, development, core structure, etc. You should make the time to locate the various documents, and read those that apply to the work you want to do.

  • https://get.typo3.org/ is the platform where you can download TYPO3 and find all release notes and change logs of TYPO3 releases.

  • https://extensions.typo3.org/ is the platform where you can search for and download TYPO3 extensions.

Chat with us

The TYPO3 community is using a tool called Slack to openly communicate with each other and with the public. Several TYPO3 teams use Slack as a way to communicate internally and most channels are a welcome place for you to join and get yourself involved.

Exchange information, ask questions, get help

Slack is nice for short discussions, but when asking questions, most answers are lost in the noise after a few minutes.

StackOverflow

To let everyone profit from an answer, we recommend to ask questions on StackOverflow. If you like, you can then post a link into the corresponding Slack channel to raise attention. And please, do not forget to tag your questions correctly with typo3 (and possibly other tags like typo3-9.5.x, Fluid or Extbase).

Official meet the TYPO3 Community overview:

Visit https://typo3.org/community/meet/

Contributing

If you want to contribute to the TYPO3 source code, take a look at our Contributors Walkthrough and Review System:

Please use the TYPO3 Slack chat, if you need help in setting up your contribution environment. The community is very helpful and get you up and running! (Please post your questions in Slack Channel #typo3-cms-coredev regarding contribution support)

The repository at GitHub is a synchronized mirror of the primary TYPO3 core git repository:

If you want to file a bug report, take a look at:

Security

If you learn about a potential security issue in the TYPO3 core or in an extension, please always contact the TYPO3 Security Team via [email protected]. Please always include the version number where you've discovered the issue. If we can confirm a problem in a third-party extension, we will inform the author immediately.

If you discover a security problem in your own extension, please inform the TYPO3 Security Team as well. They can help you to fix it, and they may want to issue an advisory once it is fixed.

For more details see TYPO3 Security Team.

Final notes

TYPO3 is said to be one of the most sophisticated PHP / Internet related applications available, and the more you play with it, the more you will agree.

Due to the advanced level of the code and functionality, a degree of study, time and perseverance is required to fully understand it, and get the best from it. You should keep trying, as we say it's definitely worth it. TYPO3 is the Enterprise Content Management System "for all".

The GPL license allows for developments that are based upon TYPO3 to also be freely available under the GPL. Please remember this, because TYPO3 is about "Inspiring People To Share". If you are making money with TYPO3 you can donate or become a member of the TYPO3 Association.

By becoming a supporting member, individuals and organisations mainly fund core development of TYPO3. The decision about what the funds are used for, is made by all members of the Association and the TYPO3 Association Board. The decisions will be made transparent to the community and especially the supporting members. Your funds will also serve for other purposes as laid out in the bylaws.

Copyleft

This document is a part of the TYPO3 project.

fluid's People

Contributors

aertmann avatar afoeder avatar albe avatar bmack avatar bnf avatar danielruf avatar foerthner avatar franzholz avatar helhum avatar hlubek avatar ichhabrecht avatar indyindyindy avatar kdambekalns avatar kitsunet avatar lolli42 avatar maddy2101 avatar mbrodala avatar namelesscoder avatar neufeind avatar o-ba avatar ohader avatar robertlemke avatar s2b avatar sascha-egerer avatar sbuerk avatar skurfuerst avatar stephanschuler avatar thommyhh avatar tmotyl avatar wouter90 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fluid's Issues

Variable name cut off

Given an array assigned to templateVariables that contains a key user2.
Now I do:

<f:alias map="{user: testVariables.user2, firstName: testVariables.user2.firstName}">
{user.lastName}, {firstName}
</f:alias>

this fails, user.lastName (and after debugging also user) is null inside the alias (the direct access to testVariables.user2.lastName works just fine). Looking at the compiled template the resulting variable access is:
$array1['user'] = $renderingContext->getVariableProvider()->getByPath('testVariables.user', $array2);

As you can see the path was cut off and the 2 is missing in the end.

Will try to deliver more debug details, but for now this seems to b a bug in parse/compile.

CycleViewHelper doesn't work when static rendered

The CycleViewHelper depends on a class property to store the current cycle it is rendering. This works when rendered initially but when rendered from a compiled state a new instance of the VH is created on every cycle effectively keeping the result stuck with the first cycle value.

Need to make up my mind how to solve that in a way that allows nesting as well...

Properties of \ArrayAccess objects may become inaccessible.

The following scenario is currently not solvable with the Accessor handling as is, but was before standalone:

Given a class roughly like this (skipped some implementation details):

class Foo implements \ArrayAccess
{
  // ArrayAccess implementation

  getSomePropertyNotAccessibleByArrayAccess()
  {
    return $this->somePropertyNotAccessibleByArrayAccess;
  }
}

Instance available in the template as foo:

{foo.somePropertyNotAccessibleByArrayAccess}

Will result in NULL because the getter is not used as soon as the object was detected as implementing \ArrayAccess.

IMHO correct would be to check if getSomePropertyNotAccessibleByArrayAccess (or any of the other allowed "getter" methods) is available or if it is a public property, before using ArrayAccess.

Performance Tests

As initially found by christian there is a performance hit compare to the typo3cms/fluid variant, which results in some cases in a almost doubled rendering time.

the main issue seems that most viewHelpers reverted to non static variants, so lets fix that :)

todo:

  • we'll make render optional by making it an automatic call to renderStatic with $this->arguments
  • make every standalone viewHelper static or compiled
  • maybe reintroduce viewHelperInstance reusing

cc @NamelessCoder @helhum @lolli42
related: https://review.typo3.org/#/c/42425/112

Ternary expression and cache seems to result in wrong result on second and consequent calls

When using current GIT master of typo3/cms and using Ternary expression then when using it like this:
{settings.false ? 'foo' : 'bar'}

And having set:
settings.false = 0

Then the result is that on the first call it results in 'bar' as output.
On the second and consequent calls it results in 'foo'

When putting the terenary expresion inside f:cache.disable:
<f:cache.disable>{settings.false ? 'foo' : 'bar'}/f:cache.disable

then it always results in 'bar'.

Add the FluidTemplate via typoscript directly and the settings like this:
10 = FLUIDTEMPLATE
10.file = PATH-TO-FILE.html
10.settings.false = 0

I have the same issue with using 10.variables instead of settings.

Might be realted to #148

double {{ and }} are also parsed but always empty

When using for instance:
{{settings.foo}}

it is also parsed but basically always empty.
It would be nice if that would retrieve the value of settings.if and then uses that string to retrieve the value of the name.
For instance, if settings.foo is bar, and bar is 123, then the output should be 123.
That way dynamic array access would also be possible.

Furthermore, there should be an option to disable the parsing of double {{ expressions as some javascript templates like handlebars use those to evaluate expressions and it makes it complicated to output such a template inside fluid. But normal { should still be resolved.
In theory one can create an interceptor for that but it is unnecessary complex.

Boolean ViewHelper arguments comparing numeric values behave differently

Not to argue what makes more sense, but to report the different behavior

"==" operator, comparing strings with integers:

<f:if condition="'foo' == 0">
  <f:then>then</f:then>
  <f:else>else</f:else>
</f:if>

Expected output

then

Actual output

else

">=" operator, comparing strings with floats:

<f:if condition="'1.1 >= 'foo'">
  <f:then>then</f:then>
  <f:else>else</f:else>
</f:if>

Expected output

then

Actual output

else

">" operator, comparing strings with integer:

<f:if condition="'foo' > 0">
  <f:then>then</f:then>
  <f:else>else</f:else>
</f:if>

Expected output

else

Actual output

then

The reason for this new behavior is that now both $left and $right are strings in BooleanNode::evaluateComparator(). Before numeric values were converted to NumericNode instances with

if (is_numeric($value)) {
    $this->leftSide->addChildNode(new NumericNode($value));
} else {
    $this->leftSide->addChildNode(new TextNode(preg_replace('/(^[\'"]|[\'"]$)/', '', $value)));
}

in the constructor.

Add CLI for linting

It would be useful if there was a CLI command for linting Fluid templates. Given the nature of Fluid templates an XML linter cannot be used for this.

ElseViewHelper has an `if` argument that seems unused

I thought at first that you could use else with a condition as if argument to get if/elseif/else behavior but I don't see any code actually implementing that. So either the argument definition is unnecessary or the implementation needs to be done?

ViewHelperExceptions should not be thrown at compile time

The ViewHelper\Exception is meant to be thrown by ViewHelpers if they come across an unresolvable error during rendering (e.g. when the count ViewHelper gets an non-countable argument).
Currently this exception is thrown when ViewHelpers can't be resolved:

<f:nonExistingViewHelper />

Expected

Parser\Exception

Actual

ViewHelper\Exception

This is important because the framework should be able to deal differently with the two cases.
E.g. in Flow we silently skip ViewHelpers that throw a ViewHelper\Exception in Production context. This should never happen for parsing errors.

"-1 != -1" wrongly converted to boolean.

The BooleanParser seems to struggle with the mentioned expression.

Running

<f:if condition="-1 != -1">
  <f:then>
    Then child!
  </f:then>
  <f:else>
    Else child!
  </f:else>
</f:if>

Will result in Then child! and the compiled code looks like this:

$array2 = array();
$array2['0'] = '-1 != -1';

$expression3 = function($context) {return "-";};
$arguments1['condition'] = TYPO3Fluid\Fluid\Core\Parser\SyntaxTree\BooleanNode::convertToBoolean(
                    $expression3(
                        TYPO3Fluid\Fluid\Core\Parser\SyntaxTree\BooleanNode::gatherContext($renderingContext, $array2)
                    ),
                    $renderingContext
                );

From what I see the BooleanParser does not take - into account. I will try to find a fix for it.

RFC: Fine grained whitespace control

Request for comments: Add a syntax-element for controlling whitespace trimming

Currently, the compiler adds a lot of whitespace to the resulting templates, in a form that the amount of whitespace is roughly equivalent to the amount of space the syntax took right before the compile step.

Background

Having a more complex snippet of fluid code like this:

<f:if condition="expression">
<ul>
  <f:for each="{fruit} as apple">
    <li>{apple.color}</li>
  </f:for>
</ul>
</if>

will compile to something like this:

<!-- whitespace line here -->
<ul>
  <!-- whitespace line here -->
  <li>green</li>  <li>red</li>
  <!-- whitespace line here -->
</ul>
<!-- whitespace line here -->

Which is a lot of noise added through a simple control structure.

While machines are able to compress / collapse the whitespace and easily parse the relevant parts, as software developers that have to look a lot at compiled and evaluated templates it's vital to be able to mentally parse the resulting html as well. It would be desirable to have a syntax element that controls when and how whitespace is stripped and which allow for more fine-grained control of that stripping process than f:spaceless.

Example solution with Jinja

The Jinja 2 and Twig (as implementation of the Jinja spec in PHP) templating languages support a "strip whitespace operator" on the node level, implementing a similar feature should be desirable.

Links to relevant documentation:

For example given a naive example:

<ul>
{% for apples in fruit %}
  <li>{{ apple.color }}</li>
{% endfor %}
</ul>

Would roughly compile down to:

<ul>
<!-- whitespace line here -->
  <li>green</li>  <li>green</li>
<!-- whitespace line here -->
</ul>

Now using the "strip whitespace operator" - the example would look like this:

<ul>
{%- for apples in fruit -%}
  <li>{{ apple.color }}</li>
{%- endfor -%}
</ul>

Would roughly compile down to:

<ul><li>green</li><li>green</li></ul>

Notice that the dash-operator - can be added to any expression, such as blocks or variable nodes ({{- value }}) and can be added to both sides of a node or only one (to control the whitespace prior to a node, but not the one produced by the node, for example).

Needed solutions

ViewHelperNodes

Well. To my ad-hoc knowledge, xhtml doesn't allow additional characters that apart from [a-z] as element names, so we may need a different, xhtml compliant "signal" to trigger the compiler to strip whitespace.

Expression nodes

For simple variable nodes, I propose we add a dash as stripping operator so that

<li>
  {- identifier -}
</li>

would compile to:

<li>value</li>

I would be glad to discuss this over time, if someone wants to share their thoughts, please go ahead. Maintainers: feel free to edit the text and form to match your liking.

Falsy call to scandir() in SimpleFileCache

/**
 * @codeCoverageIgnore
 * @return array
 */
protected function getCachedFilenames()
{
    return scandir($this->directory . '*.php');
}

scandir() does not work like this. glob() should be used instead.

Cant check for "variable is not set" in Ternary Expressions

It is not possible to check if a variable is not set in a ternary expression.

{ myArray.invalidVariable ? 'yes' : 'no' } Will always return yes because myArray.invalidVariable is evaluated as a string as not variable is found with this name

{('{myArray.invalidVariable}' !== '') ? 'yes' : 'no'} does also not work as the parser does not recognize this syntax as a ternary expression but simply outputs the text.

Exceeding ViewHelper arguments are ignored

When specifying a ViewHelper argument that is not registered, an exception is thrown.
Currently the respective argument is simply ignored - which is very error prone.

BTW: There's a related feature request that would allow ViewHelpers to handle exceeding arguments. It would be great to integrate that at some point, but even then those ViewHelpers are expected to throw an exception if they come across unsupported arguments (see https://review.typo3.org/31708)

Template

<f:if foo="bar" />

Expected output

Exception: Argument "foo" was not registered.

Actual output

xmlns definition on tags not recognized

This code used to work in CMS 7 and below:

    <div xmlns:rx="http://typo3.org/ns/Reelworx/RxShariff/ViewHelper">
        <rx:shariff data="{url: 'http://example.com/'}" services="xing,facebook"  />
    </div>

The issue is that the xmlns is not resolved anymore. I need to put this into the <html>-tag in order to get this working.

[TASK] Allow escaping of characters inside accessor paths

currently it's not possible to access keys of arrays that contain fluid specific characters like . { } etc.
although that's not a usecase that we "endorse" using those characters inside accessor paths, but there's
a relatively valid usecase to use a "." inside the array key when you assign typoscript values into fluid
which contains dots for the array keys

example*

<?php
$view->assign('foo', 
    'foo' => array(
        'bar.' => 'dasoidjo'
    )
);
{foo.bar\.}

Syntax check for boolean fluid expressions

Problem

We have the problem that fluid simply ignores invalid syntax in templates and treats it as a string in case of syntax errors. for example, <f:if condition="{settings.type === 'ordered'}"> is always true because there is the triple = instead of a double.
It gets even worse if you have complex objects.
Is there anything we can do to catch such errors?

Chat discussion

NamelessCoder: cweiske there isn't much you can do for that specific use case. The reason is that passing any string value as condition is perfectly okay and results in TRUE unless the string is empty or contains a zero. So any invalid expression there silently gives a TRUE, and we can't make it not do that without completely breaking other use cases. We don't have a "this string looks like Fluid but isn't" check and such a check probably wouldn't be much good anyway.

NamelessCoder: if you move the expression out of the condition attribute that's still the best way to debug very complex boolean expressions

NamelessCoder: if the === issue is one you come across often we will of course consider adding that to the booleanparser capabilities

NamelessCoder: btw: <f:if condition="{settings.type === 'ordered'}"> should be <f:if condition="{settings.type} == 'ordered'"> so the === isn't the only thing in that expression (thus further proving your point)

NamelessCoder: let's ping @mneuhaus as well, maybe he has some way to make booleanparser throw up if for example it sees a purely hardcoded string that doesn't make sense as boolean expression... but I think it doesn't see any of that, only knows that it's a string but not where it came from, and we do not want to trigger this on strings coming from an object accessor node.

cweiske: a linting tool would help, too. then we could use that in our commit hooks and on the test server

mneuhaus: we could to a "does this look like fluid syntax check" in cases where a boolean is expected i guess

mneuhaus: only usecase that could "blow up" is something like condition="{jsonData}" i guess

mneuhaus: if (is_string($booleanArgument) && looks_like_fluid($booleanArgument)) -> throw Exception

mneuhaus: it's an edgecase, but one we could adress i guess

mneuhaus: @NamelessCoder what do you think about that variant?

NamelessCoder: a linting tool would not detect this one cweiske because it is valid syntax to pass a string as condition

NamelessCoder: if the check is cheap I have no objection to that, I would advise though that it only happens in parsing, not once compiled

NamelessCoder: maybe in NodeConverter?

NamelessCoder: and... better throw an extreme amount of good test cases after that one to make sure it doesn't puke all over complex inline syntax!

mneuhaus: agreed, i guess we should be fine with a simple preg_match, that should be pretty cheap

mneuhaus: shouldn't interfere with that, imho

NamelessCoder: yeah I think so too, maybe even the existing preg from inline/shorthand syntax.

mneuhaus: because we'd be looking at it "after" the fluid logic

mneuhaus: kinda like, wtf, why did this fluid looking string slip through

NamelessCoder: I would check: 1) must be a TextNode input. 2) Must have zero child nodes. 3) must contain at least one occurrence of fluid syntax {.

cweiske: { or }

NamelessCoder: oh, and another thing: consider having abstractcondition catch the error and output it in template instead of exception

NamelessCoder: condition vh already has access to parse-time arguments etc.

NamelessCoder: but afaics those checks would be pretty efficient to catch exactly this unintended string issue.

NamelessCoder: I will say it will have side effects though. Consider <f:if condition="{inline:vh(arg: '{dontDoThis}') cdscdsc">

NamelessCoder: resulting node structure is one root node containing three nodes; one text node, then an object accessor, then another text node

mneuhaus: @NamelessCoder we could hook in here instead

mneuhaus: https://github.com/TYPO3/Fluid/blob/master/src/Core/Parser/SyntaxTree/BooleanNode.php#L160

mneuhaus: that's after "all" parsing and evaluating is done

mneuhaus: we should take a hard look at the performance impact, but that could be the easiest and safest place to check for cases like this

NamelessCoder: then it also runs once compiled, that's what I wanted to avoid

NamelessCoder: hmm, the more I think about this the more I think it needs to happen in nodeconverter, delegated to booleanparser if needed but having access to the syntaxtree nodes that would be treated as boolean once parsed.

NamelessCoder: that's the only place we can be sure that some weirdo syntaxtree stack is an error, not something contained in for example TS variables, rte content, stupid markup etc.


Related:

Re-Introduce escaping modifiers functionality

4cdbc74

Removed the escaping modifiers functionality. Any reasons why? Currently the escaping interceptor is enabled by default despite the request format (other than in older Fluid version, where the escaping was only enabled for format HTML). With that, most VHs become unusable in formats, where HTML escaping is not desired (json). Because of that, the escaping modifiers functionality was introduced, which can be used to disable escaping for such cases!

RFC: TagBasedViewHelper in compiled context

Challenge

TagBasedViewHelpers are currently not specifically compilable and will be called via the ViewHelperInvoker in compiled templates. Due to how such ViewHelpers are initialised (the process has additional requirements to initialise a tag builder and allow additional arguments) combined with needing to call them statically, we are prevented from generating a consistent static call that will be possible to implement in such ViewHelpers (e.g. renderStatic).

Technical background

A method to render ViewHelpers statically already exists - renderStatic - but it receives no additional input variables beside arguments, render children closure and rendering context. In order to properly render a tag we would need the following:

  • Wrapping to create a tag builder in renderStatic and calling a delegate method on the ViewHelper which in addition to current arguments receives this tag builder instance.
  • An alternative publicly callable method which receives the same input arguments.

The second alternative method would be preferable since compiling can then become a matter of calling this new static method from within compiled templates, passing it either a globally available tag builder or a fresh tag builder per instance.

Tag Builder peculiarities

The tag builder itself has two peculiarities which come into play:

  1. The tag builder has a reset method but this is not automatically called and is not consistently called in initialisation methods of either the base AbstractTagBasedViewHelper class or any currently known implementations which are not overrides of existing tag based ViewHelpers. The exception is overrides which need to create a fresh tag and thus call reset before re-initialising the tag builder.
  2. The tag builder has a setTagName method which must be called with a tag name - which is currently defined non-statically in the ViewHelper that renders the tag (or provided explicitly to the tag builder during initialisation or re-initialisation after override).

These two perspectives together mean that 1) if using a global instance of tag builder for performance reasons, the tag builder must be reset on each call, and 2) the tag name must be possible to set consistently in the default method as well as allow customising the tag name. The solution thus must take precautions to handle this in the static callable context.

Suggested solution

The following sketched solution (two variants) is suggested to fulfil the requirements:

We add a public static method renderTag which receives the tag builder, tag name, attributes, arguments, render children closure and rendering context

public static function renderTag(TagBuilder $tag, $tagName, array $attributes, array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext) {
    // renders a tag using static calls and passed instances
}

Which in a compiled template is initialised with:

// extract of compiled code in for example a section rendering method on compiled template:

// $tagBuilder is inserted in the compiled template if parser/compiler detects any tag based VH
$tagBuilder->reset();
$tagBuilder->setTagName('staticnamefromclass');
$attributes = []; // generated with call to static method on ViewHelper
$arguments = []; // already generated by compiling
// $renderChildrenClosure generated by compiling
// $renderingContext is globally available
$output .= MyViewHelperClass::renderTag($tagBuilder, 'staticnamefromclass', $attributes, $arguments, $renderChildrenClosure, $renderingContext);

The solution would have the added benefit that the method to generate attributes can be overridden on subclasses which want to process those separately. The tag name is taken from the class while it gets compiled - and is possible to override in the top of an overridden renderTag method.

The AbstractTagBasedViewHelper class would then receive a default method to process attributes through a public method (not yet defined, awaiting comments). A Trait would be created but not implemented in the AbstractTagBasedViewHelper - instead it would be opt-in for any TagBasedViewHelper subclass (as it gets converted to be able to render the tag statically).

Requested comments

The following type of comments are requested:

  1. Objections related to the implementation (concerns about potential breaking, concerns about not fitting common use cases, etc.)
  2. Suggestions for alternative solutions to fulfil the same requirements, but improving performance, developer API friendliness, etc.
  3. Questions to elaborate the impact of the proposed solution in specific areas (required class migrations, etc.)
  4. Simple thumbs up / thumbs down vote if you understand the proposal and simply agree or disagree that it should be implemented.

Thanks in advance to participants!

evaluateCondition on AbstractConditionViewHelper should be made public

This would allow calling that method directly from compiled templates, replacing all the current condition compiling logic with one call to check the condition and generic logic around it which can be the exact same for every type of condition ViewHelper.

This does, however, constitute a change to a public contract and would break implementers, so the change is scheduled for the next major release.

Throw exception for unresolved namespaces

Unknown namespaces used to be ignored in Fluid. But that lead to serious issues, e.g. when extracting template code into a partial while forgetting the namespace imports.
S.th. like

<media:image image="{image}" />

Would try to render '{image}directly if themedia:image` ViewHelper was ignored, leading to various errors that are very hard to debug.

With Flow 3.0 we therefore introduced a stricter handling of unknown namespaces, see: https://jira.neos.io/browse/FLOW-150

<unknownNamespace:foo />

Expected output

Error while rendering a ViewHelper
The namespace of ViewHelper notation "<unknownNamespace:foo.../>" could not be resolved.

Possible reasons are:
* you have a spelling error in the viewHelper namespace
* you forgot to import the namespace using "{namespace unknownNamespace=Some\Package\ViewHelpers}"
* you're trying to use a non-fluid xml namespace, in which case you can use "{namespace unknownNamespace}" to ignore this namespace for fluid rendering

Actual output

<unknownNamespace:foo />

[FEATURE] groupedFor with sorting

Currently there seems to be a lack of functionality when grouped records in the view have to be sorted. defaultSorting for repositories do not intervene.

Use case:
Need to sorting records grouped by f:groupedFor ViewHelper by groupBy property. In case the groupyByproperty is an object that itself brings "sorting" column.

  • Record with category property
  • Category has sorting property
  • Records are grouped in view with f:groupedFor
  • Sorting of grouped records should be based on Category property

Reuse ViewHelper instances

The current implementation contains a change in behavior that prevents some ViewHelpers to work as before: Previously a ViewHelper instance was reused for the same node in the structure. Now a new instance is created every time.
Aside from a potential increase in memory consumption this leads to the following problem:

<f:for each="{0:1, 1:2, 2:3, 3:4}" as="foo">
    <f:cycle values="{0: 'foo', 1: 'bar', 2: 'baz'}" as="cycle">{cycle}</f:cycle>
</f:for>

Expected output

foo
bar
baz
foo

Actual output

foo
foo
foo
foo

Although we could maybe adjust the cycle ViewHelper to cater for that new behavior, it will probably break some 3rd party ViewHelpers, too.

Fatal error if a ViewHelper is not correctly-cased

When referring to a ViewHelper without using the right camelCasing, a fatal error is triggered.
See https://jira.neos.io/browse/FLOW-152 for a related fix that improved handling of those cases.

Template

the ViewHelper is called FlashMessagesViewHelper, with an uppercase M

<f:flashmessages />

Expected output

The ViewHelper "<f:flashmessages>" inside your template is not written correctly upper/lowercased.
Based on your spelling, the system would load the (non-existant) class "TYPO3\Fluid\ViewHelpers\FlashmessagesViewHelper", however the real class name is "TYPO3\Fluid\ViewHelpers\FlashMessagesViewHelper".
This error can be fixed by making sure the ViewHelper is written in the correct upper/lowercase form.

Actual output

Fatal error: Call to a member function getMethodParameters() on null in AbstractViewHelper.php on line 208

XSD schema generator missing / not working

The advertised schema generator seems to not be part of the package anymore. Also, even when manually added (namelesscoder/fluid-schema-generator), it doesn't seem to work with the current sources.

Additionally, Packagist states that namelesscoder/fluid-schema-generator is abandoned and one should use typo3fluid/schema-generator, but a package if this name doesn't seem to exist.

As a short term solution: Is there a recent schema including the most important viewhelpers downloadable somewhere?

HtmlSpecialChars VH different behavior cached/uncached

The HtmlSpecialCharsViewHelper has slightly different behavior when executed first time compared to afterwards.

In render the keepQuotes flag is evaluated like this:
$keepQuotes ? ENT_NOQUOTES : ENT_QUOTES;

While in compile that is translated to:
(%2$s['keepQuotes'] ? ENT_NOQUOTES : ENT_COMPAT)

So if keepQuotes was false it would first render with ENT_QUOTES and then when rendered from compiled state it would render with ENT_COMPAT.

Boolean ViewHelper arguments containing "false" are considered FALSE

<f:if condition="anArbitary String containing FaLsE">
  <f:then>then</f:then>
  <f:else>else</f:else>
</f:if>

Expected output

then

Actual output

else

Also:

<f:if condition="   FALSE   ">
  <f:then>then</f:then>
  <f:else>else</f:else>
</f:if>

Expected output

then

Actual output

else

New version tag with parsing off ?

parsing off support so far is only available in master branch but not in any version.
It would be nice if that feature would make it into TYPO3 CMS 8.5

Performance regression due to additional `count` call

Calling count() on an object can be very "expensive", especially if it's a QueryResult-object with a large set of records as a SELECT COUNT(*) can be very slow with a lot of records (pagination, i.e. a limit/offset won't make a difference).

In my case it's more than an order of a magnitude difference to render 30 records at once (0,042s vs 0,76s)

The bottleneck comes with the newly introduced AbstractViewHelper::isValidType():
It does some (possibly dangerous and expensive) operations on the given arguments, including count and getFirstElementOfNonEmpty() on collection values.

Previously we only checked whether the type matched the argument definition

BTW: There's another possible side-effect in the argument validation: getFirstElementOfNonEmpty() actually resets any collection argument

Error with 1.1.1

I get a Call to undefined method TYPO3Fluid\Fluid\Core\Compiler\TemplateCompiler::getCurrentlyProcessingState() since updating to 1.1.1

Called in AbstractTemplateView line 335.

Don't `count` objects in `ForViewHelper` if not required

When specifiying the iteration argument in the f:for ViewHelper some more details about the current iteration and the total number of items is determined.

Previously this was only done if the argument was actually set.
Now these details are always calculated whether used or not leading to a severe performance regression (see #242)

Global view helper namespace import gone?

The documentation describes a way to globally import a view helper namespace by calling:

$view = new TemplateView();
$view->getTemplatePaths()->registerNamespace('foo', 'Vendor\\Foo\\ViewHelpers');

However, a method called registerNamespace() doesn't seem to exist on TemplateView. Has the support for this been removed?

[FEATURE] easier way to disable "{{" (and maybe also "{' for certain Javascript templates then CDATA per "{"

I think it would be really nice to have an option to disable the "{{" support due to certain JavaScript templates without losing "{" support and not having to add CDATA per "{" that has such values.

For Javascript Code itself containing JSON disabling "{" would also be an idea.

Maybe in a way like disabling htmlspecialchars for certain code blocks that disables either "{{" or "{"

Probably not the highest priority though.

RawViewHelper doesn't use `value` argument

The \TYPO3Fluid\Fluid\ViewHelpers\Format\RawViewHelper registers a value argument to be used instead of the children but in fact never uses it in renderStatic nor in the compiled version, leading to NULL results in case the VH was used with the value argument eg.

<f:format.raw value="don't encode" />

PHP namespace must change to `TYPO3\Fluid`

As part of the up-coming 3.0 release, the PHP namespace must be switched to the final TYPO3\Fluid namespace.

@bmack assigned but issue is coordinated with myself; he who gets to it first lets the other know.

If a contributor wishes to prepare a PR for this, please contact us first by commenting on this issue!

FEATURE: Be able to change the special characters in the parse.

Could be really nice if "{" and "}" could be set somehow somewhere depending of something. I'm sure I'm not the first one that thought about this while was working with .json templates. I know this is possible in other template systems, so could be good for us. Not sure how much effort is needed or if the parse process could decrease the performance a lot. By now I saw is "hardcoded" everywhere which looked strange for me so my only thought about this reason was performance.

Any feedback is welcomed as always.

Remove reserved variable names except "_all"?

This is an issue to discuss whether or not we should remove the on, yes, true, off, no and false variable names (case insensitive!) which are currently reserved.

Background

In earlier versions of Fluid, using a reserved variable name would trigger an error. In Fluid standalone however, such variables are given a default value so for example using {on} in a template will result in a boolean TRUE being returned from the ObjectAccessorNode.

This feature is as of this time undocumented but considered a hardcoded feature of Fluid.

Improvement

Dropping the reserved variable names would result in two things:

  1. Performance of every ObjectAccessorNode can be improved by avoiding the need to check if a variable is reserved (which happens for every variable you try to access).
  2. Reserved variable names can now be used in the template (previously, you could declare but not access the declared value - it would be hidden away due to the name).

The method could then be compressed to a single decision: is the variable name _all; if so, return ->getAll() from VariableProvider. Furthermore the special _all variable name could be made case sensitive and only the lowercase variant trigger getting all - which would save an additional strtolower call for every variable accessed.

See https://github.com/TYPO3Fluid/Fluid/blob/master/src/Core/Parser/SyntaxTree/ObjectAccessorNode.php#L81

debug helper falsely stops dumping with 'see above'

TYPO3 7.6.10 fluid 7.6.0
I am dumping $objects of TYPO3\CMS\Extbase\Persistence\Generic\QueryResult. $object has a member $childobjects of TYPO3\CMS\Extbase\Persistence\ObjectStorage in an MM relation. The $object is not fully rendered (without a plus sign), but with 'see above' marker as an $object before shares the same $childobject. That is wrong. The 'see above' should be with the $childobject only. Assigning the query result to the view differently ->assign('objects', array('anykey' => $objects)), it renders everything correctly and marks the $childobject with 'see above' only.

Ternary expression: string constants with "special" characters

When using ternary expression and string constants with "special" characters like '-'
then the expression is not parsed, for instance:
{settings.false ? 'foo-bar' : 'xyz'}

This also results in the expression not being parsed in case of e.g.:
{'{settings.false}' ? 'foobar' : 'xyz'}

where one tries to retrieve the value by using '{value}' in the condition.

The same for:
{settings.false ? '{foobar}' : 'xyz'}

where foobar is retrieved and the output is then:
{settings.false ? 'VALUE OF foobar' : 'xyz'}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.