How to include a markdown file in index.html? - pelican

In summary, I want to include a specific markdown file in a template.html. How do I do that?
I currently have an about.md page which gets rendered to a about.html using the page.html template in my theme.
Instead of that, I want the about.md to get rendered inside of my index.html template.
I see how to include other templates, eg. {% include "index-sidebar.html" %}
But I want something like {% include "about-rendered.html" %} , where about-rendered.html was rendered using the about.md source.
I see in the page.html template, the markdown content is inserted with {{ page.content }}.
Perhaps there is something like {{ about.md.content }} ?

There is lots of data available to use in the templates.
This is what worked for me.
https://docs.getpelican.com/en/stable/themes.html#common-variables
https://docs.getpelican.com/en/stable/themes.html#page
{% for p in pages %}
{% if p.title == 'About' %}
{{p.content}}
{% endif %}
{% endfor %}

Related

How does one display a collection list filtered by customer tags in shopify using `assign collection =`

I'm trying to create a section within the 'Simple' Shopify theme that filters collections based on customer tags. For example, the customer has the following tags "Foo", "Bar". In turn display the following collections "Foo", "Bar".
I'm not too familiar with liquid so I'm trying to keep things as simple as possible. As such I have duplicated the collection-list.liquid from the 'Simple Theme' for my base and made the following edits to the file.
My Edits
<!-- the magic -->
<div class="collection-grid">
<div class="grid grid--uniform">
{% for tag in customer.tags %} // check customer tags.
{% capture tag_handle %} // capture tag URL handle e.g. /t-shirts in a variable 'tag_handle'
{{ tag | handle }}
{% endcapture %}
{% unless collection.handle contains tag_handle %} // check collection handles against the current tag handle to find a match. If so then do.
<div class="grid__item {{ grid_item_width }} slide-up-animation animated" {{ block.shopify_attributes }} role="listitem">
{% assign collection = collection.handle %} // Assign correct collection. I suspect this to be my stumbling block. See below for reason why.
{% include 'collection-grid-item' %}
</div>
{% endunless %}
{% endfor %}
</div>
</div>
<!-- / the magic -->
With the current code snippet, I do get results equal to the number of customer tags. The problem is that the results are empty, or at least the assigned collection variable is empty.
Any help with this would be greatly appreciated. Thanks in advance.
If you don't want to have to set up and maintain section blocks, how about something like this?
<!-- the magic -->
<div class="collection-grid">
<div class="grid grid--uniform">
{% for tag in customer.tags %} // for each customer tag do
{% assign tag_handle = tag | handle %} // get the tag handle (I.e. no spaces & lowercase)
{% assign collection = collections[tag_handle] %}
{% if collection == blank %}
{% continue %}
{% endif %}
<div class="grid__item {{ grid_item_width }} slide-up-animation animated" role="listitem">
{% include 'collection-grid-item' %}
</div>
{% endfor %}
</div>
</div>
<!-- / the magic -->
This approach will:
Loop through all the customer tags, as before, then
Takes the handle-ized version of the tag and performs a collection lookup
Skips to the next tag if there was no matching collection found
Displays the collection grid item if there is a matching collection
If you are expecting customers to have a lot of tags but only a few collection-related tags, one possible improvement may be to use a special prefix for the collection-related tags that you can check for and skip to the next tag if the prefix is not present. I also know that Shopify has a limit of 50 uses of the all_products lookup per page, but I don't know if there is a similar limit for collection lookups. Either way, for page performance it is probably best if the number of tags and collection lookups is kept reasonably small.
As an aside, one of the things you may be concerned with is page load time. Having too many expensive Liquid operations can cause Shopify's servers to have a bit of delay when serving your site's pages. While you're trying and testing solutions, one extremely useful tool that you can take advantage of is the "Shopify Theme Inspector" plugin for Chrome. This will give you a visual breakdown of how long it takes for Shopify to put your page together on the back-end. (I have no connection with the plugin at all, it's just a useful tool that I have used a few times when evaluating site performance)
So I was able to resolve my issue by taking a slightly different approach based upon #Bilal Akbar question. Seeing as the existing approach worked in the original Simple Theme why try to alter it? Why not allow the admin to load all collections and simply filter the results during the output.
<!-- the magic -->
<div class="collection-grid">
<div class="grid grid--uniform">
{% for tag in customer.tags %} // for each customer tag do
{% assign tag_handle = tag | handle %} // get the tag handle (I.e. no spaces & lowercase)
{% for block in section.blocks limit: section.blocks.size %} // keeping the original loop from the original file.
{% if block.settings.collection == tag_handle %} // check the collections list within the block to see If it matches the tag handle. if so then do.
<div class="grid__item {{ grid_item_width }} slide-up-animation animated" {{ block.shopify_attributes }} role="listitem">
{% assign collection = collections[block.settings.collection] %}
{% include 'collection-grid-item' %}
</div>
{% endif %}
{% endfor %}
{% endfor %}
</div>
</div>
<!-- / the magic -->
Again I'm not too savvy with liquid, If anyone has any alternate or maybe even a better way to achieve my desired result. I would be interested in hearing about it. Thanks again.

Related products based on grouping tags limit memory. Use instead collection with certain handle tag

By starting from this point https://www.shopify.com/partners/blog/related-products
I end up to this custom and working code:
{% comment %}
Get dynamic tag from product and create static collection handle
{% endcomment %}
{% for tag in product.tags %}
{% if tag contains 'IDSeries_' %}
{% assign ser_tag = tag %}
<li>
<a href="/collections/all/{{ ser_tag | handleize }}">
<h2>{{ ser_tag | remove: "IDSeries_" | prepend: "Go to products with Serie ID number:" }}</h2>
</a>
</li>
{% endif %}
{% endfor %}
{% comment %}
Return products by using the extracted tag
{% endcomment %}
{% for product in collections.all.products %}
{% if product.tags contains ser_tag %}
{{ product.title }}
{% endif %}
{% endfor %}
This above does work. But it's not the solution!
because limited memory, it works only for the first bunch of products and not for all.
By considering I have twenty five thousands products all with an incremental "IDSeries_'INT'"
My goal is: to show products with same specific "IDSeries_'INT'".
Since when this already happens at collection tag url like this <a href="/collections/all/{{ ser_tag | handleize }}">
I was wondering if I can return products (into a section products) that are already filtered at the collection handle tag url layer.
So at Themes/Debut/Sections/product-template.liquid
I am trying the following with no luck:
{% assign collection_handle = ser_tag %}
{% for product in collections.all[collection_handle].products %}
{{ product.title }}
{% endfor %}
Question:
Any clue on how to achieve a consistent result for such a big stock of products?
Extra question:
For a store with 30k products each with five tags (so 150k tags in
total).
Does tags have any limitation?
I also created a Shopify community topic https://community.shopify.com/c/Technical-Q-A/Related-products-based-on-grouping-tags-limit-memory-Use-instead/td-p/759705
I can think of two solutions for your problem, that doesn't affect the speed of the site.
Search based + Javascript
The search page on Shopify can search for tags as well.
So if you make a fetch request to the search page like so:
fetch('/search?q=IDSeries_*').then(res => res).then(res => console.log(res))
This will return you the products that include this tag combination and you can append it with javascript.
So you will populate the products with javascript.
GraphQL
You can use the Storefront GraphQL API to make a request and get products by specific tag, like so:
{
products(first: 10, query:"tag:>'IDSeries_'"){
edges {
cursor
node {
title
}
}
}
}
This will require understanding of GraphQL and especially their Store-Front API (not the Admin API).
For a store with 30k products each with five tags (so 150k tags in total).
Does tags have any limitation?
The all_tags object for the collection can return up to 1000 tags, the rest will be skipped. They need to be unique tags, repeatable tags doesn't count.
Other than that there are no limitations to my knowledge.
So at the end of the day to display tag search results in to a Shopify section I used fetch() and script looks like this:
<script>
{% for tag in product.tags %}
{% if tag contains 'IDSeries_' %}
{% assign ser_tag = tag %}
{% endif %}
{% endfor %}
const url = '/search?view=serie_list&q={{ ser_tag }}';
fetch(url)
.then(response => response.text(
))
.then(data => {
$('#serie_list_id').html(data);
});
</script>
Also as the magic #drip said I created a separate search template with {% layout none %} at the top and some other style

How to add collection.liquid to an existing page?

In Shopify, I'm trying to take the template collection.liquid and render it in another page, just like embedding it. But i'm not sure how to accomplish that.
{% paginate collection.products by 50 %}
{% include 'breadcrumb' %}
{% if settings.show_sort_by and collection.products_count > 1 %}
{% include 'collection-sort' %}
{% endif %}
{% if current_tags.size > 0 %}
<h1>{{ current_tags.first }}</h1>
{% else %}
{% endif %}
{% if collection.description.size > 0 %}
<!--START HERO-->
<!--END HERO-->
{% endif %}
<!--START PRODUCT GRID-->
<section class="product-grid twelve columns alpha omega">
<div id="collection_hero" class="collection_hero_class">
<img src="http://carnegie.org/fileadmin/Media/News/press_releases/whitehouse.JPG">
</div>
{% if collection.products.size > 0 %}
{% for product in collection.products %}
{% include 'product-grid-item' %}
{% endfor %}
{% else %}
<p id="no-products" class="animated fadeInUpBig">There aren't any products in this collection!</p>
{% endif %}
</section>
<!--END PRODUCT GRID-->
{% include 'paging' %}
{% endpaginate %}
I've been trying to do the same thing and kept getting errors.
Fixed it by making a new Snippet called list-collections and copying everything from list-collections.liquid into that. Then made a page template called page.list-collections.liquid and pasted this code into that before /div: {% include 'list-collections' %}
Then, I made a new page using the page.list-collections template, and entered my introductory text, images etc in that, which displays above product collections on the page when published :)
Copy everything that's in collection.liquid and paste it into a new snippet (let's say you call it collection-copy.liquid).
Then, in the page you want to add the collections page to, just add {% include 'collection-copy' %}
That should just dump everything that's in collection-copy.liquid and output it to your page.
The simplest way to do so is to :
Create a new page template for example : page.list-collections
Then place under : {{ page.content }} this line :
{% section 'list-collections-template' %}
Now create a new page in Shopify then select the new page template.
Normally you should be able to add new collections in the "Customize" section of your page !

How can I pass variables between DRY templates and ncludes in Jekyll

I have a simple Blog site where the front page index is a list of posts, non truncated and rendered exactly like the individual pages.
I have the index page setup and working:
---
layout: default
---
<div>
{% for post in site.posts %}
{% include post/post.html %}
{% endfor %}
</div>
Where post/post.html contains the post layout using the post variable like so:
<article>
<header>
{% include post/title.html %}
{% include post/metadata.html %}
</header>
<div class="entry-content" itemprop="text">
{{ post.content }}
</div>
</article>
Now, on a specific post page, I want to reuse this include layout so that I can keep my code DRY, so I have the posts use the post.html layout (different from posts/post.html above):
---
layout: default
comments: true
---
{% include post/post.html %}
but the problem is that the include file expects a post variable to exist such post.content is how you access the content.
I have tried:
{% assign post = page %}
and that seems to be the right to pass a variable in, but page is not the right one as it renders as a markdown string instead of the html on the page.
So, how can I pass self -- or whatever is needed -- so that the include file does not need to be altered for the index page or the post page, thus sharing the same code?
While #David Jacquel's answer work, I found it to be unclean and a little verbose, though it did get me on the right track.
_includes/post/post.html swaps the {{ post.content }} for {{ body }}
<article>
<header>
{% include post/title.html %}
{% include post/metadata.html %}
</header>
<div class="entry-content" itemprop="text">
{{ body }}
</div>
</article>
_layouts/index.html now uses
{% assign body = post.content %}
{% include post/post.html %}
_layouts/post.html uses:
{% assign post = page %}
{% assign body = content %}
{% include post/post.html %}
Simple.
We can do it ! With some layout and variable passing.
Regular post use post layout :
---
layout: post
....
---
post content ...
A custom post use the custom_post layout (_layouts/custom_post.hmtl)
---
layout: custom_post
...
---
post content ...
The _layouts/custom_post.hmtl layout just calls our post include, passing the page variable :
---
layout: default
---
{% include post/post.html page=page %}
And finally the _includes/post/post.html conditionally assign the post variable if the page variable is set :
{% if include.page %}
{% comment %}
This only append in the custom_post view context
{% endcomment %}
{% assign post = include.page %}
{% endif %}
<article>
<header>
{% include post/title.html %}
{% include post/metadata.html %}
</header>
<div class="entry-content" itemprop="text">
{{ post.content }}
</div>
</article>

How to use django tree-menu

I try to use django-treemenus.
http://code.google.com/p/django-treemenus/
I create a tree menu (and menu item) using the admin interface.
When I try to load menus using show_meny tag ( below you find my template where I call this tag).
I think I need to call treemenus/menu.html ( given in the sample to start) , but I don't know how? shoold I modify my TEMPLATE_DIRS ?
{% extends "polls/base.html" %}
{% block title %}Poll list{% endblock %}
{# we override the block content here#}
{% block content %}
**{% load tree_menu_tags %}
{% show_menu "home" "vertical" %}**
{% if object_list %}
<ul>
{% for poll in object_list %}
<li>{{ poll.question }} at [ {{poll.pub_date|date:"F j, Y"}}]</li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
{% endblock %}
Found your question while looking for the answer to a different treemenu question and I think I'm (just barely) qualified to answer.
The answer is no, you don't need to modify your TEMPLATE_DIRS. You do need to create a treemenus directory inside your template directory and inside that put a menu.html and menu_item.html. You will find examples of both of those in the docs directory of the django-treemenus distribution.