PhpStorm 无法识别 TYPO3 Fluid 结束标签
PhpStorm not recognizing TYPO3 Fluid closing tags
我有一个 Fluid 模板,我将列表分成 4 组,例如:
<ul>
<f:for each="{items}" as="item" iteration="i">
<li>(CONTENT HERE)</li>
<f:if condition="{i.cycle} % 4">
</ul>
<ul>
</f:if>
</f:for>
</ul>
我已将 Fluid XML 命名空间添加到我的项目 like this,但 PhpStorm 仍然通知我我的结束 </f:if>
标记 'matches nothing'.
有没有办法配置 PhpStorm 来识别这个结构?
我在 <f:if>
中包裹结束和开始标记是否违反了最佳实践?
PHP Storm 验证的第一件事是 XML/HTML 的正确嵌套 - 就像标签一样,在你的示例中你无情地破坏它(从 IDE 的角度来看,不是据我所知,需要在 Fluid 中使用模 break),添加有效的 XML 命名空间甚至禁用 [=41= 都没关系]检查员。
更重要的是 聪明 即使在 then 通知中也能识别标签(该死的!),这也将显示IDE级错误:
<ul>
<f:for each="{items}" as="item" iteration="i">
<li>Item {i.cycle}</li>
{f:if(condition: '{i.cycle} % 4', then: '</ul><ul>')}
</f:for>
</ul>
到目前为止,我发现并在许多项目中成功使用的唯一解决方案是自定义 ext 中的自定义 ViewHelper(对于 IDE,重要的是在 endTag
之前声明 startTage
!):
<?php
namespace Vendor\Myext\ViewHelpers;
/**
* {namespace myNs=Vendor\Myext\ViewHelpers}
*
* = Inline samples
*
* === Break the list:
* {myNs:breakTagByModulo(iterator: i, modulo: 2)}
* or...
* {myNs:breakTagByModulo(iterator: i, modulo: 2, startTag: '<ul class="next-level">', endTag: '</ul>')}
*
* result on valid modulo:
* </ul><ul class="next-level">
*
* === Break the Bootstrap row:
* {myNs:breakTagByModulo(iterator: i, modulo: 2, startTag: '<div class="row">', endTag: '</div>')}
*
* result on valid modulo:
* </div><div class="row">
*
* etc...
*/
class BreakTagByModuloViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper {
/**
* @param array $iterator Iterator from `f:for` VH
* @param integer $modulo Modulo to check
* @param boolean $skipLast If skipLast==true VH will return false even if condition is correct, needed for `not full` lists
* @param string $startTag Begin of the tag
* @param string $endTag End of the tag
*
* @return bool|string
*/
public function render($iterator, $modulo, $skipLast = true, $startTag = '<ul>', $endTag = '</ul>') {
$i = $iterator['cycle'];
$bool = ($i % $modulo == 0);
if ($skipLast && $iterator['isLast']) {
$bool = false;
}
return ($bool) ? $endTag . $startTag : null;
}
}
?>
视图中的用法如上所示,仅对于您的示例,它类似于:
{namespace myNs=Vendor\Myext\ViewHelpers}
<ul>
<f:for each="{items}" as="item" iteration="i">
<li>(CONTENT HERE)</li>
{myNs:breakTagByModulo(iterator: i, modulo: 4)}
</f:for>
</ul>
(当然,您要用自己的值替换 myNs
、Vendor
和 Myext
)
我受到了 LazyOne 的评论和 Biesior 的回答的启发。采取以下措施:
<ul>
<f:for each="{items}" as="item" iteration="i">
<li>Item {i.cycle}</li>
{f:if(condition: '{i.cycle} % 4', else: '</ul><ul>')}
</f:for>
</ul>
我尝试用 HTML 实体和 Unicode 转义序列替换尖括号,两者都完整输出。然后我想到做字符替换。我找到了 v:format.replace viewhelper,并执行了以下操作:
<v:format.replace substring="(" replacement="<"><v:format.replace substring=")" replacement=">">{f:if(condition: '{iter.cycle} % 4', else: '(/ul)(ul)')}</v:format.replace></v:format.replace>
也就是说,我在我的代码中放入了括号,并将它们切换为尖括号以用于输出。
所以对于任何想使用它的人来说,都有一个冗长得可笑的选项。
我建议采用不同的方法来确保稳固的 html 结构。混合模板 HTML 和来自视图助手的 HTML 似乎是一个危险的想法,当开始标签来自一个而结束标签来自另一个时。
由于将列表拆分成块似乎是逻辑上的必要性而不是表象,因此其逻辑应该发生在控制器而不是视图中。如果出于某种原因,您无法更改控制器逻辑(第 3 方扩展?),您应该求助于小部件/视图助手。在那里,您可以使用纯 PHP 将列表拆分为 4 组,然后使用循环迭代模板中的集合。这样,HTML 将不易损坏,更易于维护且更易于理解(对您和 PHPSTORM)。
我有一个 Fluid 模板,我将列表分成 4 组,例如:
<ul>
<f:for each="{items}" as="item" iteration="i">
<li>(CONTENT HERE)</li>
<f:if condition="{i.cycle} % 4">
</ul>
<ul>
</f:if>
</f:for>
</ul>
我已将 Fluid XML 命名空间添加到我的项目 like this,但 PhpStorm 仍然通知我我的结束 </f:if>
标记 'matches nothing'.
有没有办法配置 PhpStorm 来识别这个结构?
我在 <f:if>
中包裹结束和开始标记是否违反了最佳实践?
PHP Storm 验证的第一件事是 XML/HTML 的正确嵌套 - 就像标签一样,在你的示例中你无情地破坏它(从 IDE 的角度来看,不是据我所知,需要在 Fluid 中使用模 break),添加有效的 XML 命名空间甚至禁用 [=41= 都没关系]检查员。
更重要的是 聪明 即使在 then 通知中也能识别标签(该死的!),这也将显示IDE级错误:
<ul>
<f:for each="{items}" as="item" iteration="i">
<li>Item {i.cycle}</li>
{f:if(condition: '{i.cycle} % 4', then: '</ul><ul>')}
</f:for>
</ul>
到目前为止,我发现并在许多项目中成功使用的唯一解决方案是自定义 ext 中的自定义 ViewHelper(对于 IDE,重要的是在 endTag
之前声明 startTage
!):
<?php
namespace Vendor\Myext\ViewHelpers;
/**
* {namespace myNs=Vendor\Myext\ViewHelpers}
*
* = Inline samples
*
* === Break the list:
* {myNs:breakTagByModulo(iterator: i, modulo: 2)}
* or...
* {myNs:breakTagByModulo(iterator: i, modulo: 2, startTag: '<ul class="next-level">', endTag: '</ul>')}
*
* result on valid modulo:
* </ul><ul class="next-level">
*
* === Break the Bootstrap row:
* {myNs:breakTagByModulo(iterator: i, modulo: 2, startTag: '<div class="row">', endTag: '</div>')}
*
* result on valid modulo:
* </div><div class="row">
*
* etc...
*/
class BreakTagByModuloViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper {
/**
* @param array $iterator Iterator from `f:for` VH
* @param integer $modulo Modulo to check
* @param boolean $skipLast If skipLast==true VH will return false even if condition is correct, needed for `not full` lists
* @param string $startTag Begin of the tag
* @param string $endTag End of the tag
*
* @return bool|string
*/
public function render($iterator, $modulo, $skipLast = true, $startTag = '<ul>', $endTag = '</ul>') {
$i = $iterator['cycle'];
$bool = ($i % $modulo == 0);
if ($skipLast && $iterator['isLast']) {
$bool = false;
}
return ($bool) ? $endTag . $startTag : null;
}
}
?>
视图中的用法如上所示,仅对于您的示例,它类似于:
{namespace myNs=Vendor\Myext\ViewHelpers}
<ul>
<f:for each="{items}" as="item" iteration="i">
<li>(CONTENT HERE)</li>
{myNs:breakTagByModulo(iterator: i, modulo: 4)}
</f:for>
</ul>
(当然,您要用自己的值替换 myNs
、Vendor
和 Myext
)
我受到了 LazyOne 的评论和 Biesior 的回答的启发。采取以下措施:
<ul>
<f:for each="{items}" as="item" iteration="i">
<li>Item {i.cycle}</li>
{f:if(condition: '{i.cycle} % 4', else: '</ul><ul>')}
</f:for>
</ul>
我尝试用 HTML 实体和 Unicode 转义序列替换尖括号,两者都完整输出。然后我想到做字符替换。我找到了 v:format.replace viewhelper,并执行了以下操作:
<v:format.replace substring="(" replacement="<"><v:format.replace substring=")" replacement=">">{f:if(condition: '{iter.cycle} % 4', else: '(/ul)(ul)')}</v:format.replace></v:format.replace>
也就是说,我在我的代码中放入了括号,并将它们切换为尖括号以用于输出。
所以对于任何想使用它的人来说,都有一个冗长得可笑的选项。
我建议采用不同的方法来确保稳固的 html 结构。混合模板 HTML 和来自视图助手的 HTML 似乎是一个危险的想法,当开始标签来自一个而结束标签来自另一个时。
由于将列表拆分成块似乎是逻辑上的必要性而不是表象,因此其逻辑应该发生在控制器而不是视图中。如果出于某种原因,您无法更改控制器逻辑(第 3 方扩展?),您应该求助于小部件/视图助手。在那里,您可以使用纯 PHP 将列表拆分为 4 组,然后使用循环迭代模板中的集合。这样,HTML 将不易损坏,更易于维护且更易于理解(对您和 PHPSTORM)。