How to use django tree-menu - django-templates

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.

Related

Shopify' s all_products[ ] does only accept title

For a client I'm building a way to choose what products are shown in the recommended products section on the product page. To achieve this I thought about inserting the handles from the products I'd like to display into the tag part of the product.
So I'm able to loop over all the tags from the product and then for every tag I'd take the product object and display it. The problem is this code doesn't seem to work:
{% for tag in tags %}
{% for single_product in all_products[tag] %}
{{ single_product }}
{% endfor %}
{% endfor %}
This code does work:
{% for tag in tags %}
{% for single_product in all_products[tag].title %} <---- Added .title
{{ single_product }}
{% endfor %}
{% endfor %}
Sadly, I need the entire product object to display it instead of only the product title. How do I achieve this in shopify?
Side info: This code is placed inside of the framework--product-recommendations.liquid file
The solution was using the collection instead of the all_product. I create a collection containing all product and was perfectly able to loop over it.
My code looks like this now:
{% for tag in tags %}
{% for single_product in all_the_products %}
{% if tag == single_product.handle %}
<div class="product-recommendations--item">
{%
render 'framework--product--item',
product: single_product,
view: 'grid'
%}
</div>
{% endif %}
{% endfor %}
{% endfor %}
all_the_products is assigned to a collection containing all the products.

Shopify check if Metafield exists?

I'm looking to hide content if the metafields are empty for a product, but right now it's returning it for all pages which means my if statement is broken somewhere.
Product Page
{% if product.metafields.review %}
{% include 'extra-review' %}
{% else %}
{% endif %}
Review Snippet Page (extra-review.liquid)
{% assign review = product.metafields.review %}
{% assign key = 'author' %}
{% assign key = 'author-img' %}
{% assign key = 'long' %}
<p> Hello world </p>
Any help would be brilliant
EDIT
Added review metafields layout
To check if a namespace exists you can do a comparison against blank. For example:
{% if product.metafields.review != blank %}
...
{% endif %}
You could also used the size if you wanted to ensure you had three keys. Here we simply output the size:
{{ product.metafields.review.size }}
More info on truthy/falsy can be found in the Shopify docs:
https://help.shopify.com/themes/liquid/basics/true-and-false
Truthiness in Liquid is not like Javascript. I've been bitten by this a few times:
Your test should be:
{% if product.metafields.review == true %}
...
{% endif %}
and review in product.metafields.review is the namespace of the review metafields. see https://help.shopify.com/themes/liquid/objects/metafield

Filter out collection name from product tag list (display) shopify

I would love to know how to remove from display tags that are used to automatically create collections (they appear in other product section).
For example:
$125
COLLECTION : BUSINESS
TAGS: AUTUMN BUSINESS BLACK
So that BUSINESS tag (which is used to form a BUSINESS collection ) is filtered out.
Tries the following 'straightforward' solution:
{% for tag in product.tags %}
{% unless tag == 'Business' or tag == 'Vintage' or tag == or tag == 'Boho' %}
display {{ tag }} link
{% endunless %}
{% endfor %}
Which did not see to Work
Thanks
Sometimes multiple conditions in if statements don't work so well in liquid. (See here and here.)
You could try something like this instead:
{% assign excluded_tags = "Business,Vintage,Boho" | split: "," %}
{% for tag in product.tags %}
{% unless excluded_tags contains tag %}
{{ tag }}
{% endunless %}
{% endfor %}
EDIT:
I just tested your code again, and even with the typo or tag == or..., it still works fine for me (just a warning on save).
Another suggestion is perhaps it's got to do with capitalisation. E.g. If you have a tag BUSINESS, then tag == 'Business' is not going to work. The capitalisation needs to be consistent.
EDIT 2:
From comment below:
I was thinking how to automatically populate excluded tags by the names of the collections of a product.
You can use map to get an array of collection titles:
{% assign excluded_tags = product.collections | map: 'title' %}
Your straightforward is incomplete.
{% for tag in product.tags %}
{% unless tag == 'Business' or tag == 'Vintage' or tag == <missing_value_here> or tag == 'Boho' %}
display {{ tag }} link
{% endunless %}
{% endfor %}
The third condition is empty hence could be the reason it is failing.
Also as mentioned in another answer by Steph, multiple conditions may be unstable at times, if that the case try this:
{% for tag in product.tags %}
{% unless tag == collection.title %}
display {{ tag }} link
{% endif %}
{% endfor %}
It will take care of any future collections as well.
P.S. This is assuming that the page where the tags are displaying contains a collection url.

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 !

Django template inheritance the other way round

Django template system lets you easily specify a template and fill it with different data using extends and blocks.
What I need to do is to have several templates, filled with the same data (blocks) while avoiding code repetition. It sounds like a usecase for templatetags but consider this example:
<div class="container">
{% get_tags page as tags %}
{% if tags %}
<div class="ribbon">
<span class="ribbon-inner">{{ tags|join:' | ' }}</span>
</div>
{% endif %}
</div>
If I wanted to display the tags in another template using a different html elements/classes I would have to create at least two templatetags (has_tags and get_tags) or include html in templatetags code.
I'd like to have something like this:
#common.html
{% block tags %}
{% get_tags page as tags %}
{% if tags %}
<div class="ribbon">
<span class="ribbon-inner">{{ tags|join:' | ' }}</span>
</div>
{% endif %}
{% endblock %}
#template_A.html
{% include common.html %}
<div class="container-1">
{% block tags %}
{{ block.super }}
{% endblock %}
</div>
#template_B.html
{% include common.html %}
{% block tags %}
{% get_tags page as tags %}
{{ tags|join:', ' }}
{% endblock %}
The problem is that include renders the template first, therefore it doesn't work this way. There are a lot of similar points in the file I'm editing, so creating and including template for each of them is not a great solution either.
Any thoughts?
Well, this is my solution:
#templateA.html
{% include "_common.html" with parent_file="_templateA.html" %}
#templateB.html
{% include "_common.html" with parent_file="_templateB.html" %}
#_templateA.html
<i>{% block tags %}{% endblock %}</i>
#_templateB.html
<b>{% block tags %}{{ tags|join:' & ' }}{% endblock %}</b>
#_common.html
{% extends parent_file %}
{% block tags %}
{% if not block.super %} # this does the trick
{{ tags|join:' I ' }}
{% else %}
{{ block.super }}
{% endif %}
{% endblock %}
This allows having HTML templates in _templateA.html and _templateB.html. If the block is left empty, it is filled with default from _common.html, while it can be overriden in _template.
It would be nice to override the block tag to avoid code repetition in _common.html but the following implementation fails on block.super() because of missing context.
#register.tag('overridable_block')
def overridable_block(parser, token):
from django.template.loader_tags import do_block
block = do_block(parser, token)
if block.super():
return block.parent
return block
Haven't found a way past this yet.