如何在 silverstripe 模板中执行数学运算?

How can I perform maths in a silverstripe template?

我来自 Rails 背景,正在 PHP 7.1 上的 Silverstripe 3.7 项目中工作,我需要更改模板以修复列对齐问题。

如果我在 Rails 中进行此更改,模板中的代码可能如下所示:

<% items = ['item1', 'item2', 'item3, 'item4'] %>
<% len = items.length %>
<% mod = len % 3 %>
<% items.each_with_index do |item, index| %>
    <% if mod != 0 && mod == len-index %>
        <div class="col-sm-4 col-sm-offset-<%= 6 - (mod*2) %>">
    <% else %>
        <div class="col-sm-4">
    <% end %>
<% end %>

在发现您似乎无法在模板中进行数学运算之前,我在 Silverstripe 中尝试过的是:

<% loop $ProductSectionBlocks %>
    <% if $TotalItems % 3 != 0 && $TotalItems % 3 == $FromEnd %>
        <div class="col-sm-4 col-sm-offset-{6 - (($TotalItems % 3) * 2)}">
    <% else %>
        <div class="col-sm-4">
    <% end_if %>
<% end_loop %>

我读过 here "You should create a method on your object which contains the logic and call that.",但我不确定如何将这些建议应用到这个案例中。

我怀疑它最终会是这样的:

function ProductSectionBlocksMod() {
    return ProductSectionBlocks.length % 3;
}

function ProductSectionBlocksOffset() {
    return 6 - (ProductSectionBlocksMod * 2);
}

<% loop $ProductSectionBlocks %>
    <% if $ProductSectionBlocksMod != 0 && $ProductSectionBlocksMod == $FromEnd %>
        <div class="col-sm-4 col-sm-offset-{$ProductSectionBlocksOffset}">
    <% else %>
        <div class="col-sm-4">
    <% end_if %>
<% end_loop %>

任何人都可以指出我如何以 Silverstripe 方式做到这一点的正确方向吗?

下面的代码应该可以工作。

模板:

<div class="row">
    <% loop $ProductSectionBlocks %>
        <% if $Top.ProductSectionBlocksMod != 0 && $Top.ProductSectionBlocksMod == $FromEnd %>
            <%-- Bootstrap ^4 offset --%>
            <%--<div class="col-sm-4 offset-sm-{$Top.ProductSectionBlocksOffset}">--%>

            <%--Bootstrap 3 offset--%>
        <div class="col-sm-4 col-sm-offset-{$Top.ProductSectionBlocksOffset}">
            Column #{$Pos}
        <% else %>
        <div class="col-sm-4">
            Column #{$Pos}
        <% end_if %>
    </div>
    <% end_loop %>
</div>

页面控制器:

public function getProductSectionBlocks()
{
    return Page::get()->limit(5); // Replace 'Page' with your real DataObject
}

public function ProductSectionBlocksMod()
{
    return ($this->getProductSectionBlocks()->count() % 3);
}


public function ProductSectionBlocksOffset()
{
    return 6 - ($this->ProductSectionBlocksMod() * 2);
}