Hot answers tagged

5

The better approach in my opinion is to declare the variables in the corresponding templates rather than in the _layout template Layout.twig {% if seoTitle is not defined or seoTitle is empty %} {% set seoTitle = config.seoTitle %} <-- fallback if nothing is defined {% endif %} <title>{{ siteName }} - {{ seoTitle }}</title> _entry.twig ...


5

I think you're getting your variable names mixed up. Something like this should work: {% for row in entry.content1|batch(2) %} <div class="row"> {% for block in row %} <div class="col-sm-6">Content</div> {% endfor %} </div> {% endfor %} I've changed the name of the first block to row.


5

Option 1 is a safe bet. This allows you to have completely separate, editable templates for each chosen year. You can then change the page slug to match the year of that page. You can reuse fields year over year if you'd like or create new fields for each year. Plugins like seomatic will help you create individual SEO content on a per template basis.


4

It seems to be what you need is Twigs extend functionality. What you have here is a very common template structure so there is nothing out of the ordinary! Firstly, going from your code I'd recommend your main layout template file looks something like this. The idea here being that these elements will not change for each page, but the content or information ...


4

How about we have a matrix, with block types x and y. Then you can test for block type in your loop: {% for block in entry.this %} {% switch block.type %} {% case 'x' %} ... {% case 'y' %} ... {% endswitch %} {% endfor %} Another issue is that 33.33 + 66.66 = 99.99, which is never going to be equal to 100. (Also, the test for equality is ==:...


3

You're not specific about what your Ajax template should return (HTML, JSON...?) – but assuming you want your payload in JSON format, here's a basic layout example which will 1) test if the current request is indeed an Ajax request and 2) set headers for JSON and Access-Control-Allow-Origin (crossdomain): In /templates/_layouts/ajax: {% if not craft....


3

Unfortunately, there's no way around having the {% block %} tag somewhere in the template that's being extended. In other words, your main layout template it's going to have {% block %} tags. However, you can use the {% embed %} tag to "wrap" a block in a third template (e.g. "components/main-wrapper.html"): {# base.html #} <body> {% block main %}...


3

You are hashing the string '{{item.mailto}}'. There shouldn't be any need for the quotes or second set of curly braces. Twig does not permit curly braces inside curly braces. Try {{ item.mailto|hash }} instead.


2

Instead of building rows, how about building your layout with inline-block elements or flexbox elements with the flex-wrap property set, to make your elements wrap automatically.


2

Generally, I'll have a div that picks up on the position's value. For example: <div class="image-{{ entry.myPositionHandle }}"> <img src="my-image.jpg"> </div> That renders something like: <div class="image-left"> <img src="my-image.jpg"> </div> Then I'll have a css rule like this: .image-left img { ...


2

No, unfortunately there's no way to re-use a Field Layout in Craft. You might want to consider adding a feature request at http://feedback.buildwithcraft.com.


2

Easiest way I can think of is just to use some math. If your grid columns need to add to 12, keep a current column count while iterating over the matrix blocks. I'd imagine you'd want your content blocks have some sort of built-in "column" width to begin with... a text content block might be 8 columns and an image would be 4. Or 6 and 6. If the current ...


2

I'm doing this at the moment. It's not a perfect solution, but nor is it terrible. In a lot of ways, I'd quite like Craft to just burn Singles and Channels and use nothing but Structures. You can do everything with Structures that you can with the other two, and you get better flexibility and much nicer groupings in the CMS that make more sense to clients (...


2

Are you on Craft 3 or 2? In 3, you can use the built-in {% js %} ... {% endjs %} tag to inject scripts into tags named {{ endBody() }} or {{ beginBody() }} that you place wherever you like in your layout. When outputting from the entry, also be sure to use the |raw filter. https://docs.craftcms.com/v3/dev/tags/js.html Craft 2 had a similar function: https:...


2

Your above code is not working because you are using "block" instead of "item" in your children. So... {% for item in block.children %} {% switch item.type.handle %} You don't necessarily need to do a switch here, you could do a series of includes and make their file names match your block type... so "_includes/neo/box.twig" and "_includes/neo/image....


2

This question comes up in support tickets every so often from client users. We like to say that Craft fills the space between where WordPress ends and Enterprise begins. It's meant for designers and developers to build bespoke websites for clients. That would include Squarespace-like website building services as well. If your design, technical, and ...


2

Try putting it inside of a simple block as the default value... {% block contactButton %} {% include '_contact-button' %} {% endblock %} Then on your one-off page, override that block with emptiness... {% block contactButton '' %} Untested, but that should do the trick!


2

You can check against the Entry Type as well. I would try to validate it with something like: {% set exclusions = ['home'] %} {% if entry.type not in exclusions %} ....


1

You'll need to loop through all entries first and divide the entries into three arrays. Then using a combination of id and fixedOrder you can create three more entries calls to loop through each column and it's entries. This would make a nice dynamic solution that doesn't need refactoring as more entries are added. https://craftcms.com/docs/templating/...


1

There's no easy twig function available to do this, but the code from this answer should be able to help you. {% set columns = 3 %} {% for entry in entries %} {% if loop.first or loop.index0 is divisibleby(columns) %} <tr> {% endif %} <td>{{ entry.title }}</td> {% if loop.last and loop.index is not divisibleby(...


1

I've had this issue previously before when working on a larger website, when you want to copy an entry type and all its field layouts, or even copy a section all its entry types and all their field layouts. I've written a plugin that tackles this, check it out here: Craft Cloner


1

After hours I managed to fix it. I'm assuming I made an error where I was trying to copy the Fields in the Entry Type I literally just created. So it was copying over 0 fields. I built the functions from scratch again and finally found the working code. For future reference or to help others, here is the snippet in question. private function CopyEntryTypes(...


1

You must call the inner blocks (level2, level3 and so on) like the first level {% if entry.bodyMain is defined and entry.bodyMain | length %} {% nav block in entry.bodyMain.level(1) %} {% switch block.type.handle %} {% case 'accordion' %} <ul class="accordion accordion-2"> {% nav block in ...


1

You could use the approach you already suggested, but combine it with a grid that doesn't require to close rows, but automatically wrap into the next row if there's not enough space left. There's two common ways to achieve such a grid cell behavior, inline-blocks and flexbox with flex-wrap set to wrap.


1

Although you couldn't necessarily change the _layout template with the method given in that tutorial. What you could do is include the header the templates rather than in the _layout.html for each template and change it out with another header in the other specific URLs. Or hide it, or whatever you like.


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