Django: Display images from dictionary - javascript

I have a dictionary in views.py which contains track_id and image_path. For each track_id there could be one or more image_path, hence it is a dictionary where values are passed as the list.
Example representation:
{0: ['1.jpg', '2.jpg'], 1: ['3.jpg'], 2: ['4.jpg', '5.jpg', '6.jpg']}
How can I display images on HTML?

Assuming the dictionary is passed to your template as track_images:
{% for track_id, image_paths in track_images.items %}
<div>
<h1>Track {{ track_id }}</h1>
{% for image_path in image_paths %}
<img src="{{ image_path }}" >
{% endfor %}
</div>
{% endfor %}
The timer stuff is not Django-related.

Related

Create an iterative counter in DJango template

I've checked a lot of other questions and I haven't seen my particular scenario really addressed and I've tried a lot of things out without success.
What I have is a DJango for loop in my HTML code, and within the for loop is an if statement checking if each element from the list that is being looped through equals a certain value. If that is true, then an entry is created on the page. I need to dynamically print the element number (eg. entry 1 would display as 1. and entry 2 would display as 2.)
The two best attempts I have made are:
1.
<!-- this approach prints out 1 for each entry -->
{% with counter=0 %}
{% for q in questionnaire.questions %}
{% if q.answer %}
<div class="row"><h3>
{{ counter|add:1 }}. {{ q.name }}
</h3></div>
<!-- some other code-->
{% endif %}
{% endfor %}
{% endwith %}
{% for q in questionnaire.questions %}
{% if q.answer %}
<div class="row"><h3>
<span id="displayCount">0</span>. {{ q.name }}
</h3></div>
<!-- some other code-->
{% endif %}
{% endfor %}
<script type="text/javascript">
var count = 0;
var display = document.getElementById("displayCount");
count++;
display.innerHTML = count;
</script>
Any help would be appreciated
You can access the built-in counter of your for loop using forloop.counter. It starts at 1, you can also you forloop.counter0 if you'd like to start at zero.
{% for q in questionnaire.questions %}
{% if q.answer %}
<div class="row">
<h3>
{{ forloop.counter }}. {{ q.name }}
</h3>
</div>
<!-- some other code-->
{% endif %}
{% endfor %}
Filter your queryset in your view as to avoid issues with indexing and separating presentation from logic.

Is it possible do sort Jekyll Collection and Jekyll Data in one array?

How can I sort this <ul> that the 2 for Statements are mixed?
I allready tried with javascript and jquery but I only got the error that the <ul> is NULL.
<ul>
{% assign docs = site.documents | sort: "title" %}
{% for document in docs %}
<li>
{{ document.title }} - {{ document.url }}
</li>
{% endfor %}
{% assign dataDocs = site.data.documents | sort: "title" %}
{% for document in dataDocs %}
<li>
{{ document.title }} - {{ document.url }}
</li>
{% endfor %}
</ul>
You're sorting each list rather than one list. You could make it one list before sorting, and render each item differently by giving them an extra front matter identifier (is_from_data):
<ul>
{% assign docs = site.documents | concat: site.data.documents | sort: "title" %}
{% for document in docs %}
<li>
{% if document.is_from_data %}
{{ document.title }} - {{ document.url }}
{% else %}
{{ document.title }} - {{ document.url }}
{% endif %}
</li>
{% endfor %}
</ul>
You can add is_from_data: true to each item's front matter or with Jekyll defaults in your configuration.
Older versions of Jekyll might not have the concat filter. You can get around this by pushing each element to a new array:
{% assign docs = "" | split: "" %}
{% for doc in site.documents %}
{% assign docs = docs | push: doc %}
{% endfor %}
{% for doc in site.data.documents %}
{% assign docs = docs | push: doc %}
{% endfor %}

AngularJS/HTML/CSS - Slideshow to show different link buttons and url links

I am experimenting with creating a slideshow that has four images, for example. And the thing is I want to create a link button with its own url link for each image. But what I have done is created four link buttons that appears on the slideshow, instead of the one link button that changes along with each image, and with its own url link.
{% if settings.show_block_lookbook %}
<div id="lookbook-section" class="section-full lookbook-section">
<div class="lookbook-wrapper">
<div class="lookbook-text">
<div class="lookbook-container">
<div class="container">
<div class="lb-text">
{% assign lbText1 = settings.block_lookbook_text_1 %}
{% assign lbText2 = settings.block_lookbook_text_2 %}
{% assign lbText3 = settings.block_lookbook_text_3 %}
{% assign lbText4-1 = settings.block_lookbook_text_4_1 %}
{% assign lbText4-2 = settings.block_lookbook_text_4_2 %}
{% assign lbText4-3 = settings.block_lookbook_text_4_3 %}
{% assign lbText4-4 = settings.block_lookbook_text_4_4 %}
{% assign lbLink-1 = settings.block_lookbook_link_1 %}
{% assign lbLink-2 = settings.block_lookbook_link_2 %}
{% assign lbLink-3 = settings.block_lookbook_link_3 %}
{% assign lbLink-4 = settings.block_lookbook_link_4 %}
{% if lbText1 != blank %}<h3>{{ lbText1}}</h3>{% endif %}
<div class="bg-slider-arrows">
<span class="button-prev no-border"></span>
<span class="button-next no-border"></span>
</div>
{% if lbText2 != blank %}<h2>{{ lbText2 }}</h2>{% endif %}
{% if lbText3 != blank %}<p>{{ lbText3 }}</p>{% endif %}
{% if lbText4-1 != blank %}{{ lbText4-1 }}{% endif %}
{% if lbText4-2 != blank %}{{ lbText4-2 }}{% endif %}
{% if lbText4-3 != blank %}{{ lbText4-3 }}{% endif %}
{% if lbText4-4 != blank %}{{ lbText4-4 }}{% endif %}
</div>
</div>
</div>
</div>
</div>
<div class="lookbook-bg">
{% for i in (1..4) %}
{% assign newShow = 'block_lookbook_img_' | append: i %}
{% if settings[newShow] %}
{% assign newImage = 'block_lookbook_img_' | append: i %}
<div class="lookbook-item">
<img src = "{{ newImage | append: '.jpg' | asset_url}}" alt="" />
</div>
{% endif %}
{% endfor %}
</div>
</div>
{% endif %}
I am totally lost as to what to do, as I am very very new to this. I would think I somehow need to link the images with the urls and link buttons etc, but have no idea how to code it so that each image has its own link button and url link...Any help? Any examples?
Hold on, you are not using much of angular here. I think its django or some other template with {% if %} .
Use something like:
<div ng-repeat="object in objects">
{{object.name }}
<img src="{{ object.img_path}}" />
</div>
For look try this link for ng-repeat
For the functionality u need, I would recommend you to look into cleaner approach of Carousel

Shopify Product Page to hide variant images

I am sort of new with Shopify and I´ve been playing around with it for the ast week or so without much success when trying to solve my issue.
I am currently using the Brooklyn template and the way they represent the Product Page doesn´t precisely give the best user experience. The way it´s representing the images by default is by having all the product variants images showed to the customer all the time even if he hasn´t actually picket that variant (i.e. a specific colour for the product). It also displays all the product images in a vertical way which makes navigation for the user quite frustrating if you have more than a couple of pictures per product variant.
I´ve found online a tutorial ( http://littlesnippets.ca/blogs/tutorials/15665261-grouping-images-with-variants )that addresses the part of my issue to hide the pictures of the variants that are not selected by the customer, and show them once the user click on it.(you can see an example of what I want here http://group-variant-images.myshopify.com/collections/frontpage/products/anson-chair ). This is more or less how it looks my site now (https://themes.shopify.com/themes/brooklyn/styles/brooklyn/preview).
The problem is that that tutorial is being applied to a website that is not using the exact theme/functionality that Ii do, although it´s similar.
I´ve failed to apply those changes to my theme, can anybody give me a hand?
This is my product.liquid piece of code at the moment:
<!-- /templates/product.liquid -->
<div itemscope itemtype="http://schema.org/Product">
<meta itemprop="url" content="{{ shop.url }}{{ product.url }}">
<meta itemprop="image" content="{{ product.featured_image.src | img_url: 'grande' }}">
{% assign current_variant = product.selected_or_first_available_variant %}
<div class="grid product-single">
<div class="grid__item large--seven-twelfths medium--seven-twelfths text-center">
<div class="product-single__photos">
{% assign featured_image = current_variant.featured_image | default: product.featured_image %}
{% comment %}
Display current variant image, or default first
{% endcomment %}
<div class="product-single__photo-wrapper">
<img class="product-single__photo" id="ProductPhotoImg" src="{{ featured_image | img_url: 'grande' }}" {% if settings.product_zoom_enable %}data-mfp-src="{{ featured_image | img_url: '1024x1024' }}"{% endif %} alt="{{ featured_image.alt | escape }}" data-image-id="{{ featured_image.id }}">
</div>
{% comment %}
Display rest of product images, not repeating the featured one
{% endcomment %}
{% for image in product.images %}
{% unless image contains featured_image %}
<div class="product-single__photo-wrapper">
<img class="product-single__photo" src="{{ image.src | img_url: 'grande' }}" {% if settings.product_zoom_enable %}data-mfp-src="{{ image.src | img_url: '1024x1024' }}"{% endif %} alt="{{ image.alt | escape }}" data-image-id="{{ image.id }}">
</div>
{% endunless %}
{% endfor %}
</div>
</div>
<div class="grid__item product-single__meta--wrapper medium--five-twelfths large--five-twelfths">
<div class="product-single__meta">
{% if settings.product_vendor_enable %}
<h2 class="product-single__vendor" itemprop="brand">{{ product.vendor }}</h2>
{% endif %}
<h1 class="product-single__title" itemprop="name">{{ product.title }}</h1>
<div itemprop="offers" itemscope itemtype="http://schema.org/Offer">
{% comment %}
Optionally show the 'compare at' or original price of the product.
{% endcomment %}
{% if product.compare_at_price_max > product.price %}
<span class="product-single__price--wrapper">
<span class="visually-hidden">{{ 'products.general.regular_price' | t }}</span>
<span id="ComparePrice" class="product-single__price--compare-at">
{% if current_variant.compare_at_price > current_variant.price %}
{{ current_variant.compare_at_price | money }}
{% endif %}
</span>
<span class="visually-hidden">{{ 'products.general.sale_price' | t }}</span>
</span>
{% endif %}
<span id="ProductPrice" class="product-single__price{% if product.compare_at_price > product.price %} on-sale{% endif %}" itemprop="price">
{{ current_variant.price | money }}
</span>
<hr class="hr--small">
<meta itemprop="priceCurrency" content="{{ shop.currency }}">
<link itemprop="availability" href="http://schema.org/{% if product.available %}InStock{% else %}OutOfStock{% endif %}">
<form action="/cart/add" method="post" enctype="multipart/form-data" class="product-single__form" id="AddToCartForm">
<select name="id" id="ProductSelect" class="product-single__variants">
{% for variant in product.variants %}
{% if variant.available %}
<option {% if variant == product.selected_or_first_available_variant %} selected="selected" {% endif %} data-sku="{{ variant.sku }}" value="{{ variant.id }}">{{ variant.title }} - {{ variant.price | money_with_currency }}</option>
{% else %}
<option disabled="disabled">
{{ variant.title }} - {{ 'products.product.sold_out' | t }}
</option>
{% endif %}
{% endfor %}
</select>
{% comment %}
<div class="product-single__quantity">
<label for="Quantity" class="product-single__quantity-label js-quantity-selector">{{ 'products.product.quantity' | t }}</label>
<input type="number" hidden="hidden" id="Quantity" name="quantity" value="1" min="1" class="js-quantity-selector">
</div>
{% endcomment %}
<div class="product-single__add-to-cart">
<button type="submit" name="add" id="AddToCart" class="btn">
<span id="AddToCartText">{{ 'products.product.add_to_cart' | t }}</span>
</button>
</div>
</form>
</div>
<div class="product-single__description rte" itemprop="description">
{{ product.description }}
</div>
{% if settings.social_sharing_products %}
{% include 'social-sharing' %}
{% endif %}
</div>
</div>
</div>
{% if collection %}
<hr class="hr--clear">
<div class="text-center">
← {{ 'products.general.collection_return' | t: collection: collection.title }}
</div>
{% endif %}
</div>
{% comment %}
*IMPORTANT:*
This theme uses a customized version of `option_selection.js` to support using radio inputs for color and size variants. The custom version is in `variant_selection.js`.
If you wish to enable the default dropdowns for size and color
you can change the liquid asset tag below from:
{{ 'variant_selection.js' | asset_url | script_tag }}
to
{{ 'option_selection.js' | shopify_asset_url | script_tag }}
If you use the default `option_selection.js` the labels for the dropdowns will appear outside the dropdown.
You will also need to change `.radio-wrapper` to `.selector-wrapper` below.
{% endcomment %}
{{ 'variant_selection.js' | asset_url | script_tag }}
<script>
var selectCallback = function(variant, selector) {
timber.productPage({
money_format: "{{ shop.money_format }}",
variant: variant,
selector: selector,
translations: {
addToCart : {{ 'products.product.add_to_cart' | t | json }},
soldOut : {{ 'products.product.sold_out' | t | json }},
unavailable : {{ 'products.product.unavailable' | t | json }}
}
});
};
jQuery(function($) {
new Shopify.OptionSelectors('ProductSelect', {
product: {{ product | json }},
onVariantSelected: selectCallback,
enableHistoryState: true
});
// Add label if only one product option and it isn't 'Title'. Could be 'Size'.
{% if product.options.size == 1 and product.options.first != 'Title' %}
$('.radio-wrapper:eq(0)').prepend('<label for="ProductSelect-option-0" class="single-option-radio__label">{{ product.options.first | escape }} </label>');
{% endif %}
// Hide drop-down selectors if we only have 1 variant and its title contains 'Default'.
{% if product.variants.size == 1 and product.variants.first.title contains 'Default' %}
$('.selector-wrapper').hide();
{% endif %}
});
</script>
Shopify's admin interface only allows for one product image per variant. For this reason, to do what you are trying to do isn't as easy as you are hoping. Through the Shopify API you can add metafields to products and product variants and in these metafields you can store whatever information you want -- including links to additional images. Here is a link to the documentation for the metafields on variants: https://docs.shopify.com/api/reference/product_variant
Since the admin interface doesn't really give you the ability to modify the metafields directly, you have a couple of choices:
Spend the time and energy (or money) to hook up your own management tool to the API and modify it yourself.
Purchase an app from the Shopify app store that already does this for you. Here is a link to some of these apps that should guide you in the right direction: https://apps.shopify.com/search/query?utf8=%E2%9C%93&q=variant
Either way, you'll need to come up with some sort of property name convention so you know you're dealing with images because the metafields accept whatever you feel like dropping into them.
Once you are able to define the images for your product variants, then you'll need to update the logic in your liquid/javascript to accomplish the desired functionality. You can do this a few different ways, and different people will have different opinions based on SEO but my suggestion for the path of least resistance is to do something like this:
{% for v in product.variants %}
<div id="variant_{{ v.id }}">
{% for m in v.metafields %}
{% if m.key contains "WHATEVER_CONVENTION_YOU_USED_TO_DENOTE_IMAGES" %}
{% comment %}
OUTPUT THE IMAGE TAG - PROBABLY WRAPPED IN AN ANCHOR
{% endcomment %}
{% endif %}
{% endfor %}
</div>
{% endfor %}
You'll want to incorporate some logic to show and hide the div based on the variant. Note the <div id="variant_{{ v.id }}">
The reason for this approach rather than using the api to populate js objects is that your links are already in the DOM and you can create javascript handlers when the page loads. If you wait to populate your images and links until the user selects the variant, then you'll have to deal with the event handling of dynamically created nodes.
Hope all this guides you in a good direction. If you have questions or need help feel free to reach out to me via my profile.
Additional Note: Good software developers will note the O(n^2) time complexity in the code above. Shopify doesn't execute your backend code when the page loads, rather it is executed and cached when your theme is uploaded or modified. Because of this, the poor O(n^2) time complexity won't hurt your page load performance.
As a side fun fact, this is the reason Shopify cannot create Liquid tags for things like current_time or random. Their caching mechanism which keeps sites from crashing even when being presented on Shark Tank also relies on the fact that their liquid tags, filters, and blocks don't return variable results. So, they can cache the resulting HTML and serve it directly from their caching servers...thus tags like random or current_time would only ever have an opportunity to run once.
you can try variant-image-automator paid app. this hides unnecessary images from the product page.

Django: Jquery click function not working in Ajax

I have been working through the Tango with Django exercises to cut my teeth into Django. Almost done but having a problem with the Ajax part.
Ajax function to auto_add a page is not being called. Idk what the problem is since the other functions are being called.
On the shell prompt, there is no call to the ajax function at all. Help needed.
Pertinent code attached. It is the same as on the website link above.
static/rango-ajax.js
$('.rango-add').click(function(){
var catid = $(this).attr("data-catid");
var title = $(this).atrr("data-title");
var url = $(this).attr("data-url");
$.get('/rango/auto_add_page/', {category_id: catid, url: url, title: title}, function(data){
$('#pages').html(data);
me.hide();
});
});
templates/rango/category.html
{% if user.is_authenticated %}
<button data-catid="{{category.id}}" data-title="{{ result.title }}" data-url="{{ result.link }}" class="rango-add btn btn-mini btn-info" type="button">Add</button>
{% endif %}
rango/views.py
#login_required
def auto_add_page(request):
context = RequestContext(request)
cat_id = None
url = None
title = None
context_dict = {}
if request.method == 'GET':
cat_id = request.GET['category_id']
url = request.GET['url']
title = request.GET['title']
if cat_id:
category = Category.objects.get(id=int(cat_id))
p = Page.objects.get_or_create(category=category, title=title, url=url)
pages = Page.objects.filter(category=category).order_by('-views')
#Adds our results list to the template context under name pages.
context_dict['pages'] = pages
return render_to_response('rango/page_list.html', context_dict, context)
rango/urls.py
urlpatterns = patterns('',
url(r'^$', views.index, name='index'),
url(r'^goto/$', views.track_url, name='track_url'),
url(r'^add_category/$', views.add_category, name='add_category'),
url(r'^auto_add_page/$', views.auto_add_page, name='auto_add_page'),
Complete code is at this link.
your code is good, the only thing what you have to do is to define your template in /tango/templates/rango/page_list.html. This template have the following code:
{% if pages %}
<ul>
{% for page in pages %}
<li>
{{ page.title}}
{% if page.views > 1 %}
({{page.views}} views)
{% elif page.views == 1 %}
({{page.views}} view)
{% endif %}
</li>
{% endfor %}
</ul>
{% else %}
<strong> No Pages currently in category. </strong>
{% endif %}
And inside of your category template you must define the following code:
% if category %}
{% if user.is_authenticated %}
Add a new Page <br>
{% endif %}
{% if pages %}
<div id="pages">
<ul>
{% for page in pages %}
<li>
{{ page.title}}
{% if page.views > 1 %}
({{page.views}} views)
{% elif page.views == 1 %}
({{page.views}} view)
{% endif %}
</li>
{% endfor %}
</ul>
</div>
{% else %}
<strong> No Pages currently in category. </strong>
{% endif %}
{% else %}
The specified category {{ category_name }} does not exist!
{% endif %}
I'm working through this section of the tutorial now and just want to add to Héctor's answer. To avoid duplicating the code to display the list of pages I did the following:
I added a get_page_list() method to tango/rango/templatetags/rango_extras.py, similar to the get_category_list() method used to display a list of categories in an earlier section of the tutorial.
from rango.models import Page
#register.inclusion_tag("rango/page_list.html")
def get_page_list(category):
pages = Page.objects.filter(category=category) if category else []
return {'pages': pages}
Then we just need to load rango_extras and call the get_page_list() method in tango/templates/rango/category.html.
{% extends 'rango/base.html' %}
{% load rango_extras %}
<!-- Existing code -->
{% if category %}
<!-- Existing code to show category likes and like button -->
<div id="page_list">
{% get_page_list category %}
</div>
<!-- Existing code to show search if user is authenticated -->
{% else %]
The specified category {{ category_name }} does not exist!
{% endif %}
This allows you to display the list of pages when a category page is first loaded and then refresh it if a category is added from the search area, without having to duplicate any code.

Categories

Resources