3

I am looking for something quite simple, but I still can't find a way to do it in twig syntax. So basically here is my code:

{% set upperlimit = 3 %}
    {% for entry in entry.getChildren() %}
        {% if loop.index0 < upperlimit %}
            <button type="button" class="btn btn-default ma-category-btn {% if loop.first %}first{% endif %} {% if loop.index == upperlimit %}last{% endif %}">{{ entry. title }} <span class="glyphicon glyphicon-info-sign"></span></button>
        {% endif %}
    {% endfor %}

<button type="button"  class="btn btn-default ma-more-category-btn">VIEW MORE CATEGORIES</button>

Basically when I click on the button "VIEW MORE CATEGORIES", it should load the next three children and create three more buttons like the ones in the for loop if there are enough children for that entry.

Is it possible to have this dynamic behaviour in craft and twig?

  • 2
    You could just hide the "extra" entries, and then use JS to display the next batch when the user clicks the "view more" button. – Stephen Lewis Aug 1 '14 at 11:23
4

You can't use Twig for dynamic interactions on your site, as it is a server side language. Twig compiles to PHP code, which is then rendered and loaded to the DOM.

What you'd need is a script running in userland. The technique Stehen suggested is one way to do it, but you probably don't want your site's visitors to load all data right from the start, using the button simply to reveal already loaded "extra entries".

I'd say you should learn how to do AJAX loading with Javascript or jQuery. This is how you could properly address the desired behavior.

A way to make it work with your Craft template would be to split your entries list into multiple parts using the paginate tag. The first block would load right away and then with every click on that button each succeeding entry block is loaded into the DOM via Javascript.

2

Here is the way I solved this issue in order someone comes around looking for a solution. I created a plugin basically. The plugin had only a single controller. So the main plugin.php file contains:

<?php
namespace Craft;

class MyPluginPlugin extends BasePlugin
{
     function getName()
     {
         return Craft::t('My Plugin');
     }

    function getVersion()
    {
        return '1.0';
    }

    function getDeveloper()
    {
        return 'Digital Butter';
    }

    function getDeveloperUrl()
    {
        return 'http://butter.com.hk';
    }
}

Then the controllers folder had only one file MyPlugin_MyController.php as follows:

<?php
namespace Craft;

class MyPlugin_MyController extends BaseController
{
public function actionGetEntry()
{

    $parent = craft()->entries->getEntryById($_GET['id']);
    $type = craft()->elements->getElementTypeById($parent->id);
    $elemModel = craft()->elements->getCriteria($type);

    $attributes = array(
        "descendantOf" => $parent->id,
        "level" => "2"
        );
    $child = $elemModel->find($attributes);

    $children = array();

    foreach ($child as $value) {
        array_push($children, $value->slug);
    }

    $this->returnJson($children);
}


}

Finally we have the page in which I wanted to get the entries dynamically, the javascript is as follows:

// function to dynamically generate he entries that represent sub-categories of articles like cancer
var num = 3;
$('.ma-more-category-btn').click(function(){
num = num+3;
var x = {{ entry.id }};
$.ajax({
url: "{{ siteUrl }}/actions/myPlugin/my/getEntry",
data: { "id": x },
success: function(data){

    $('.ma-category-btns').html('');

if(num > data.length + 3)
    num = num-3;
jQuery.each(data, function(index, value){
    if(index < num)
    {
            if(index == 0)
        {
            $('.ma-category-btns').append(
            "<button type=\"button\" class=\"btn btn-default ma-category-btn first\">" + value + "<span class=\"glyphicon glyphicon-info-sign\"></span></button>"
            );

        }
        else if(index == data.length - 1 || index == num-1)
        {
            $('.ma-category-btns').append(
            "<button type=\"button\" class=\"btn btn-default ma-category-btn last\">" + value + "<span class=\"glyphicon glyphicon-info-sign\"></span></button>"
            );
        }
        else {
            $('.ma-category-btns').append(
            "<button type=\"button\" class=\"btn btn-default ma-category-      btn\">" + value + "<span class=\"glyphicon glyphicon-info-sign\"></span></button>"
            );
        }
      }

    });
    }
    });
});

Also the html layout for this purpose was as follows:

             <div class="ma-category-btns">
                {% for entry in entry.getChildren() %}
                    {% if loop.index <= 3 %}
                        <button type="button" class="btn btn-default ma-category-btn {% if loop.first %}first{% elseif loop.index == 3 %}last{% endif %}">{{ entry.title }}<span class="glyphicon glyphicon-info-sign"></span></button>
                    {% endif %}
                {% endfor %}

            </div>

I hope this helps anyone that comes travelling to this page.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.