Hot answers tagged

19

Fabien Potencier, the main developer of the Twig templating language answered the question like so: Macros: reusable markup across a lot of templates Includes: part of "pages" that are extracted for readability and reusability The reason for this, as far as I understand, is that you can only use the include tag to render the complete file ...


17

There are actually two issues with this approach. The first, and the direct reason you’re getting that Twig error, is that templates that extend another template can only output things within {% block %} tags. Any HTML that gets output outside of those tags (either directly or via {{ output tags }}) will result in that Twig error. The {% include %} tag is ...


11

You can leave the with lightswitchTest part off altogether, and all the variables from the parent template will be available inside the include too. with expects an array, where the keys correspond to the variable names and their values, so if you did want to explicitly pass that in (say as a different variable) you could use: page.twig {% include "...


10

You'll never need to put Twig tags within other Twig tags... Try it like this: {% include "partials/includes/page-header" with { 'title' : entry.heading } %}


8

Your code should work if you remove the quotation marks enclosing your variable. {% set embedAsset = entry.productId %} {% include embedAsset %} If you want, you can use string concatenation to add a path or extension to it. {% set embedAsset = '_products/' ~ entry.productId ~ '.html' %} {% include embedAsset %} You could also add a "fallback template", ...


5

You can't pass a JS variable into a JS file (that doesn't quite make sense). What you can do is to create a JS variable, and make it accessible to the script you are including. So you'd include your JS file as you are already doing: {% includeJsFile 'path/to/file' %} And then you would create your variable, and in JavaScript pass that variable back into ...


4

If I had to guess, I'd say a macro would be faster because it's accessing the file system less. In any case, unless you're dealing with hundreds of thousands of calls, I'd also guess that's the difference is going to be negligible for most use cases.


4

What I do is to handle the metadata in a macro that I call from _layout, which is passed the _context twig global variable In _layout.html: {% import '_macros/_metaData' as m_metaData %} <head> {{m_metaData.output(_context)}} ... Here is the content of _macros/_metaData.html. The output macro constructs a metaData object, based on what is in the ...


4

That seo code will need to be in a block of its own. Create a seo block in your _layout template and then wrap your seo code in your include template with block tags of the same name.


4

You've got a quote in the wrong place. This... {% "include _views/reviews.twig" %} should be this... {% include "_views/reviews.twig" %}


4

I believe it is possible @jack. Take a look at this working demo - http://twigfiddle.com/9rwjeo Update: On closer inspection the original example did not work. You can not have a block inside an include how you are describing. I have update the twig fiddle with a work around though


4

You're really fighting against the way Craft CMS does things. I'd start by having a good read through the Craft Docs first, there really isn't a shortcut. The docs are really great though, and contain everything you're likely to need. Then, I'd set up a copy of Craft in isolation of your site/framework and just get a feel for how you do things the "Craft ...


3

Your syntax is a bit off – the search() parameter doesn't accept multiple parameters, only a search query (e.g. .search('body:foobar')) or an object containing the search query plus search term options. In your case, you're actually passing an object (.search(entry.clientsOrAgency)), in which case Craft will look for a query parameter on that object (the ...


3

Whenever Craft receives an URL request, it tries to figure out what resource to serve the client. Among other things, it'll look inside your templates folder and try to find the requested resource there – which is why a request to styles/index.css works if that file exists inside your templates folder. However, Craft only looks at files in your templates ...


3

I'm not sure if this is better or not but one thing I'd do here is to set some defaults in my include. This also means you don't need to worry about checking whether it's defined or not. You're just checking whether it's true. {% set options = { author: true, badge: true, date: true, magnify: true, meta: true, thumbnail: true, } | ...


3

Take 2: I think you may be looking to use a Twig Macro. Here's the gist of that approach, but I don't fully understand the layout of your template yet, so my answer may be a bit out of context until I do. You'll need to create your macro higher in your template or in a separate file and import it into the template you are working in. (See the docs linked ...


3

Another option would be to create a small plugin with a variables file dedicated to storing this data. class MyPluginVariable { public function exampleVariable($optional = null) { return "Return anything you want."; } } Then in your template, you can just use: {{ craft.myPlugin.exampleVariable }}


3

You need to let Twig interpret the variable as a string. This works for me: {% set theForm = entry.formSelect %} {% include ''~theForm~'' %} Hope this helps!


3

I was speaking with Andy Harris on IM earlier, and he told me that there was no need to pass the meta data from the entry template to the layout template. Instead, he said I can just put the metadata code straight into the layout template, and it would parse for the individual entries (I had it in my head that I had to pass this information from the entry ...


3

You set the variable that your are passing in to your include to a string. And in your include you try to access it like an object. The variable which you’re passing in to your include is set to a string 'businessIntelCategories'. And in your include you try access a object property dynamically using that string which doesn’t work. Use this code instead. {...


3

You don't need to (more specifically, you can't) nest Twig tags within other Twig tags. Ditch the inner Twig tag and its respective quotes, and just pass the variable directly into the outer Twig tag... {% include entry.dropSubsection %} That being said, I'm not sure this will achieve exactly what you're looking for. You may need to append .value as well......


3

The typical 'Craft' way of doing this would be via a Matrix field instead of a single text block field, so that editors can sandwich the dynamic content (which would be its own block type) in between whatever other block types they select. That way is very powerful, flexible, extensible, and clean... However, assuming migrating your content to a Matrix ...


2

Anything that is defined in index.twig outside of a block will be available in skeleton.twig, and so also in template.twig. This should work: skeleton.twig {% include '_includes/template' %} index.twig {% extends "skeleton" %} {# Set parameter #} {% set param = { section: ['handle1', 'handle2'] } %}


2

Another little thing to consider, instead of using: {% if entry.metaDescription != '' %}{% endif %} which effectively means 'if this field is not equal to nothing', try using Twigs |length filter: {% if entry.metaDescription|length %}{% endif %} But yes to answer your question, since1976 has already said it but you will just need to wrap your SEO code (...


2

Adding my own discovery in case anyone ever runs into this. The format that worked was lower camel for both the plugin name, and also lower camel for the secondary name. So for the following class: class MyPlugin_OtherService extends BaseApplicationComponent { public function myfunction() {} } I was able to access it like: return craft()->...


2

When calling services, you should not include "service" in method name. Try return craft()->myPlugin_other->testing();


2

It looks like another good solution is to use a template hook. I just became aware of these, but they look very useful for this type of thing.


2

Using macro command you can replace the set command, avoiding the disadvantage of long code every time you need to call a variable. I had the same need, and my solution is: Parent template "main.twig.html": {% import "constants.twig" as constants %} var priceA = {{ constants.priceA }} Child template "constants.twig": {% macro priceA () %} 15.10 {% ...


2

I've figured it out. To anyone who has a similar question. They are called Globals. Set them up from the settings area with fields then you can reference them from your template like below. {{ mailingList.textArea }} mailingList is the handle of my Global Set and textArea is the field. Info: http://buildwithcraft.com/docs/globals


2

I think you should look into "Globals" for content you want to edit, and re-use throughout your entire site. http://buildwithcraft.com/docs/globals


Only top voted, non community-wiki answers of a minimum length are eligible