4

I found several solutions to build a dynamic, complex navigation in craft. One is described here: Adding active class to globally cached navigation. Now i would like to create a more powerfull twig filter for creating different navigation and breadcrumb types with selecting of active links. I already wrote some test code in plain php and used for this the library simplehtmldom (helper for changing dom elements in php like in jquery). A demonstration about what i want to do can be found here: http://www.bahu.ch/craft/. Now i started with creating the twig filter, but i can't include the library in my plugin. Here is a quick overview of my plugin code.

   <?php 
   namespace Craft;
   use Twig_Extension;

   use Twig_Filter_Method;

Now i need to include the library (i know, that the next line is incorrect)

   include('simple_html_dom.php');

   class k4NavigationTwigExtension extends \Twig_Extension

   {


public function getName()
{
    return 'k4Navigation';
}

public function getFilters()
{
    return array(
        'k4Navigation' => new Twig_Filter_Method($this, 'k4Navigation'),
    );
}

public function k4Navigation($navigation)
{

    $html = str_get_html($navigation);

on the next line the current url should replace the string "test.html"

    $selectElem = $html->find('a[href="test.html"]')[0];

    if (is_object($selectElem)){
       // loop li and set class active
        for ($i = 1; $i <= 20; $i++) {
            $selectElem->setAttribute("class","active");
            $selectElem =  $selectElem->parent();
            if (!is_object($selectElem)){
                break;
            }
        }    
    }

    return $html;

   }

   }

Maybe someone can give me a hint, how to includ the library and the first example? You can download the full test code and started plugin from here: https://github.com/tombauer/k4-navigation

Many thanks for any help!

Sunny regards Tom

Tom Bauer
  • 1,327
  • 7
  • 14

2 Answers2

4

Douglas McDonald's answer is correct with one issue though. The import statement is actually case sensitive

Craft::import('plugins.myplugin.twigextensions.MyTwigExtension');

I also have 2 additional notes:

  • The getName() method is deprecated so you shouldn't bother with it
  • The getFilters() method can be written much shorter, for example:
public function getFilters()
{
    return [
        'myfilter' => new \Twig_Filter_Method($this, 'myfilter'),
    ];
}
2

In your plugins main file add the following:

public function addTwigExtension()
{
    Craft::import('plugins.myplugin.twigextensions.myTwigExtension');

    return new MyTwigExtension();
}

In your plugin folder, add a new folder called 'twigextensions'.

In the new 'twigextensions' folder, add your twig filter 'MyTwigExtension.php'.

<?php

namespace Craft;

use Twig_Extension;
use Twig_Filter_Method;

class MyTwigExtension extends \Twig_Extension
{

    public function getName()
    {
        return 'My Twig Extension';
    }

    public function getFilters()
    {
        $returnArray = array();
        $methods = array(
            'myfilter',
        );

        foreach ($methods as $methodName) {
            $returnArray[$methodName] = new \Twig_Filter_Method($this, $methodName);
        }

        return $returnArray;
    }

    public function myfilter($content)
    {
        // perform filter operations

        return "My Filter Result";
    }

}

You can thank Luke Holder's twig extension craft-inflect for this!

Douglas McDonald
  • 13,457
  • 24
  • 57
  • Dear Douglas thank you for the answer. Whit the code i did now my plugin setup, but it does still not work. When i try to use the filter, it ends with a error "Undefined offset: 0". Maybe there is still a problem with including the needed library? Here is the link to the PHP and Plugin-Code link. Maybe you see the problem? – Tom Bauer Apr 15 '15 at 10:15
  • 1
    @giveandfindhelp See this question for some expert opinions on how to include third party libraries/classes in Craft plugins. – Mats Mikkel Rummelhoff Apr 15 '15 at 11:37
  • @MatsMikkelRummelhoff Thanks. I updated the plugin, but it has still the same error. I added a better description in github to explain what i try to do - see https://github.com/tombauer/k4-navigation. – Tom Bauer Apr 15 '15 at 11:58
  • That specific error message – Undefined offset: 0 – just means that you attempted to access the first index of an array, and the array is either empty, or not an array at all. You have several calls like this in your code: $selectElem = $html->find( $selectedFilter)[0];; note that if $html->find() returns a falsey value (or an empty array), you'd get the error message above when trying to access specific indexes. You should test whatever $html->find() returns (e.g. using empty() and is_array() before attempting to access that return value's data. – Mats Mikkel Rummelhoff Apr 15 '15 at 12:10
  • 1
    I have to say though, that this is going into general PHP territory, and as such is technically outside of the scope for this site. I'd recommend looking to the main Stack Overflow site for any general PHP or Simple HTML DOM related questions or issues, as those aren't really related to Craft in any way :) – Mats Mikkel Rummelhoff Apr 15 '15 at 12:12
  • Also – and please don't take this the wrong way, I'm just trying to be helpful – I'm honestly a little confused about your approach here. Wouldn't it be better to just feed your Twig filters a dataset representing your navigational structure (e.g. a nested array of links and labels), and then output the necessary markup, rather than to first build the menu markup manually and then manipulate it with Simple HTML DOM? Seems a little roundabout as long as you have control over the initial markup/input. Just my 2 cents :) – Mats Mikkel Rummelhoff Apr 15 '15 at 12:17
  • @MatsMikkelRummelhoff Thanks for your hint - i got working the plugin with a static code :-) - so the library works and now i have to find the problem with my dynamic content. And YES, your right, it's not a realy sexy solution and your solution with a dataset would be much better. For the moment i try to get working my "quick&dirty" solution (with standard, built in craft navigation function) and after i will try to optimize it. Thanks again. – Tom Bauer Apr 15 '15 at 12:41
  • Sounds like a decent strategy, @giveandfindhelp. Good luck! – Mats Mikkel Rummelhoff Apr 15 '15 at 14:18