Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
Twig view parsing issue
  • I'm having an issue using the Twig parser in my module views. I have different modules for my dashboard, corppages and clientsites, each with their own respective module directories. Things work fine for the most part up until I started using the Twig parser.



    I have "layout" views in my project which I extend from the originating view. For example, I have a 404.twig view file gets called from the controller. In the 404.twig view file, I extend the page.twig layout file which defines how the page layout will look. And inside the page.twig view file, I extend an html.twig file which defines the HTML shell (everything up to the body) of the entire site. This works perfectly fine.

    My issue arises when I have the same layout files in another module. I would expect Fuel to detect the module and use the corresponding layout views if they are found in the module's views directory, which they are. If I cause a 404 in my dashboard module, I have a 404 method setup in that module which displays the dashboard 404.twig file. However, in that view file, Fuel always fetches Twig's "extends" and "include" tags from the default app/views direcotry, not the module's views directory, even though the files are there.



    I added a parser config file to each module and set the "views_path" array variable to include the corresponding module's views directory, ex: APPPATH."modules/dashboard/views". When I check the PHP profiler, I can see that module directory gets added, however, Fuel appends it after the initial app/views directory, so the default app/views directory seems to always get checked first and Fuel displays the views from the default path.



    I went into the core parser config and manually put my dashboard module's views path first, then the default app/views path second and it works. If I put the default app/views path before my module's views path, it doesn't work.



    Is there any way to have Fuel override, or prepend my module's views path before the default app/views path for this specific config file? I'm pretty sure that if I could do this, everything would work fine. Fuel's default app/views directory is the final place Fuel should check for a view file. It should always be checking the module's views directory first. This is the case when calling a view from a controller, Twig or PHP.



    Again, this issue only happens when using Twig's "extends" or "include" tags from within a view located inside of a module's views path.
  • I'm not a Twig user and my knowledge is limited, but Twig itself is not aware of the way Fuel templates work, and doesn't have access to or uses the Fuel file loader.

    There is a "parser.View_Twig.views_paths" configuration key, defined in the parser config file, that defines additional view locations, and is initialized with "APPPATH\views" if not set.

    It is used every time a template is rendered, when fetching the twig template. So if you can find a way to update this config key with the view paths.

    This might work in the parsers twig.php class, could you try?

  • I see what you are doing with the code snippet above. I did try it in the twig.php class, however the problem persists. The reason being is that in the parser package's default config file, it applies Fuel's default app/views directory to "parser.View_Twig.views_paths" by default. Then it prepends the current directory of the view file being called in on line 49 using array_unshift(). If I call in a view from my administration module's root views path, the parser.View_Twig.views_paths config array looks something like this:

    [0] => /my/web/root/fuel/app/modules/administration/views
    [1] => /my/web/root/fuel/app/views

    The above will correctly load my module's layout files. However, if I have a view located in a subdirectory, such as views/page/index.twig, the parser.View_Twig.views_paths array now looks like this and prevents Fuel from finding my module's layout views.

    [0] => /my/web/root/fuel/app/modules/administration/views/page
    [1] => /my/web/root/fuel/app/views

    Long story short, if my initial view is in a subdirectory, Fuel thinks that the views path is that subdirectory (/my/web/root/fuel/app/modules/administration/views/page) and won't load my module's layout views which are located here: /my/web/root/fuel/app/modules/administration/views/layouts.

    If I manually add the module's views directory in a custom parser config file in my module, the parser.View_Twig.views_paths array now looks like this:

    [0] => /my/web/root/fuel/app/modules/administration/views/page
    [1] => /my/web/root/fuel/app/views
    [2] => /my/web/root/fuel/app/modules/administration/views

    The parser.View_Twig.views_paths array should actually look like the following after I set the parser's config file in my module:

    [0] => /my/web/root/fuel/app/modules/administration/views
    [1] => /my/web/root/fuel/app/views

    When you set a custom parser config file in any module, Fuel appends whatever array you set for the $views_paths key to the end of the array, so it will never look for that directory first, which it should be doing. I would suggest using the following code for the Twig views class: https://bin.fuelphp.com/snippet/view/OK.

    I do an array_reverse on the parser.View_Twig.views_paths array since Fuel appends them in the order it finds them and will never look inside a module's views directory. Before reversing the array, I use array_unique to make sure that there are no duplicate paths as Fuel will append the same path over and over if you set it up that way. I removed the the line of code that array_unshifts the current path as this isn't needed, especially when your views are in subdirectories. The views paths should specifically be set via the parser config files.

    Let me know if this makes sense to you. It seems to be working perfectly on my end.
  • If anyone does come across this specific issue, you can simply load the following code in the before() method of your module's base controller to get around the issue for now.

    \Config::load('parser', true);
    \Config::set('parser.View_Twig.views_paths', array_reverse(array_unique(\Config::get('parser.View_Twig.views_paths'))));

    Please note that Fuel will still prepend the current view's path to the "parser.View_Twig.views_paths" configuration, though that shouldn't be much cause for concern.
  • HarroHarro
    Accepted Answer
    Ok, missed the fact that there is a default in the config file, so it's never null.

    Had the time to dig into this a bit, it seems you can inject a custom file loader into twig, which would be a better solution, as that could use fuel's finder to locate the template, just like a standard view file.

    I'll try to look into it over the weekend.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion