Shopify Theme Development - Section and Block development - themes

Hello Shopify Theme Development Pros,
I am trying to add a block in a section of my theme and although the input block shows up on the screen, when I input type nothing shows up on the actual website. I have tried defining styles in CSS as well, but no luck.
This is what I have added to the block settings in the liquid file...
{
"type": "text",
"id": "review_title",
"label": "Review Heading",
"default": "Enter title here"
},
And this is the html that I added...
<div class="testimonial-heading> {% if section.settings.review_title != blank %} <p> {{ section.settings.review_title | escape }} </p> {% endif %}</div>

When you are using blocks you need to loop them since there are dynamic content that can be added multiply times.
So at the moment you are targeting the settings object and not the blocks section.settings.review_title.
In order to list the blocks you need to do the following:
{% for block in section.blocks %}
<div class="testimonial-heading">
{% if block.settings.review_title != blank %}
<p> {{ block.settings.review_title | escape }} </p>
{% endif %}
</div>
{% endfor %}

Related

How can I specify an 11ty collection in frontmatter?

On my website, I want to show a list of collection items on pages corresponding to each collection. For example on the Games page, I want to show a list of all game related articles, on the Politics page, I want to show a list of all politics related articles, etc.
What I have right now is one Nunjucks template file for each such page, which I don't particularly like since they are the same except for the collection to show. Here is two of my templates, for my politics articles and for my games articles, where I extend a common boilerplate (base.njk) and in the main block, I first print some Markdown content and then comes the list of collection items:
{# politics.njk #}
{% extends "base.njk" %}
{% block main %}
<main>
{{ content | safe }}
<ul class="postlist no-bullets">
{% for item in collections.politics %}
{% include "partials/collection-list-item.njk" %}
{% endfor %}
</ul>
</main>
{% endblock %}
{# games.njk #}
{% extends "base.njk" %}
{% block main %}
<main>
{{ content | safe }}
<ul class="postlist no-bullets">
{% for item in collections.games %}
{% include "partials/collection-list-item.njk" %}
{% endfor %}
</ul>
</main>
{% endblock %}
As you can see, the only difference between these two files is collections.politics and collections.games. I would want to use one template, and in the frontmatter specify which collection I want. Since I'm already having one Markdown file per page the template used (for writing stuff before I begin listing articles), it would have been nice if it was possible. For example:
<!-- politics.md -->
---
layout: articles-list.njk
title: Politics
listCollection: collections.politics
---
# Politics
Below is a list of all politics articles I've written.
<!-- games.md -->
---
layout: articles-list.njk
title: Games
listCollection: collections.games
---
# Games
I think about games a lot. Below is a list of articles I've written on the topic.
{# articles-list.njk #}
{% extends "base.njk" %}
{% block main %}
<main>
{{ content | safe }}
<ul class="postlist no-bullets">
{% for item in listCollection %}
{% include "partials/collection-list-item.njk" %}
{% endfor %}
</ul>
</main>
{% endblock %}
Is it possible to do what I want to do in some other way than to have multiple template files?
You might be able to get to the collection using computed data, though I'm not sure if you have access to the collections there.
A simpler approach: Set your frontmatter field to the name of the colletion you want to display as a string, then use that to get the collection in the template:
<!-- politics.md -->
---
layout: articles-list.njk
title: Politics
listCollection: 'politics'
---
{# articles-list.njk #}
{% extends "base.njk" %}
{% block main %}
<main>
{{ content | safe }}
<ul class="postlist no-bullets">
{% for item in collections[listCollection] %}
{% include "partials/collection-list-item.njk" %}
{% endfor %}
</ul>
</main>
{% endblock %}
The way I handled this on my blog (https://github.com/cfjedimaster/raymondcamden2020) was like so:
I create a collection of my categories. I do this by using .eleventy.js and eleventyConfig.addCollection. I use some JavaScript to get all of my posts, iterate over each ones list of categories, and creating a unique list. At the end, I've got a collection called categories.
eleventyConfig.addCollection("categories", collection => {
let cats = new Set();
let posts = collection.getFilteredByGlob("_posts/**/*.md");
for(let i=0;i<posts.length;i++) {
for(let x=0;x<posts[i].data.categories.length;x++) {
cats.add(posts[i].data.categories[x].toLowerCase());
}
}
return Array.from(cats).sort();
});
I then made one page, categories.liquid, that is reponsible for generating my category pages. It's rather simple:
---
pagination:
data: collections.categories
size: 1
alias: cat
permalink: "categories/{{ cat | myEscape }}/"
layout: category
renderData:
title: "{{ cat }}"
---
Notice I use cat for each item in the category and notice I've got nothing else in here. All the layout is done in the category layout page.
Here's the top portion of my category page:
---
layout: default
---
{% assign posts = collections.posts | getByCategory: cat %}
So given I've got a collection of posts where each post has N categories assigned to it, I wrote a custom filter that just reduces this down to a post that has cat as one of it's categories.
S the end result is N category pages filled posts assigned to that category.

How to filter Taxonomies using Rust-based Zola / Tera?

I have recently discovered Zola and Tera (Rust frameworks for statically-generated websites) and found them amazing.
I'm trying to filter specific category pages to display in a section on the same page. To illustrate, I wrote some code like this:
<div class="content">
{% block content %}
<div class="list-posts">
{% for page in section.pages %}
{% for key, taxonomy in page.taxonomies %}
{% if key == "categories" %}
{% set categories = taxonomy %}
{% for category in categories %}
{% if category == "rust" %}
<article>
<h3 class="post__title">{{ page.title }}</h3>
</article>
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
{% endfor %}
</div>
{% endblock content %}
</div>
There should be MULTIPLE sections of the code above for different categories, e.g. "rust", "java", etc.
I wrote the code to explain my question, but it isn't the way I want it (and it doesn't work when the sections are duplicated).
How do I do the filtering of the particular category when the sections/pages are loaded?
The front-matter metadata in the content file is:
title = "A web page title"
[taxonomies]
categories = ["rust"]
If you see my example code above, I have to access it first via a hash map, then an array, in order to filter all pages which is "rust".
The filter below doesn't work:
for page in section.pages | filter(attribute="taxonomies.categories", value="rust"
I managed to resolve it. First, I did tests like this:
HTML test print output
{% set categories = get_taxonomy(kind="categories") %}
{% set rustItems = categories.items | filter(attribute="name", value="rust") %}
{% set javaItems = categories.items | filter(attribute="name", value="java") %}
{{ rustItems[0].pages | length }}
<br>
{{ rustItems[0].pages[0].title }}
<br>
{{ rustItems[0].pages[1].title }}
<br>
I was able to pick up the title as set in the .md file.
So I moved on further and I did:
{% set categories = get_taxonomy(kind="categories") %}
{% set category = categories.items | filter(attribute="name", value="business") | first %}
{% for page in category.pages %}
{{ page.title }}
... etc.
The above code will filter the pages for category taxonomy.

Create Jekyll link from YAML array

I have a YAML array in a file called navigation.yml as follows:
docs:
- title: Home
url: index.md
id: index
- title: Support
url: support.html
id: support
- title: About
url: about.md
id: about
I am creating a navigation bar as follows:
<section id="navigation" class="clearfix">
{% for item in site.data.navigation.docs %}
<span>{{ item.title }}</span>
{% endfor %}
</section>
What should I put in place of index.md to get the item.url that I want from the YAML file.
I am totally new to GitHub Pages, YAML, and Jekyll.
At the moment, the link tag doesn't seem to support variables.
There's a pull request trying to change this, but it has not been merged into the main Jekyll repo yet.
So if you want to do this now, you need to use some tricks.
The solution suggested by flyx in his comment (replace {% link index.md %} by {{ item.url }}) basically works, but shows the original filename written in the data file.
⇒ If index.md is automatically renamed to index.html while rendering the site, your link won't work anymore.
(or if support.html becomes support/index.html)
That's probably why you wanted to use the link tag instead.
Without using the link tag, you need to loop your data file, loop through all pages to find the respective page, and show that page's actual URL in your link:
<section id="navigation" class="clearfix">
{% for item in site.data.navigation.docs %}
{% for page in site.pages %}
{% if page.path == item.url %}
<span>{{ item.title }}</span>
{% endif %}
{% endfor %}
{% endfor %}
</section>
This even takes stuff like explicitly set permalinks (permalink: /whatever/ in the page's front matter) into account.

Nunjucks, blocks defined within "include" partial file ignored by extend

Here is my use case
I have a file that pulls pieces together (holy-grail.njs) that then is extended by the actual page I want (single.njs). Problem is that the blocks defined in included files are ignored by the actual page template. You can see the extended sidebar text is not appearing in screenshot <p>Here is some additional content for the sidebar extended in</p>
Just for grins I moved that block code from sidebar.njs to holy-grail.njs and yes it is extended by single.njs so it is indeed as I suspected.
Is the a bug?, a non-feature? How about a work around? Or will Jade do what I want? I assumed that "included" files were just included as in before further processing but maybe they are processed then included? Without being able to do this my whole groovy way of organizing my template pieces/partials and then extending/customizing the content will be a no go.
this same question was asked three years ago and no one answered
Blocks in included files not being filled by extended templates
single.njs
{% extends "layouts/holy-grail.njs" %}
{% block sidebar %}
<p>Here is some additional content for the sidebar extended in</p>
{% endblock %}
{% block article %}
{% raw %}
{{ Hugo code here to grab the article title and content }}
{% endraw %}
{% endblock %}
holy-grail.njs
{% set reg = "regions/" %}
{% set cmp = "components/" %}
{% include "regions/head.njs" %}
<body class='page'>
{% include reg + "header.njs" %}
<div class="rollover-wrapper">
{% include reg + "topbar.njs" %}
<main>
{% include reg + "sidebar.njs" %}
<section id="content">
{% block article %}
{# This is where one melds in article content #}
{% endblock %}
</section>
</main>
{% include reg + "footer.njs" %}
</div>
{% include cmp + "javascripts.njs" %}
</body>
sidebar.njs
<aside id="sidebar" class="sidebar">
<p> some sidebar content set in the sidebar.njs file </p>
{% block sidebar %}
{# This is where one melds in more sidebar content #}
{% endblock %}
</aside>
This from one of the maintainers of Nunjucks
Your guess is correct: includes operate at a "higher level" than
template inheritance. So an included template can have blocks, and can
have its own "extends" tag, and a totally separate template
inheritance hierarchy, but its blocks don't in any way interact with
the blocks of the including template's inheritance hierarchy.
So the solution I came up with is to use another tool (gulp plugin) to pre-assemble the partials then run them through nunjucks like this.
N.B my preprocessor file uses extension *.pnjs and outputs to a corresponding *.njs file which then is processed/extended in the single.njs.
var merge = require('gulp-file-include')
var rename = require("gulp-rename");
gulp.task('html:pre', function() {
gulp.src(['assets/html/nunjucks/layouts/*.pnjs'])
.pipe(merge({
prefix: '##',
basepath: 'assets/html/nunjucks'
}))
.pipe(rename({extname: ".njs"}))
.pipe(gulp.dest('assets/html/nunjucks/layouts/'));
});
var nunjucks = require('gulp-nunjucks-render');
gulp.task('html:njs',['html:pre'], function() {
gulp.src('assets/html/nunjucks/*.njs')
.pipe(nunjucks({ path: ['assets/html/nunjucks'] // String or Array
}))
.on('error', console.log)
.pipe(gulp.dest('./builds/dev/'));
});
and then you'd have to change your include syntax to that supported by gulp-file-include
like this.
##include('regions/head.njs')
<body class='page'>
##include('regions/header.njs')
<div class="rollover-wrapper">
##include('regions/topbar.njs')
<main>
##include('regions/sidebar.njs')
<section id="content">
{% block article %}
{# This is where one melds in article content #}
{% endblock %}
</section>
</main>
##include('regions/footer.njs')
</div>
##include('components/javascripts.njs')
</body>

Post without title in Jekyll

In my Jekyll blog, I would like some posts not to have a title. How could I modify the Jekyll codebase to make it so that posts do not require a title?
You don't need to alter the jekyll codebase to remove titles. That can be done using different layouts with appropriate liquid filters and tags.
For individual post pages, simply make a new layout file (e.g. "_layouts/no-title-post.html") that doesn't have the {{ page.title }} liquid tag. In your _posts source file, set the YAML front matter to call it. For example:
---
layout: no-title-post
---
Note here that "title:" isn't required in the YAML front matter. If jekyll needs it, the value will be automatically crated from the filename. For example, "_posts/2012-04-29-a-new-post.md" would have its title variable set to "A New Post" automatically. If your templates don't call the title tags, it won't matter. You could include a "title:" in the front matter and it simply wouldn't be displayed.
You can also display the page without the title in your listing/index pages. Check the posts layout to determine if the title should be displayed. For example, to show titles on all your pages except ones that have the 'no-title-post' layout, you would do something like this:
{% for post in paginator.posts %}
{% if post.layout != 'no-title-post' %}
<h1>{{ post.title }}</h1>
{% endif %}
<div class="postContent">
{{ post.content }}
</div>
{% endfor %}
In that case, the link to the page itself is also removed. If the page needs to be addressable, you would have to add the link back in somewhere else.
edemundo's solution doesn't work anymore in all cases with Jekyll 3.
I use an empty title as default:
defaults:
-
scope:
type: "posts"
values:
layout: "post"
title: ""
Then you can compare titles against the empty string in your layouts, for example:
{% if post.title == "" %}
{{ post.content | strip_html | truncatewords:5 }}
{% else %}
{{ post.title }}
{% endif %}
If you like the automatic title generation you can use as frontmatter:
---
title: ""
---
I was having the same doubt, then I stumbled on this really simple solution:
{% if post.title %}
<h1>{{ post.title }}</h1>
{% endif %}
And then in the post file itself you would leave the title variable empty:
---
layout: post
title:
---
This way, the h1 will not print if the title is empty. I found this method particularly useful for post types like quotes, which most of the time doesn't have titles.

Resources