List categories associated with post in Jekyll - jekyll

I'm using Jekyll as my blogging platform and it's great. Right now I have the following code that I'm trying to tweak in my index.html page so that it only displays the categories associated with each post.
For example let's say I have the following posts:
| Post Name | Category |
|--------------|---------------|
| Post1 | Travel Dining |
| Post2 | Projects |
When the post list displays I want to get something like:
Post1, 6/7/15, Category: Travel Dining
Here's what I have for code:
Filed In:
{% for category in site.categories %}
{{ category | first }}
{% endfor %}

You question is not clear but maybe this code can do the job.
<ul>
{% for p in site.posts %}
<li>
{{p.title}} -
{{ p.date | date: "%a, %b %d, %y" }}
{% unless p.categories == empty %}
-
{% for cat in p.categories %}
<h1>{{ cat }}</h1>
{% endfor %}
{% endunless %}
</li>
{% endfor %}
</ul>

Related

How do I query a complex JSON in Jinja2?

I'm parsing a complex JSON with a Jinja2 template in Ansible. The JSON has a lot of items and random arrays.
For example, how could I query the value of name & id if the date < 2001 for all motors? (this should return: Premium diesel & 4). Please note that this is an example structure and it could have random and more children in my real scenario. What I need is a query to r search for the above keys in the entire tree.
{
"cars":[
{
"Ford":[
{
"vehicle":{
"motor":[
{
"diesel":[
{
"regular":{
"name":"Regular diesel",
"specs":{
"law":[
{
"id":1,
"date":"2008"
}
],
"gas_station":[
{
"id":2,
"date":"2002"
}
]
}
},
"premium":{
"name":"Premium diesel",
"specs":{
"law":[
{
"id":3,
"date":"2005"
}
],
"gas_station":[
{
"id":4,
"date":"2000"
}
]
}
}
}
]
}
]
}
}
]
}
]
}
Q: "How could I query the value of name & id if the date < 2001?
(this should return: Premium diesel & 4)
A: Create a list of the items where the date is less than '2001'
year: 2001
vehicle_motors_year:
2001:
- brand: Ford
id: 4
name: Premium diesel
type: gas_station
- brand: Ford
id: 6
name: Natural gasoline
type: gas_station
- brand: VW
id: 12
name: Hybrid hydrogen
type: gas_station
Then select and format the items
result: "{{ vehicle_motors_year[year]|
json_query('[].[name, id]')|
map('join', ' & ') }}"
gives the expected result
result:
- Premium diesel & 4
- Natural gasoline & 6
- Hybrid hydrogen & 12
Details:
Given the list of cars for testing
cars:
- Ford:
- vehicle:
motor:
- diesel:
- premium:
name: Premium diesel
specs:
gas_station:
- date: '2000'
id: 4
law:
- date: '2005'
id: 3
regular:
name: Regular diesel
specs:
gas_station:
- date: '2002'
id: 2
law:
- date: '2008'
id: 1
- gasoline:
- natural:
name: Natural gasoline
specs:
gas_station:
- date: '2000'
id: 6
law:
- date: '2005'
id: 5
- VW:
- vehicle:
motor:
- hybrid:
- hydrogen:
name: Hybrid hydrogen
specs:
gas_station:
- date: '2000'
id: 12
law:
- date: '2005'
id: 11
Get the lists of brands and motors
brands: "{{ cars|map('first') }}"
motors: "{{ cars|json_query(query_motors) }}"
query_motors: '[].*[][].vehicle[].motor'
give
brands:
- Ford
- VW
motors:
- - diesel:
- premium:
name: Premium diesel
specs:
gas_station:
- date: '2000'
id: 4
law:
- date: '2005'
id: 3
regular:
name: Regular diesel
specs:
gas_station:
- date: '2002'
id: 2
law:
- date: '2008'
id: 1
- gasoline:
- natural:
name: Natural gasoline
specs:
gas_station:
- date: '2000'
id: 6
law:
- date: '2005'
id: 5
- - hybrid:
- hydrogen:
name: Hybrid hydrogen
specs:
gas_station:
- date: '2000'
id: 12
law:
- date: '2005'
id: 11
Create a dictionary of the brands' vehicles' motors
vehicle_motors_str: |
{% for motor in motors %}
{{ brands[loop.index0] }}:
{% for fuels in motor %}
{% for fuel,types in fuels.items() %}
{% for type in types %}
{% for k,v in type.items() %}
{{ fuel }}_{{ k }}:
{{ v }}
{% endfor %}
{% endfor %}
{% endfor %}
{% endfor %}
{% endfor %}
vehicle_motors: "{{ vehicle_motors_str|from_yaml }}"
gives
vehicle_motors:
Ford:
diesel_premium:
name: Premium diesel
specs:
gas_station:
- date: '2000'
id: 4
law:
- date: '2005'
id: 3
diesel_regular:
name: Regular diesel
specs:
gas_station:
- date: '2002'
id: 2
law:
- date: '2008'
id: 1
gasoline_natural:
name: Natural gasoline
specs:
gas_station:
- date: '2000'
id: 6
law:
- date: '2005'
id: 5
VW:
hybrid_hydrogen:
name: Hybrid hydrogen
specs:
gas_station:
- date: '2000'
id: 12
law:
- date: '2005'
id: 11
Use this dictionary to find items where the date is less than '2001'
year: 2001
vehicle_motors_year_str: |
{{ year }}:
{% for brand,fuels in vehicle_motors.items() %}
{% for fuel,types in fuels.items() %}
{% for k,v in types.specs.items() %}
{% for i in v %}
{% if i.date|int < year|int %}
- name: {{ types.name }}
id: {{ i.id }}
brand: {{ brand }}
type: {{ k }}
{% endif %}
{% endfor %}
{% endfor %}
{% endfor %}
{% endfor %}
vehicle_motors_year: "{{ vehicle_motors_year_str|from_yaml }}"
gives
vehicle_motors_year:
2001:
- brand: Ford
id: 4
name: Premium diesel
type: gas_station
- brand: Ford
id: 6
name: Natural gasoline
type: gas_station
- brand: VW
id: 12
name: Hybrid hydrogen
type: gas_station
Example of a complete playbook for testing
- hosts: localhost
vars:
cars:
- Ford:
- vehicle:
motor:
- diesel:
- premium:
name: Premium diesel
specs:
gas_station:
- date: '2000'
id: 4
law:
- date: '2005'
id: 3
regular:
name: Regular diesel
specs:
gas_station:
- date: '2002'
id: 2
law:
- date: '2008'
id: 1
- gasoline:
- natural:
name: Natural gasoline
specs:
gas_station:
- date: '2000'
id: 6
law:
- date: '2005'
id: 5
- VW:
- vehicle:
motor:
- hybrid:
- hydrogen:
name: Hybrid hydrogen
specs:
gas_station:
- date: '2000'
id: 12
law:
- date: '2005'
id: 11
brands: "{{ cars|map('first') }}"
motors: "{{ cars|json_query(query_motors) }}"
query_motors: '[].*[][].vehicle[].motor'
vehicle_motors_str: |
{% for motor in motors %}
{{ brands[loop.index0] }}:
{% for fuels in motor %}
{% for fuel,types in fuels.items() %}
{% for type in types %}
{% for k,v in type.items() %}
{{ fuel }}_{{ k }}:
{{ v }}
{% endfor %}
{% endfor %}
{% endfor %}
{% endfor %}
{% endfor %}
vehicle_motors: "{{ vehicle_motors_str|from_yaml }}"
year: 2001
vehicle_motors_year_str: |
{{ year }}:
{% for brand,fuels in vehicle_motors.items() %}
{% for fuel,types in fuels.items() %}
{% for k,v in types.specs.items() %}
{% for i in v %}
{% if i.date|int < year|int %}
- name: {{ types.name }}
id: {{ i.id }}
brand: {{ brand }}
type: {{ k }}
{% endif %}
{% endfor %}
{% endfor %}
{% endfor %}
{% endfor %}
vehicle_motors_year: "{{ vehicle_motors_year_str|from_yaml }}"
tasks:
- debug:
var: brands
- debug:
var: motors
- debug:
var: vehicle_motors
- debug:
var: vehicle_motors_year
If you get rid of the redundant lists
cars:
Ford:
vehicle:
motor:
diesel:
premium:
name: Premium diesel
specs:
gas_station:
- {date: 2000, id: 4}
law:
- {date: 2005, id: 3}
regular:
name: Regular diesel
specs:
gas_station:
- {date: 2002, id: 2}
law:
- {date: 2008, id: 1}
gasoline:
natural:
name: Natural gasoline
specs:
gas_station:
- {date: 2000, id: 6}
law:
- {date: 2005, id: 5}
VW:
vehicle:
motor:
hybrid:
hydrogen:
name: Hybrid hydrogen
specs:
gas_station:
- {date: 2000, id: 12}
law:
- {date: 2005, id: 11}
Create the dictionary brands_motors
brands_motors: "{{ dict(cars.keys()|list|
zip(cars|
json_query('*.*.*.*.*')|
flatten(levels=2)|
map('flatten'))) }}"
gives
brands_motors:
Ford:
- name: Premium diesel
specs:
gas_station:
- date: 2000
id: 4
law:
- date: 2005
id: 3
- name: Regular diesel
specs:
gas_station:
- date: 2002
id: 2
law:
- date: 2008
id: 1
- name: Natural gasoline
specs:
gas_station:
- date: 2000
id: 6
law:
- date: 2005
id: 5
VW:
- name: Hybrid hydrogen
specs:
gas_station:
- date: 2000
id: 12
law:
- date: 2005
id: 11
Create a list of the motors
motors_str: |
{% for brand,motors in brands_motors.items() %}
{% for motor in motors %}
{% for spec,types in motor.specs.items() %}
{% for type in types %}
- brand: {{ brand }}
name: {{ motor.name }}
spec: {{ spec }}
date: {{ type.date }}
id: {{ type.id }}
{% endfor %}
{% endfor %}
{% endfor %}
{% endfor %}
motors: "{{ motors_str|from_yaml }}"
gives
motors:
- {brand: Ford, date: 2000, id: 4, name: Premium diesel, spec: gas_station}
- {brand: Ford, date: 2005, id: 3, name: Premium diesel, spec: law}
- {brand: Ford, date: 2002, id: 2, name: Regular diesel, spec: gas_station}
- {brand: Ford, date: 2008, id: 1, name: Regular diesel, spec: law}
- {brand: Ford, date: 2000, id: 6, name: Natural gasoline, spec: gas_station}
- {brand: Ford, date: 2005, id: 5, name: Natural gasoline, spec: law}
- {brand: VW, date: 2000, id: 12, name: Hybrid hydrogen, spec: gas_station}
- {brand: VW, date: 2005, id: 11, name: Hybrid hydrogen, spec: law}
The selection is trivial
year: 2001
result: "{{ motors|
selectattr('date', 'lt', year)|
json_query('[].[name, id]')|
map('join', ' & ') }}"
gives the expected result
result:
- Premium diesel & 4
- Natural gasoline & 6
- Hybrid hydrogen & 12

How to display the information of a subobject using ngfor

I am developing an application with angular and I need to display some data that has the following structure:
{
"id": 33,
"arg": 7,
"date": "2022-01-31",
"User": {
"Name": "Cristian",
"Group": {
"NGroup": "Group 1"
}
},
"Sport": {
"NSport": "Sport 1"
}
},
The information should be displayed in this way
id | arg | date | Name (User) | NGroup (Group) | NSport (Sport)
For this I was trying to use keyvalue, the problem with this is that when it brings the User object, it shows me an "item" called [object Object] that corresponds to group and there is no way to hide it. This is the current code:
<tbody>
<tr *ngFor="let item of listItems">
<td><div>{{ item.id }}</div></td>
<td><div>{{ item.arg}}</div></td>
<td><div>{{ item.date }}</div></td>
<td *ngFor="let key of item.User | keyvalue "><div>{{ key.value }}</div></td>
<td *ngFor="let key of item.User | keyvalue"><div *ngFor="let key2 of key.value | keyvalue" >{{ key2.value }}</div></td>
<td *ngFor="let kv of item.Sports | keyvalue"><div>{{kv.value}}</div></td>
</tr>
</tbody>
The output of this is:
id | arg | date | [Object,Object] | Name(User) | NGroup (Group) | NSport(sport)
The question is : How could I show only some items of the object and not all the content
Thanks!!
You can filter out the items to display using something like this:
<table>
<tr *ngFor="let item of listItems">
<td><div>{{ item.id }}</div></td>
<td><div>{{ item.arg}}</div></td>
<td><div>{{ item.date }}</div></td>
<ng-container *ngFor="let key of item.User | keyvalue ">
<td *ngIf="isInteresting(key.value)">{{ key.value }}</td>
</ng-container>
<td *ngFor="let key of item.User | keyvalue"><div *ngFor="let key2 of
key.value | keyvalue" >{{ key2.value }}</div></td>
<td *ngFor="let kv of item.Sport | keyvalue"><div>{{kv.value}}</div></td>
</tr>
</table>
and in the component:
isInteresting(val): boolean { return typeof val !== 'object'; }
This may be dodging the question, but typically I try to keep component template files simple. It helps keep business logic contained inside your TS file which also enables for better testing scenarios.
Since you know the desired output id | arg | date | Name (User) | NGroup (Group) | NSport (Sport) you should use the component's TS file to create that interface for the view. A simple .map() should do the job.
this.viewItems = this.listItems.map(item=>{
const { id, arg, date, User, Sport } = item;
const name = User.Name;
const nGroup = User.Group.NGroup;
const nSport = Sport.NSport;
return { id, arg, date, name, nGroup, nSport };
});
Now you only need one *ngFor loop for rendering your data.
<tbody>
<tr *ngFor="let item of viewItems">
<td><div>{{ item.id }}</div></td>
<td><div>{{ item.arg}}</div></td>
<td><div>{{ item.date }}</div></td>
<td><div>{{ key.name }}</div></td>
<td><div>{{ key.nGroup }}</div></td>
<td><div>{{ key.nSport }}</div></td>
</tr>
</tbody>
Note: While it's already defined in your source data, I would avoid naming objects with uppercase letters (User and Sport). This naming style should be reserved for defining classes.

Display Json data in laravel

How can I get and display each element from the product json data type in laravel.
"category" => accessories
"product" => "["eyewear", "watches", "shoes"]"
Data has been saved correctly using
$casts = [
'product' => 'array'
];
When I try to display, I get the list like show down
Category :
accessories | Product : ["eyewear", "watches", "shoes"]
Is it possible to get result like
Category : accessories | Product: eyewear *****
Category : accessories | Product: watches *****
Category : accessories | Product: shoes *****
Thanks for your help
Provided the JSON has indeed been successfully converted to an array (in this case to a 1D array), you can get the value for each index like you normally would with any other array:
{{ $product[0] }}
If you want to create some sort of list out of it, you can just loop through it using foreach:
#foreach($product as $p)
{{ "Category: " . $category }}
{{ "Product: " . $p }}
#endforeach
If I understand correctly you already have some query results stored in $items, where you have stored values for category_id and product (based on your original post I assume you've already converted the JSON to an array using the $casts property inside your model, alternatively you could use PHP function json_decode()). If you want to loop through $items, it would probably look like this:
#foreach($items as $item)
#foreach($item['product'] as $product)
{{ "Category: ".$item['category_id']." | Product: ".$product }}
</br>
#endforeach
#endforeach
The code above should output something like this:
Category: 1 | Product: eyewear
Category: 1 | Product: watches
Category: 1 | Product: shoes
Category: 2 | Product: a
Category: 2 | Product: b
Category: 2 | Product: c

Django choices that change automatically based on male/female checkboxes. Categories will be displayed based on the gender choice

I have searched on the internet but did not find anything suitable. I want to have a model that will have a a set of choices of categories which will change based on whether the male or female checkbox/choice (whichever is more appropriate) was selected.
In models.py,
class MyModel(models.Model):
MALE_CATEGORIES = {
('Male Category 1', 'Male Category 1'),
('Male Category 2', 'Male Category 2'),
('Male Category 3', 'Male Category 3'),
}
FEMALE_CATEGORIES = {
('Female Category 1', 'Female Category 1'),
('Female Category 2', 'Female Category 2'),
('Female Category 3', 'Female Category 3'),
}
# Male/Female option as either choices or checkboxes depending on whichever one is more suitable
gender =
# Either MALE_CATEGORIES or FEMALE_CATEGORIES
# Depending on gender
categories = models.CharField(max_length=18, choices=)
In forms.py,
class MyModelForm(forms.ModelForm):
class Meta:
model = MyModel
fields = [
'gender',
'categories',
]
This is how I did it. It represents a basic method to make a dependent dropdown list using Django and JQuery.
In models.py, I defined all the choices as follows.
GENDER_CHOICES = [
('Male', 'Male'),
('Female', 'Female'),
]
MALE_CATEGORIES = [
('Male Category 1', 'Male Category 1'),
('Male Category 2', 'Male Category 2'),
('Male Category 3', 'Male Category 3'),
]
FEMALE_CATEGORIES = [
('Female Category 1', 'Female Category 1'),
('Female Category 2', 'Female Category 2'),
('Female Category 3', 'Female Category 3'),
]
Defined a method (get_all_choices) to append and return all the (MALE_CATEGORIES and FEMALE_CATEGORIES) choices as follows. Make a call to the method to assign all the choices to the choices variable of the category field MyModel.
def get_all_choices():
all_choices = MALE_CATEGORIES
all_choices+=FEMALE_CATEGORIES
return all_choices
class MyModel(models.Model):
name = models.CharField(max_length=50, unique=True)
gender = models.CharField(max_length=7, choices=GENDER_CHOICES)
category = models.CharField(max_length=20, choices=get_all_choices())
In forms.py,
class MyModelForm(ModelForm):
class Meta:
model = MyModel
fields = [
'name',
'gender',
'category',
]
Render the html through some view with the form as a context (in this case, mymodelform).
In my html,
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<form class="form-class" action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{% for field in mymodelform %}
<p>
{{ field.label_tag }}
{{ field }}
{% if field.help_text %}
<small style="color: black;"> {{ field.help_text }} </small>
{% endif %}
{% for error in field.errors %}
<p style="color: red;"> {{ error }} </p>
{% endfor %}
</p>
{% endfor %}
<button class="btn btn-outline-primary" type="submit">Join</button>
</form>
<script>
$(document).ready( function() {
$("#id_category").hide();
$("#id_gender").on('change', function(){
var gender = $("#id_gender").val();
if(gender == 'Male'){
$('#id_category').empty();
$("#id_category").show();
var maleCategories = ['Male Category 1', 'Male Category 2', 'Male Category 3'];
var length = maleCategories.length;
var i;
for(i=0; i < length; i++){
maleCategory = maleCategories[i];
$('#id_category').append(
`
<option value="${maleCategory}">
${maleCategory}
</option>
`
);
}
}
else if(gender == 'Female'){
$('#id_category').empty();
$("#id_category").show();
var femaleCategories = ['Female Category 1', 'Female Category 2', 'Female Category 3'];
var length = femaleCategories.length;
var i;
for(i=0; i < length; i++){
femaleCategory = femaleCategories[i];
$('#id_category').append(
`
<option value="${femaleCategory}">
${femaleCategory}
</option>
`
);
}
}
else{
$('#id_category').empty();
}
});
});
</script>

Sort Products by Published date in collection page - SHOPIFY

We want our products sorted out by Publish Date, (not by created date)
I'm sure this is possible in Shopify, I just don't get what I'm missing.
{% assign date_now_sort = 'now' | date:'%s' %}
{% assign product_sort = collection.products | sort: 'published_at' | reverse %}
{% for product in product_sort %}
{% assign date_published = product.published_at | date:'%s' %}
{% assign date_now = 'now' | date:'%s' %}
{% assign date_difference = date_now | minus: date_published %}
{% if date_difference < 5259492 %}
<div id="product-loop">
{% for product in collection.products %}
{% assign products-per-row = section.settings.products-per-row %}
<div id="product-listing-{{ product.id }}" class="product-index {% if products-per-row == 6 or products-per-row == "6" %}desktop-2{% cycle ' first', '', '', '', '', ' last' %}{% elsif products-per-row == 4 or products-per-row == "4" %}desktop-3{% cycle ' first', '', '', ' last' %}{% elsif products-per-row == 3 or products-per-row == "3" %}desktop-4{% cycle ' first', '', ' last' %}{% elsif products-per-row == 5 or products-per-row == "5" %}desktop-fifth{% cycle ' first', '', '', '', ' last' %}{% elsif products-per-row == 2 or products-per-row == "2" %}desktop-6{% cycle ' first', ' last' %}{% endif %} tablet-half mobile-half" data-alpha="{{ product.title }}" data-price="{{ product.price }}">
{% include 'product-listing' %}
</div>
{% endfor %}
</div>
{% endif %}
{% endfor %}
This is what I came up with.
{%- assign dates = '' -%}
{%- assign datesHandles = '' -%}
{%- for product in collections.all.products limit: 20 -%}
{%- assign createdAt = product.created_at | date: '%s' -%}
{%- assign dates = dates | append: createdAt | append: ',' -%}
{%- assign datesHandles = datesHandles | append: product.handle | append: '#' | append: createdAt | append: ',' -%}
{%- endfor -%}
{%- assign dates = dates | split: ',' | sort | reverse -%}
{%- assign datesHandles = datesHandles | split: ',' -%}
{%- for orderedDate in dates -%}
{%- for dateHandle in datesHandles -%}
{%- assign dateHandleArr = dateHandle | split: '#' -%}
{%- if orderedDate == dateHandleArr[1] -%}
{{ all_products[dateHandleArr[0]].title }}<br/>
{% break %}
{%- endif -%}
{%- endfor -%}
{%- endfor -%}
The issue is that you are limited by all_products which allows only 20 unique handle request.
So this code will show only the first 20 products ordered by created date, which I don't know if it will be of any use to you.