Can I create and manipulate a Map in jekyll liquid? - jekyll

I want to calculate total sums while processing a table, so as rendering goes row by row but I need totals over the columns, I need a counter per column.
{% assign cols = "col1,col2" | split: "," %}
{% assign rows = "row1,row2" | split: "," %}
{% assign total = ????? %}
...
{% for row in rows %}
<tr>
{% for col in cols %}
<td>
{% for post in site.posts %}
{% if post.colThing == col and post.rowThing == row %}
{% assign total[row] = total[row] | plus: post.thatNumber %}
.... {{ post.thatNumber }} ...
{% endif %}
{% endfor %}
</td>
{% endfor %}
</tr>
{% endfor %}
<tr>
{% for col in cols %}
<td>
.... {{ total[row] }} ...
</td>
{% endfor %}
</tr>
The best I could come up with is to parse the site.posts again for the total:
...
<tr>
{% for col in cols %}
{% assign total = 0 %}
{% for post in site.posts %}
{% if post.colThing == col %}
{% assign total = total | plus: post.thatNumber %}
{% endif %}
{% endfor %}
<td>
.... {{ total }} ...
</td>
{% endfor %}
</tr>
Is that the most efficient way of getting that total?

Your idea of using a hash to store totals is evident except that Jekyll cannot manipulate ruby hashes. total[row] is a hash entry that cannot be populated from liquid.
The way you're printing your totals is one of the solutions.
On the Efficiency side,it might be interesting to explore an other way if you want to avoid to loop over all posts each time you want to populate a cell, by using where and where_exp filters. Depending of the number of posts you're manipulating, this can be more efficient :
{% assign cols = "col1,col2" | split: "," %}
{% assign rows = "row1,row2" | split: "," %}
<thead><tr>{% for col in cols %}<th>{{ col }}</th>{% endfor %}</tr></thead>
{% for row in rows %}
<tr>
{% for col in cols %}
<td>
{% comment %}
where_exp: "post", "post.colThing == col and post.rowThing == row"
returns null if no post fulfill conditions
or
returns an array of posts fulfilling conditions
first
returns the first post of the returned array
{% endcomment %}
{% assign post = site.posts | where_exp: "post", "post.colThing == col and post.rowThing == row" | first %}
{% if post != null %}
{{ post.title }} : {{ post.thatNumber }}
{% else %}
NO DATAS AT THIS POSITION
{% endif %}
</td>
{% endfor %}
</tr>
{% endfor %}
<tfoot><tr>
{% for col in cols %}
{% assign total = 0 %}
{% comment %}
Select posts that are in each column
{% endcomment %}
{% assign posts = site.posts | where: "colThing", col %}
{% for post in posts %}
{% assign total = total | plus: post.thatNumber %}
{% endfor %}
<td>{{ total }}</td>
{% endfor %}
</tr></tfoot>

Related

Data view in html table from django views

I am trying to display data the tables from the database in some tables in an HTML template from django views. The problem is that the words are in a list and I want each word to be in each field in the table, How can I do that?
views.py:
def index(request):
if request.method == 'POST':
tp = request.POST.get('tp')
ms = request.POST.get('mode_selection')
if tp == "Download" or tp == "Preview":
usr = User.objects.get(username=request.user)
if ms=='2':
data=WordDifferentTable.objects.filter(user=usr).values_list('word1','word2',word3', 'word4', 'word5', 'result')
hds = ['word1', 'word2', 'word3', 'word4', 'word5', 'result']
elif ms=='3':
data = LogicAnaloguiesTable.objects.filter(user=usr).values_list('word1', 'word2',
'word3', 'word4', 'word5', 'result', 'distance_to_word12')
hds = ['word1', 'word2', 'word3', 'word4', 'word5', 'result',
'distance_to_word12']
elif ms=='4':
data = SimilarWInContextTable.objects.filter(user=usr).values_list('word1',
'word2', 'word3', 'word4', 'word5', 'distance_to_word12', 'distance_to_word13',
'distance_to_word23')
hds = ['word1', 'word2', 'word3', 'word4', 'word5', 'distance_to_word12',
'distance_to_word13', 'distance_to_word23']
else:
data = WordsTable.objects.filter(user=usr).values_list('word1', 'word2', 'word3',
'word4', 'word5',)
hds = ['word1', 'word2', 'word3', 'word4', 'word5',]
return render (request, "base.html",context)
else:
return render (request, "base.html")
HTML table:
{% if data %}
<div style="padding-top: 30px" class="row">
<h3 align="center">Preview</h3>
<table style="border: 1px solid #dddddd;">
<thead>
<tr style="border: 1px solid;">
{% for h in hds %}
<th style="border: 1px solid;">{{h}}</th>
{% endfor %}
</tr>
</thead>
<tbody style="border: 1px solid;">
{% for d in data %}
<tr>
{% for word in data %}
<td style="border: 1px solid;">{{ word }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
An example of how the data is shown, I want each word to be in each field:
When you iterate over data you get tuples, you need to iterate over each tuple to get your table cells
{% for d in data %}
<tr>
{% for word in data %}
<td style="border: 1px solid;">{{ word }}</td>
{% endfor %}
</tr>
{% endfor %}

Jinja2 if statement, where MySQL date type is null

I am generating a table using the jinja2 notation, within a flask app querying data from a MySQL database.
The html template:
{% for j in JRN %}
<tr>
<td>{{ j[0] }}</td>
{% if j[1] != '0000-00-00' %}
<td>{{ j[1] }}</td>
{% else %}
<td></td>
{% endif %}
...
{% endfor %}
producing:
Where Date, j[1], is null, or ‘0000-00-00’, I would like the table to be blank, rather than ‘None’.
The Date field is of type: date
In addition to the if clause shown above, I have tried:
...
{% elif j[1] != '0' %}
<td>{{ j[1] }}</td>
{% elif j[1] != 0 %}
<td>{{ j[1] }}</td>
{% elif j[1] != 'None' %}
<td>{{ j[1] }}</td>
{% elif j[1] != 'NULL' %}
<td>{{ j[1] }}</td>
{% else %}
<td></td>
...
Thanks for your help
Why don't you try using HTML entities to keep that area blank
updated code:
{% for j in JRN %}
<tr>
<td>{{ j[0] }}</td>
{% if j[1] != '0000-00-00' %}
<td>{{ j[1] }}</td>
{% endif %}
{% if j[1] == '0000-00-00' %}
<td> </td>
{% endif %}
{% endfor %}
Let me know if the problem persists.

Equivalent between `MySQL JOIN` and Django

I'm using Django 1.11 and I would like to get the correct syntax in order to translate my MySQL Join request to Django QuerySet Syntax.
I have 3 different models (1 Model in my Identity application and 2 Models in my Fiscal application) as following :
#Identity.Individu
class Individu(models.Model):
NumeroIdentification = models.CharField(max_length=30, null=True, verbose_name='Numero Identification physique', unique=True)
Civilite = models.CharField(max_length=12,choices=CHOIX_TITRE, verbose_name='Civilité')
NomJeuneFille = models.CharField(max_length=30, verbose_name='Nom de jeune fille', blank=True)
Nom = models.CharField(max_length=30, verbose_name='Nom de famille')
Prenom = models.CharField(max_length=30, verbose_name='Prénom(s)')
#Fiscal.Profession
class Profession (models.Model) :
Employe = models.ForeignKey(Individu, related_name='Individu', verbose_name='Individu', null=False, to_field='NumeroIdentification')
Entreprise = models.ForeignKey(Societe, related_name='Société', verbose_name='Société', null=False, to_field='NumeroIdentification')
NumeroImpot = models.CharField(max_length=30, null=True, verbose_name='Numéro Imposition', unique=True)
Profession = models.CharField(max_length=30, verbose_name='Profession')
#Fiscal.Salaire
class Salaire (models.Model) :
Employe = models.ForeignKey(Individu, related_name='Salaire_Individu', verbose_name='Salaire_Individu', null=False, to_field='NumeroIdentification')
Salaire_B_mensuel = models.IntegerField(verbose_name='Salaire Brut Mensuel')
Salaire_N_mensuel = models.IntegerField(verbose_name='Salaire Net Mensuel')
With Mysql, I have this request which works fine :
SELECT * FROM Identity_individu i
INNER JOIN Fiscal_profession p ON i.NumeroIdentification = p.Employe_id
INNER JOIN Fiscal_salaire s on i.NumeroIdentification = s.Employe_id;
I thing I have to use prefetch_related and I wrote this (first step, join between two tables) :
#login_required
def FiscalReporting(request) :
Contribuable = Individu.objects.prefetch_related("Profession").all().filter(NumeroIdentification=Profession.Employe)
context = {
"Contribuable" : Contribuable,
}
return render(request, 'Fiscal_Reporting.html', context)
And in my template :
<table style="width:120%">
<tbody>
<tr>
<th>ID</th>
<th>État</th>
<th>N° Identification</th>
<th>Civilité</th>
<th>Nom</th>
<th>Prénom</th>
<th>Date de Naissance</th>
<th>N° Fiscal</th>
<th>Salaire Annuel Net</th>
</tr>
{% for item in Contribuable %}
<tr>
<td>{{ item.id}}</td>
<td>{{ item.Etat}}</td>
<td>{{ item.NumeroIdentification}}</td>
<td>{{ item.Civilite }}</td>
<td>{{ item.Nom }}</td>
<td>{{ item.Prenom }}</td>
<td>{{ item.DateNaissance }}</td>
<td>{{ item.NumeroImpot }}</td>
<td>{{ item.Employe.Salaire_N_annuel }}</td>
</tr>
{% endfor %}
</tbody>
</table>
Any idea about my issue ? I don't find any result up to now because my array is empty :/
Then, How I can add a supplementary join in my Django QuerySet ?
You can use prefetch_related to prefetch more than one related table like this:
Contribuable = Individu.objects.prefetch_related("Individu", "Salaire_Individu")
Note that I use "Individu" related_name of Profession model as prefetch_related argument.
Now in template you can iterate over each profession and Salaire_Individu like this:
{% for item in Contribuable %}
...
<td>{{ item.Nom }}</td>
{% for profession in item.Individu.all %}
<td>{{ profession.NumeroImpot }}</td>
{% endfor %}
{% for salary in item.Salaire_Individu.all %}
<td>{{ salary.Salaire_B_mensuel }}</td>
{% endfor %}
{% endfor %}

Set an accordion menu default to show the content instead of hiding it in Liquid

On the side bar of my product pages there are filters within an accordian style menu.
Preview: https://www.shoplovestitch.com/collections/new-arrival-dresses
I'm trying to make the accordion menu's for filters default to be unhidden/open instead of defaulting to closed.
{% comment %} *** FILTER BY *** {% endcomment %}
{% if collection.products.size > 0 %}
<h4 class="sidebar-title collapsed" data-toggle-target="sidebar-filter-group">
Filter By
<i class="fa fa-angle-up" aria-hidden="true"></i>
</h4>
<div id="sidebar-filter-group" class="sidebar-group">
{% comment %} *** FILTER BY SIZE *** {% endcomment %}
{% assign size_tags = settings.collection_sidebar_size_tags | strip_newlines | replace: ' ,', ',' | replace: ', ', ',' | split: ',' %}
{% assign filters_selected_tags = '' %}
{% for size_tag in size_tags %}
{% assign tag_search = size_tag | replace: '-', ' ' %}
{% if current_tags contains tag_search %}
{% assign filters_selected_tags = filters_selected_tags | append: tag_search | append: ',' %}
{% endif %}
{% endfor %}
{% assign filters_selected_tags = filters_selected_tags | split: ',' %}
<div class="accordian-group" data-selected-count="{{ filters_selected_tags.size }}">
<div class="accordian-heading">
<a class="collapsed" href="#">{{ settings.collection_sidebar_size_title }}</a>
</div>
<div class="accordian-body">
{% if filters_selected_tags.size > 0 %}
{% assign current_tags_modifier = '' %}
{% for t in current_tags %}
{% unless filters_selected_tags contains t %}
{% assign h = t | handle %}
{% assign current_tags_modifier = current_tags_modifier | append: h | append: ',' %}
{% endunless %}
{% endfor %}
{% assign current_tags_modifier = current_tags_modifier | split: ',' | join: '+' %}
{% assign clear_selected_url = collection.url | append: '/' | append: current_tags_modifier %}
<div class="clear-selected">
<a href="{{ clear_selected_url }}">
<i class="fa fa-times-circle" aria-hidden="true"></i> Clear {{ settings.collection_sidebar_size_title }}
</a>
</div>
{% endif %}
<ul class="multi-select buttons">
{% for size_tag in size_tags %}
{% assign tag_name = size_tag %}
{% assign tag_search = tag_name | replace: '-', ' ' %}
{% capture link_html %}
{% if current_tags contains tag_search %}
{{ tag_name | link_to_remove_tag: tag_search }}
{% else %}
{{ tag_name | link_to_add_tag: tag_search }}
{% endif %}
{% endcapture %}
{% assign link_href = '' %}
{% assign link_html = link_html | escape %}
{% if link_html contains 'href="' %}
{% assign link_html = link_html | split: 'href="' %}
{% assign link_html = link_html[1] | split: '"' %}
{% assign link_href = link_html[0] %}
{% endif %}
{% if collection.tags contains tag_name %}
<li>
{% if current_tags contains tag_search %}
<a class="active" title="{{ tag_name }}" href="{{ link_href }}">{{ tag_name }}</a>
{% else %}
<a title="{{ tag_name }}" href="{{ link_href }}">{{ tag_name }}</a>
{% endif %}
</li>
{% endif %}
{% endfor %}
</ul>
</div>
</div>
{% comment %} *** FILTER BY COLOR *** {% endcomment %}
{% assign color_tags = settings.collection_sidebar_color_tags | strip_newlines | replace: ' ,', ',' | replace: ', ', ',' | split: ',' %}
{% assign filters_selected_tags = '' %}
{% for color_tag in color_tags %}
{% assign tag_search = color_tag | replace: '-', ' ' %}
{% if current_tags contains tag_search %}
{% assign filters_selected_tags = filters_selected_tags | append: tag_search | append: ',' %}
{% endif %}
{% endfor %}
{% assign filters_selected_tags = filters_selected_tags | split: ',' %}
<div class="accordian-group" data-selected-count="{{ filters_selected_tags.size }}">
<div class="accordian-heading">
<a class="collapsed" href="#">{{ settings.collection_sidebar_color_title }}</a>
</div>
<div class="accordian-body">
{% if filters_selected_tags.size > 0 %}
{% assign current_tags_modifier = '' %}
{% for t in current_tags %}
{% unless filters_selected_tags contains t %}
{% assign h = t | handle %}
{% assign current_tags_modifier = current_tags_modifier | append: h | append: ',' %}
{% endunless %}
{% endfor %}
{% assign current_tags_modifier = current_tags_modifier | split: ',' | join: '+' %}
{% assign clear_selected_url = collection.url | append: '/' | append: current_tags_modifier %}
<div class="clear-selected">
<a href="{{ clear_selected_url }}">
<i class="fa fa-times-circle" aria-hidden="true"></i> Clear {{ settings.collection_sidebar_color_title }}
</a>
</div>
{% endif %}
<ul class="multi-select color-swatches">
{% for color_tag in color_tags %}
{% assign color_swatch_src = color_tag | handle | prepend: 'swatch-' | append: '_icon.png' %}
{% capture color_swatch %}
<div class="swatch-border">
<img src="{{ color_swatch_src | file_url }}" alt="{{ color_tag | escape }}" />
</div>
{% endcapture %}
{% assign tag_name = color_tag %}
{% assign tag_search = tag_name | replace: '-', ' ' %}
{% capture link_html %}
{% if current_tags contains tag_search %}
{{ tag_name | link_to_remove_tag: tag_search }}
{% else %}
{{ tag_name | link_to_add_tag: tag_search }}
{% endif %}
{% endcapture %}
{% assign link_href = '' %}
{% assign link_html = link_html | escape %}
{% if link_html contains 'href="' %}
{% assign link_html = link_html | split: 'href="' %}
{% assign link_html = link_html[1] | split: '"' %}
{% assign link_href = link_html[0] %}
{% endif %}
{% if collection.tags contains tag_name %}
<li>
{% if current_tags contains tag_search %}
<a class="active" title="{{ tag_name }}" href="{{ link_href }}">{{ color_swatch }}</a>
{% else %}
<a title="{{ tag_name }}" href="{{ link_href }}">{{ color_swatch }}</a>
{% endif %}
</li>
{% endif %}
{% endfor %}
</ul>
</div>
</div>
{% comment %} *** FILTER BY PRICE *** {% endcomment %}
{% assign price_tags = settings.collection_sidebar_price_tags | strip_newlines | replace: ' ,', ',' | replace: ', ', ',' | split: ',' %}
{% assign filters_selected_tags = '' %}
{% for price_tag in price_tags %}
{% assign tag_search = price_tag | replace: '-', ' ' %}
{% if current_tags contains price_tag %}
{% assign filters_selected_tags = filters_selected_tags | append: price_tag | append: ',' %}
{% endif %}
{% endfor %}
{% assign filters_selected_tags = filters_selected_tags | split: ',' %}
<div class="accordian-group" data-selected-count="{{ filters_selected_tags.size }}">
<div class="accordian-heading">
<a class="collapsed" href="#">{{ settings.collection_sidebar_price_title }}</a>
</div>
<div class="accordian-body">
{% if filters_selected_tags.size > 0 %}
{% assign current_tags_modifier = '' %}
{% for t in current_tags %}
{% unless filters_selected_tags contains t %}
{% assign h = t | handle %}
{% assign current_tags_modifier = current_tags_modifier | append: h | append: ',' %}
{% endunless %}
{% endfor %}
{% assign current_tags_modifier = current_tags_modifier | split: ',' | join: '+' %}
{% assign clear_selected_url = collection.url | append: '/' | append: current_tags_modifier %}
<div class="clear-selected">
<a href="{{ clear_selected_url }}">
<i class="fa fa-times-circle" aria-hidden="true"></i> Clear {{ settings.collection_sidebar_price_title }}
</a>
</div>
{% endif %}
<ul class="multi-select list">
{% for price_tag in price_tags %}
{% assign tag_name = price_tag %}
{% assign tag_search = tag_name | replace: '-', ' ' %}
{% capture link_html %}
{% if current_tags contains tag_name %}
{{ tag_name | link_to_remove_tag: tag_name }}
{% else %}
{{ tag_name | link_to_add_tag: tag_name }}
{% endif %}
{% endcapture %}
{% assign link_href = '' %}
{% assign link_html = link_html | escape %}
{% if link_html contains 'href="' %}
{% assign link_html = link_html | split: 'href="' %}
{% assign link_html = link_html[1] | split: '"' %}
{% assign link_href = link_html[0] %}
{% endif %}
{% if collection.tags contains tag_name %}
<li>
{% if current_tags contains tag_name %}
<a class="active" title="{{ tag_name }}" href="{{ link_href }}">{{ tag_name }}</a>
{% else %}
<a title="{{ tag_name }}" href="{{ link_href }}">{{ tag_name }}</a>
{% endif %}
</li>
{% endif %}
{% endfor %}
</ul>
</div>
</div>
{% comment %} *** SORT BY *** {% endcomment %}
<div class="sidebar-sort">
<div class="accordian-group" data-selected-count="0">
<div class="accordian-heading">
<a class="collapsed" href="#">Sort By</a>
</div>
<div class="accordian-body">
{% include 'collection-toolbar' %}
</div>
</div>
</div>
</div>
{ % endif %}
If can edit the CSS then set .accordion-body to display: block; instead of display: none;
.accordion-body {
display: block;
}
Make this style as specific as needed if there are other .accordion-body throughout your site.
You should add the visible css class to the accordion-body.
Change the following:
<div class="accordion-body">
To:
<div class="accordion-body visible">

Flask SQLAlchemy relationship makes request very slow

I am using Flask SQLAlchemy for my project and I realized my customers page is very slow because I am trying to get destination for each customers. My structure looks like this.
class Users(db.Model):
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True)
first_name = db.Column(db.String(200), nullable=False)
last_name = db.Column(db.String(30), nullable=False)
created_date = db.Column(db.DateTime,nullable=False,default=datetime.datetime.now())
email = db.Column(db.Unicode(50), nullable=False)
account = db.Column(db.Unicode(10), nullable=False)
number = db.Column(db.String(30), nullable=False)
user_type = db.Column(db.String(10), nullable=False, default='ADMIN')
created_by = db.Column(db.Unicode(10), nullable=False, default='SYSTEM')
destinations = db.relationship('Destinations', backref="customer",lazy="dynamic")
class Destinations(db.Model):
__tablename__ = 'destinations'
import datetime
id = db.Column(db.Integer, primary_key = True)
did = db.Column(db.Text, nullable=False)
gateway = db.Column(db.Text, nullable=False)
channel = db.Column(db.Text, nullable=False)
own = db.Column(db.Text, nullable=False)
number = db.Column(db.Unicode(50), nullable=True)
user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
created_by = db.Column(db.Integer,nullable=False)
created_date = db.Column(db.DateTime, default=datetime.datetime.now())
expire_date = db.Column(db.DateTime, nullable=False)
record = db.Column(db.Integer, nullable=False)
auth_did = db.Column(db.Integer, nullable=False)
auth_gw = db.Column(db.Integer, nullable=False)
In my all customers page, I list all customers which the request if fast but when I try to load all destinations for each customer, the request takes a lot of time for it to load.
{% for customer in customers %}
<tr>
<td>{{customer.first_name}}</td>
<td>{{customer.number}}</td>
<td>
{% for destination in customer.destinations %}
{{destination.number}}<br />
{% endfor %}
</td>
<td>
{% for destination in customer.destinations %}
{{destination.did}}<br />
{% endfor %}
</td>
<td>
{% for destination in customer.destinations %}
{{destination.own}}<br />
{% endfor %}
</td>
<td>
{% for destination in customer.destinations %}
{{destination.created_date|humandatetime|safe}}<br />
{% endfor %}
</td>
<td>
{% for destination in customer.destinations %}
{% if destination.expire_date %}{{destination.expire_date|humandatetime|safe}}{% endif %}<br />
{% endfor %}
</td>
<td>
{% for destination in customer.destinations %}
{{destination.gateway or ''}}<br />
{% endfor %}
</td>
<td>
{% for destination in customer.destinations %}
{{destination.channel or ''}}<br />
{% endfor %}
</td>
<td>
{% for destination in customer.destinations %}
del<br />
{% endfor %}
</td>
<td><input type="hidden" value="{{customer.first_name}} {{customer.last_name}}"></td>
<td><a id="{{customer.id}}" class="user-delete-icon">delete</a></td>
</tr>
{% endfor %}
Also the function that get all my customers is this
customers = db.session.query(Users).filter_by(user_type='CUST').all()
I think the problem is the relationship type lazy but I can't get to fix it