django template <img src="{% static "/static/{{ image_name }}" %}" alt="my image"> does not work - static

In views.py:
image_name = PUserSliderimg.objects.filter(uid=1).values('sliderimg')
This works in html file and we can see the image:
{% load staticfiles %}
<img src="{% static "/static/cat.jpg" %}" alt="my image">
But those below does not work:
{% load staticfiles %}
#output => my image
<img src="{% static "/static/{{ image_name }}" %}" alt="my image">
#output => cat.jpg
{% for each in image_name %}
{{ each.sliderimg }}
{% endfor %}
#output => my image
{% for each in image_name %}
<img src="{% static "/static/{{ each.sliderimg }}" %}" alt="my image">
{% endfor %}
#output => [{'sliderimg': 'cat.jpg'}]
{{ image_name }}<br>
How can I get the name from db and put it in the code in order to appear image on the web page?
==================================
I even tried this:
In views.py:
photo = 'cat.jpg'
In html file:
{% for each in image_name %}
<img src="{% static "/static/{{ photo }}" %}" alt="my image">
But for the output, the word cat.jpg appeared only.
===================================
I found the answer myself, I edited the code like this:
<img src="/static/{{ photo }}" alt="my image">
And it worked. But why?
I tried to show an image on an other page before and I found that using {% static ... %} was needed, but here the code worked without using {% static ... %}. So can someone tell me why?!

Related

Multiple Dictionary Output

There is a section that is running on my flask server, and the HTML file itself. I'm trying to create a sort of results area, where it will display various parts of the dictionary. The code is working, but I'm only able to show a single result instead of multiple results. Any help to show the rest of the dictionary results on the page, instead of a single one will be helpful. Thanks.
(I didn't show the full code on my last question)
#app.route('/results')
def results():
parameters = {
"product_type": "blush"
}
response = requests. Get(API, json=parameters)
# print(response.status_code)
response.raise_for_status()
data = response.json()
for item in data:
brand=item["brand"],
name = item["name"],
price = item["price"],
description = item['description'],
product_link = item["product_link"],
website_link = item["website_link"],
tags = item["tag_list"]
return render_template('results.html',brand=brand, name=name, price=price, description=description, product_link=product_link,
website_link=website_link, tags=tags)
{% include 'header.html' %}
<body>
<section id="results">
<h1 class="results-heading">Search Results</h1>
<hr>
<div class="contents">
<p class="content-title"><strong>Brand: </strong>{{ brand }}</p>
<p class="content-title"><strong>Name: </strong>{{ name }}</p>
<p class="content-title"><strong>Product Price: </strong>
{% if price %}
${{ price.split('.')[0] }}
{% else %}
Not available
{% endif %}
</p>
<p class="content-title"><strong>Product Description: </strong>{{ description }}</p>
<p class="content-title"><strong>Product Link: </strong>{{ product_link }}</p>
<p class="content-title"><strong>Website Link: </strong>{{ website_link }}</p>
<p class="content-title"><strong>Relevant Tags: </strong>
{% if tags %}
{% for tag in tags %}
{{ tag }},
{% endfor %}
{% else %}
No Tags
{% endif %}
</p>
</div>
</section>
</body>
Your "return" statement is in the for loop, so it will terminate after the first interaction.
You can run the for loop in the template and pass the list to the render_template
Send data to template and then loop through each item in data, using jinja
#app.route('/results')
def results():
parameters = {
"product_type": "blush"
}
response = requests. Get(API, json=parameters)
# print(response.status_code)
response.raise_for_status()
data = response.json()
return render_template('results.html', data=data)
{% include 'header.html' %}
<body>
<section id="results">
<h1 class="results-heading">Search Results</h1>
<hr>
<div class="contents">
{% for item in data %}
<p class="content-title"><strong>Brand: </strong>{{ item["brand"] }}</p>
<p class="content-title"><strong>Name: </strong>{{ item["name"] }}</p>
<p class="content-title"><strong>Product Price: </strong>
{% if item["price"] %}
${{ item["price"].split('.')[0] }}
{% else %}
Not available
{% endif %}
</p>
<p class="content-title"><strong>Product Description: </strong>{{ item['description'] }}</p>
<p class="content-title"><strong>Product Link: </strong>{{ item["product_link"] }}</p>
<p class="content-title"><strong>Website Link: </strong>{{ item["website_link"] }}</p>
<p class="content-title"><strong>Relevant Tags: </strong>
{% if item["tag_list"] %}
{% for tag in item["tag_list"] %}
{{ tag }},
{% endfor %}
{% else %}
No Tags
{% endif %}
</p>
{% endfor %}
</div>
</section>
</body>

wagtail 'your first site': how do I link to original of gallery image?

In the getting started tutorial for wagtail there is the following code in a template:
{% for item in page.gallery_images.all %}
<div style="float: left; margin: 10px">
{% image item.image fill-320x240 %}
<p>{{ item.caption }}</p>
</div>
{% endfor %}
Please excuse me if I'm missing something obvious but I can't find out how to do this in the docs. How would I link to the original file? eg:
{% image item.image fill-320x240 %}
You'll want to use the {{ img.url }} property in your template.
{% for item in page.gallery_images.all %}
<div style="float: left; margin: 10px">
{% image item.image fill-320x240 as img %}
<p>{{ item.caption }}</p>
{% comment %}
Assign your image `as img` (doesn't need to be `img`, you can
use any alias you'd like
{% endcomment %}
<img href="{{ img.url }}" alt="{{ img.alt }}" />
This is the link to your image
</div>
{% endfor %}
By assigning your image an alias, such as as img (in the code above) you can use {{ img.property_name }} in your template.

How to assign values to an array using HubSpot's HubL

I'm currently trying to figure out how to allow a content manager to change the order in which elements appear within recent post link lists. Essentially, the concept involves them picking the index in a sorting array that will hold that element's type as a string, which will later be iterated over with output logic determining where each piece gets placed. Unfortunately, one of the drawbacks of using HubL is the lack of debugging or error reporting so I can't see where my syntax is failing. I was wondering if anyone in InternetLand has had any similar experience with this.
Here's the HubL:
<div class="theme-recent-posts">
{% if widget.title_name %}
<div class="theme-recent-posts-title">
<{{ widget.title_tag }}><span>{{ widget.title_name }}</span></{{ widget.title_tag }}>
</div>
{% endif %}
{% set posts = blog_recent_posts(widget.select_blog, widget.max_links) %}
{% for post in posts %}
{% set item_objects = [] %}
{% if widget.show_images == "true" %}
{% set item_objects[widget.sort_images] = "image" %}
{% endif %}
{% if widget.show_titles == "true" %}
{% set item_objects[widget.sort_titles] = "title" %}
{% endif %}
{% if widget.show_dates == "true" %}
{% set item_objects[widget.sort_dates] = "date" %}
{% endif %}
{% if widget.show_authors == "true" %}
{% set item_objects[widget.sort_authors] = "author" %}
{% endif %}
<div class="theme-recent-posts-item">
<a href="{{ post.absolute_url }}">
{% for object in item_objects %}
{% if object == "image" %}
<span class="theme-recent-posts-item-image"><img src="{{ post.featured_image }}" alt="{{ post.name }}" /></span>
{% endif %}
{% if object == "title" %}
<span class="theme-recent-posts-item-title">{{ post.name }}</span>
{% endif %}
{% if object == "date" %}
<span class="theme-recent-posts-item-date">{{ post.created }}</span>
{% endif %}
{% if object == "author" %}
<span class="theme-recent-posts-item-author">{{ post.author_name }}</span>
{% endif %}
{% endfor %}
</a>
</div>
{% endfor %}
</div>
Output currently results in:
<div class="theme-recent-posts">
<div class="theme-recent-posts-title">
<h2><span>Recent Posts</span></h2>
</div>
<div class="theme-recent-posts-item">
</div>
<div class="theme-recent-posts-item">
</div>
<div class="theme-recent-posts-item">
</div>
</div>
Assume the default values wired up in the widget panel:
widget.show_images = true
widget.show_images = true
widget.show_images = true
widget.show_images = true
widget.sort_images = 0
widget.sort_titles = 1
widget.sort_dates = 2
widget.sort_authors = 3
The output should essentially be this:
<div class="theme-recent-posts">
<div class="theme-recent-posts-title">
<h2><span>Recent Posts</span></h2>
</div>
<div class="theme-recent-posts-item">
<a href="//website/path/post-name-3">
<span class="theme-recent-posts-item-image"><img src="path/to/image-3.ext" alt="Post Name 3" /></span>
<span class="theme-recent-posts-item-title">Post Name 3</span>
<span class="theme-recent-posts-item-date">1234567890</span>
<span class="theme-recent-posts-item-author">FirstName LastName</span>
</a>
</div>
<div class="theme-recent-posts-item">
<a href="//website/path/post-name-2">
<span class="theme-recent-posts-item-image"><img src="path/to/image-2.ext" alt="Post Name 2" /></span>
<span class="theme-recent-posts-item-title">Post Name 2</span>
<span class="theme-recent-posts-item-date">1234567890</span>
<span class="theme-recent-posts-item-author">FirstName LastName</span>
</a>
</div>
<div class="theme-recent-posts-item">
<a href="//website/path/post-name-1">
<span class="theme-recent-posts-item-image"><img src="path/to/image-1.ext" alt="Post Name 1" /></span>
<span class="theme-recent-posts-item-title">Post Name 1</span>
<span class="theme-recent-posts-item-date">1234567890</span>
<span class="theme-recent-posts-item-author">FirstName LastName</span>
</a>
</div>
</div>
I'm going to tag Jinja in this post, because HubL is based on Jinja, though it's not a direct translation.
If someone with enough reputation is reading this, I would greatly appreciate the addition of the HubL language tag, as it currently does not exist to select (even though HubSpot was).
Update
Twig is also a close cousin to HubL, and so I looked up how to update elements in an array there, and came up with this answer:
Setting element of array from Twig
{% set item_objects = item_objects|merge({widget.sort_images:"image"}) %}
Implementation did not work as expected. Output remains unchanged.
While this is not an answer to the question I asked, it is an alternate solution, so I provide it as a work around until a real solution is determined.
<div class="theme-recent-posts">
{% if widget.title_name %}
<div class="theme-recent-posts-title">
<{{ widget.title_tag }}><span>{{ widget.title_name }}</span></{{ widget.title_tag }}>
</div>
{% endif %}
{% set object_order = [0, 1, 2, 3] %}
{% set posts = blog_recent_posts(widget.select_blog, widget.max_links) %}
{% for post in posts %}
<div class="theme-recent-posts-item">
<a href="{{ post.absolute_url }}">
{% for order in object_order %}
{% if widget.show_images == "true" and widget.sort_images == order %}
<span class="theme-recent-posts-item-image"><img src="{{ post.featured_image }}" alt="{{ post.name }}" /></span>
{% endif %}
{% if widget.show_titles == "true" and widget.sort_titles == order %}
<span class="theme-recent-posts-item-title">{{ post.name }}</span>
{% endif %}
{% if widget.show_dates == "true" and widget.sort_dates == order %}
<span class="theme-recent-posts-item-date">{{ post.created }}</span>
{% endif %}
{% if widget.show_authors == "true" and widget.sort_authors == order %}
<span class="theme-recent-posts-item-author">{{ post.author_name }}</span>
{% endif %}
{% endfor %}
</a>
</div>
{% endfor %}
</div>
This gives me the flexibility I was looking for and the code is actually lightened quite a bit from the original proposed method. The idea is to use the object_order list as a mask for the for order in object_order loop. This gets the job done, and while I know it's hacky, it has a touch of elegance to it.

Using ajax with sonata admin list view pagination

I'm using sonata admin in my project. In the list view sonata refresh the page when I clik to get the second list from pagination. That's the default behavior of sonata.Is there any way to use ajax call with list view pagination !!!
Same question when using sortable list view.
Thanks.
This is possible, but you have to overwrite some of the basic functionality of the sonata admin bundle.
Tested with
symfony 2.6.6
sonata admin-bundle dev-master (4f23e1a30e49681bf8ebdbbae549848784be7699)
1. Edit your bundles services.yml
You have to implement your own CrudController and a new list template. Tell this in services.yml
sonata.admin.youradmin:
class: Your\Bundle\Admin\YourAdmin
tags:
- { name: sonata.admin, manager_type: orm, group: "groupname", label: "grouplabel" }
arguments:
- ~
- Your\Bundle\Entity\EntityClass
- YourBundle:YourNewCrud # <- add your crud class here
calls:
- [ setLabelTranslatorStrategy, ["#sonata.admin.label.strategy.underscore"]]
- [ setTemplate, [list, YourBundle:YourAdmin:list.html.twig]] # <- tell sonata you want this template for list
2. Add new twig template
Now add the following template to your bundles Resources/views/YourAdmin/list.html.twig:
{# extends from the normal base_list.html.twig, but when this template is
rendered via an ajax-call, extend from an ajax-list.html.twig, we'll
add later #}
{% extends app.request.xmlHttpRequest
? 'YourBundle:ajax-list.html.twig'
: 'SonataAdminBundle:CRUD:base_list.html.twig' %}
{# YourBundle:ajax-list.html.twig is the path where you have your template, if your template is inside views/Admin, then put it like this: YourBundle:Admin:ajax-list.html.twig #}
{# Here I copied the list_table block from the original list.html.twig
from sonata.. I added custom JS-code below to do the ajax call #}
{% block list_table %}
{# The code in this block is copied from sonata.. I just added the JS-code below, and added the 'actionList' id here #}
<div id="actionList" class="col-xs-12 col-md-12">
{% if admin.hasRoute('batch') %}
<form action="{{ admin.generateUrl('batch', {'filter': admin.filterParameters}) }}" method="POST" >
<input type="hidden" name="_sonata_csrf_token" value="{{ csrf_token }}">
{% endif %}
{# Add a margin if no pager to prevent dropdown cropping on window #}
<div class="box box-primary" {% if admin.datagrid.pager.lastPage == 1 %}style="margin-bottom: 100px;"{% endif %}>
<div class="box-body {% if admin.datagrid.results|length > 0 %}table-responsive no-padding{% endif %}">
{{ sonata_block_render_event('sonata.admin.list.table.top', { 'admin': admin }) }}
{% block list_header %}{% endblock %}
{% set batchactions = admin.batchactions %}
{% if admin.datagrid.results|length > 0 %}
<table class="table table-bordered table-striped sonata-ba-list">
{% block table_header %}
<thead>
<tr class="sonata-ba-list-field-header">
{% for field_description in admin.list.elements %}
{% if admin.hasRoute('batch') and field_description.getOption('code') == '_batch' and batchactions|length > 0 %}
<th class="sonata-ba-list-field-header sonata-ba-list-field-header-batch">
<input type="checkbox" id="list_batch_checkbox">
</th>
{% elseif field_description.getOption('code') == '_select' %}
<th class="sonata-ba-list-field-header sonata-ba-list-field-header-select"></th>
{% elseif field_description.name == '_action' and app.request.isXmlHttpRequest %}
{# Action buttons disabled in ajax view! #}
{% elseif field_description.getOption('ajax_hidden') == true and app.request.isXmlHttpRequest %}
{# Disable fields with 'ajax_hidden' option set to true #}
{% else %}
{% set sortable = false %}
{% if field_description.options.sortable is defined and field_description.options.sortable %}
{% set sortable = true %}
{% set sort_parameters = admin.modelmanager.sortparameters(field_description, admin.datagrid) %}
{% set current = admin.datagrid.values._sort_by == field_description or admin.datagrid.values._sort_by.fieldName == sort_parameters.filter._sort_by %}
{% set sort_active_class = current ? 'sonata-ba-list-field-order-active' : '' %}
{% set sort_by = current ? admin.datagrid.values._sort_order : field_description.options._sort_order %}
{% endif %}
{% spaceless %}
<th class="sonata-ba-list-field-header-{{ field_description.type}} {% if sortable %} sonata-ba-list-field-header-order-{{ sort_by|lower }} {{ sort_active_class }}{% endif %}">
{% if sortable %}<a href="{{ admin.generateUrl('list', sort_parameters) }}">{% endif %}
{{ admin.trans(field_description.label, {}, field_description.translationDomain) }}
{% if sortable %}</a>{% endif %}
</th>
{% endspaceless %}
{% endif %}
{% endfor %}
</tr>
</thead>
{% endblock %}
{% block table_body %}
<tbody>
{% include admin.getTemplate('outer_list_rows_' ~ admin.getListMode()) %}
</tbody>
{% endblock %}
{% block table_footer %}
{% endblock %}
</table>
{% else %}
<div class="info-box">
<span class="info-box-icon bg-aqua"><i class="fa fa-arrow-circle-right"></i></span>
<div class="info-box-content">
<span class="info-box-text">{{ 'no_result'|trans({}, 'SonataAdminBundle') }}</span>
<div class="progress">
<div class="progress-bar" style="width: 0%"></div>
</div>
<span class="progress-description">
{% if not app.request.xmlHttpRequest %}
{% include 'SonataAdminBundle:Button:create_button.html.twig' %}
{% endif %}
</span>
</div><!-- /.info-box-content -->
</div>
{% endif %}
{{ sonata_block_render_event('sonata.admin.list.table.bottom', { 'admin': admin }) }}
</div>
{% block list_footer %}
{% if admin.datagrid.results|length > 0 %}
<div class="box-footer">
<div class="form-inline clearfix">
{% if not app.request.isXmlHttpRequest %}
<div class="pull-left">
{% if admin.hasRoute('batch') and batchactions|length > 0 %}
{% block batch %}
<script>
{% block batch_javascript %}
jQuery(document).ready(function ($) {
$('#list_batch_checkbox').on('ifChanged', function () {
$(this)
.closest('table')
.find('td.sonata-ba-list-field-batch input[type="checkbox"], div.sonata-ba-list-field-batch input[type="checkbox"]')
.iCheck($(this).is(':checked') ? 'check' : 'uncheck')
;
});
$('td.sonata-ba-list-field-batch input[type="checkbox"], div.sonata-ba-list-field-batch input[type="checkbox"]')
.on('ifChanged', function () {
$(this)
.closest('tr, div.sonata-ba-list-field-batch')
.toggleClass('sonata-ba-list-row-selected', $(this).is(':checked'))
;
})
.trigger('ifChanged')
;
});
{% endblock %}
</script>
{% block batch_actions %}
<label class="checkbox" for="{{ admin.uniqid }}_all_elements">
<input type="checkbox" name="all_elements" id="{{ admin.uniqid }}_all_elements">
{{ 'all_elements'|trans({}, 'SonataAdminBundle') }}
({{ admin.datagrid.pager.nbresults }})
</label>
<select name="action" style="width: auto; height: auto" class="form-control">
{% for action, options in batchactions %}
<option value="{{ action }}">{{ options.label }}</option>
{% endfor %}
</select>
{% endblock %}
<input type="submit" class="btn btn-small btn-primary" value="{{ 'btn_batch'|trans({}, 'SonataAdminBundle') }}">
{% endblock %}
{% endif %}
</div>
<div class="pull-right">
{% if admin.hasRoute('export') and admin.isGranted("EXPORT") and admin.getExportFormats()|length %}
<div class="btn-group">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
<i class="glyphicon glyphicon-export"></i>
{{ "label_export_download"|trans({}, "SonataAdminBundle") }}
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
{% for format in admin.getExportFormats() %}
<li>
<a href="{{ admin.generateUrl('export', admin.modelmanager.paginationparameters(admin.datagrid, 0) + {'format' : format}) }}">
<i class="glyphicon glyphicon-download"></i>
{{ format|upper }}
</a>
<li>
{% endfor %}
</ul>
</div>
-
{% endif %}
{% block pager_results %}
{% include admin.getTemplate('pager_results') %}
{% endblock %}
</div>
{% endif %}
</div>
{% block pager_links %}
{% if admin.datagrid.pager.haveToPaginate() %}
<hr/>
{% include admin.getTemplate('pager_links') %}
{% endif %}
{% endblock %}
</div>
{% endif %}
{% endblock %}
</div>
{% if admin.hasRoute('batch') %}
</form>
{% endif %}
</div>
{# When this request is not via ajax, add the following JS-code
this will trigger an ajax-request, and uses the normal a-href location #}
{% if not app.request.xmlHttpRequest %}
<script>
$('body').on('click', '.pagination li a', function(e){
var url = $(this).attr('href');
$.post(url,
{},
function(response){
if(response.code == 100 && response.success){
$('#actionList').replaceWith(response.content);
}
}
);
e.preventDefault();
return false;
});
</script>
{% endif %}
{% endblock %}
3. Add ajax template
We do this to prevent the original bundle to output everything we don't need:
YourBundle/Resources/views/YourAdmin/ajax-list.html.twig:
{% block list_table %}{% endblock %}
4. Add custom CrudController
Now the only thing left to do is, that we want to overwrite the original listAction so that we can return JSON in stead of pure HTML. Add YourCrudController.php in YourBundle/Controller/
Add the following
<?php
namespace Your\Bundle\Controller;
use Sonata\AdminBundle\Controller\CRUDController as Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
class YourCrudController extends Controller
{
public function listAction(Request $request = null)
{
// call original listAction function to get the right HTML
$response = parent::listAction($request);
if($request->isXmlHttpRequest()) {
// disable the profile, to prevent profiler code
$this->container->get('profiler')->disable();
// return JsonResponse
return new JsonResponse(array('success' => true, 'code' => 100, 'content' => $response->getContent()));
}
return $response;
}
}
Sit back, hit f5, click the pager and enjoy!

Overriding app engine template block inside an if

I have a block 'left_area' defined in a base appengine template
{% block left_area %}
<div class="span3">
Left area content
</div>
{% endblock %}
In a child template, I want to override this block inside an if
{% if not user %}
{% block left_area %}
<div class="span2">
</div>
{% endblock %}
{% endif %}
This is not working for some reason. Any suggestion?
In jinja you can solve it with super(), which renders the parent block:
{% block left_area %}
{% if not user %}
<div class="span2">
</div>
{% else %}
{{ super() }}
{% endif %}
{% endblock %}

Resources