bdx
bdx

Reputation: 3516

How can I perform maths in a silverstripe template?

I come from a Rails background and am working on a Silverstripe 3.7 project on PHP 7.1 where I need to make a change to a template to fix a column alignment issue.

If I was doing this change in Rails, the code in the template might look like this:

<% 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 %>

What I tried in Silverstripe before finding out that it seems you can't do maths in the template was this:

<% 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 %>

I've read here that "You should create a method on your object which contains the logic and call that.", but I'm not sure how to apply that advice to this case.

I suspect what it would end up looking like is this:

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 %>

Can anyone point me in the right direction for how I can do this the Silverstripe way?

Upvotes: 2

Views: 534

Answers (1)

Conny Nyman
Conny Nyman

Reputation: 337

The code below should work.

Template:

<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>

PageController:

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);
}

Upvotes: 1

Related Questions