Read a filename from json and include it by jekyll - json

Let you assume that I have this json file:
{
"components":[
{
"id" : "brandbar",
"name" : "brandbar.html",
"type":"navbar",
"description":"Bar with the brand",
"status": "draft"
},
{
"id":"topbar",
"type":"navbar",
"component":"Best brand",
"description":"Chart with Date"
}]
}
Now, I would like to have a loop on this json to retrieve the filenames.
{% for entry in site.data.component.components %}
<div class="col-md-12">
{% include {{ entry.name }} %}
</div>
{% endfor %}
The problem is that I can't use {{ entry.name }} in my include statement.
is there a way to achieve this goal ?
I don't want to loop directly in my folder... I would like to have a main file where I will fill in every important attribute about the components.

You can try to indent you json with spaces instead of tabs.
This might do the trick :
{"components":[
{
"id" : "brandbar",
"name" : "brandbar.html",
"type":"navbar",
"description":"Bar with the brand",
"status": "draft"
},
{
"id":"topbar",
"type":"navbar",
"component":"Best brand",
"description":"Chart with Date"
}
]}
Except that topbar has no name propriety, and this can cause an error.

Related

Trouble accessing json properties in Jinja2 template

I've searched around but the answers I've found aren't working for some reason.
I'm building a flask web app. I load a csv into a dataframe and display it in a table on a page (index). You can click a button to select a row and the row's details will populate below the table.
Everything works and I can print the json object returned when a row is selected, but can't print any of the properties.
I've tried row.first, row['first'], row.first[0], and other various arrangements.
What am I doing wrong / what is the proper way to interact with json objects in Jinja2?
Json from single row that is correctly returned to the template
{
"seq": {
"0": 1
},
"first": {
"0": "Justin"
},
"last": {
"0": "Powell"
},
"state": {
"0": "ND"
},
"email": {
"0": "idomapsok#bu.ne"
}
}
views.py
from flask import render_template, jsonify
from wsaflask import bp
import pandas as pd
data = pd.read_csv('wsaflask/input.csv')
#bp.route('/update-details/<int:id>', methods = ['POST'])
def update_details(id):
row_details = data.loc[data['seq'] == id]
return jsonify('', render_template('row-details.html', row = row_details.to_json()))
#bp.route('/')
def index():
return render_template('index.html', data = data)
row-details.html
<div id="detail-display">
{% if row %}
<!-- How to print row.first (name) here -->
<p>{{ row }}</p>
{% endif %}
</div>
index.html
<body>
<section class="container">
<div style="max-height: 35vh; overflow-y: scroll;">
<table class="table">
<tr>
{% for col in data.columns %}
<th>{{ col }}</th>
{% endfor %}
<th>
action
</th>
</tr>
{% for _, row in data.iterrows() %}
<tr>
{% for col in data.columns %}
<td>{{ row[col] }}</td>
{% endfor %}
<td>
<button onclick="updateDetails(row_id = {{row['seq']}})" class="btn btn-link btn-sm">Select</button>
</td>
</tr>
{% endfor %}
</table>
</div>
<!-- Div below is replaced with row-details.html via js -->
<div id="detail-display">
</div>
</section>
</body>
Javascript:
function updateDetails(row_id){
var id = row_id
$.ajax({
url:"/update-details/" + id,
type:"POST",
dataType:"json",
success: function(data){
$('#detail-display').replaceWith(data)
}
});
}
Okay I figured it out, #jspcal got me looking in the right direction and I found this post.
In short, Flask's to_json() function returns a json string rather than an actual object, though they look similar.
The view to update the data now looks like this:
import json
#bp.route('/update-details/<int:id>', methods = ['POST'])
def update_details(id):
row_df = data.loc[data['seq'] == id]
row_json = row_df.to_json(orient = 'records')
results = json.loads(row_json)
return jsonify('', render_template('row-details.html', row = results))
First I added the 'orient' parameter. This changes the structure of the resulting json string. See the docs here. It was a bit of a guessing game for me, but here's how the json looks now:
[
{
'seq': 1,
'first': 'Justin',
'last': 'Powell',
'state': 'ND',
'email': 'idomapsok#bu.ne'
}
]
Then after importing json (just import json), load the json string using json.loads(your_json_string), and pass the results to the template instead of just the string.
Now in my template, I can get the first name using row[0].first.
I'm not 100% sure what's happening so I'm sure this isn't the ideal way to handle this, but it gets the job done.

Hugo Data Templates: Where to create files and what to put in them?

I have a Hugo SSG website.
My JSON file is saved in: /data/source.json
I created a template file: /layouts/test.html that has this content:
<!-- Data is in /data/source.json -->
{{ range .Site.Data.source }}
{{ range .names }}
<!-- person_name -->
<p>{{ .identifier.person_name }}</p>
{{ end }}
{{ end }}
How do I render this .html content to the website?
The Hugo documentation here doesn't explain what I need to do after making the .html file.
It looks like you have two range operations when you need only one. You are not ranging over multiple source.json files, correct?
Assuming you have a file data/source.json like this:
{
"names": [
{
"identifier": {
"person_name": "Joe Wilson"
}
},
{
"identifier": {
"person_name": "Nancy Wilson"
}
}
]
}
Then it should be possible to render those names like this:
{{ range .Site.Data.source.names }}
<p>{{ .identifier.person_name }}</p>
{{ end }}
Add that to a layout in your themes/{theme-name}/layouts and it will render on the pages using that template.

Shopify custom text field print in front-end

I have added custom text field inside layout header using json :
{
"type": "text",
"id": "my_text",
"label": "MyText"
}
Then I have called it inside luquid file like this:
{% if settings.my_text%}
<li class="test">{{ 'layout.header.my_text' }}</li>
{% endif %}
In return I'm getting same (layout.header.my_text ) not the value which I added from customizer
So the solution is I changed : layout.header.my_text to settings.my_text .

How do I make JSON data file objects use a layout

First, I'm using GitHub Pages dependencies.
I'm trying to make use of Jekyll's data files, but I'm having problem making functional links that would use a layout to display more of the object's contents.
I can access the page via the url: http://127.0.0.1:4000/dev/ - and my for loop at ./dev/index.html shows as it should. If I click any links on that page I get a 404 message because e.g: http://127.0.0.1:4000/dev/parent/child couldn't be found.
The posts in Jekyll use Front Matter to determine which layout it should use, but I don't know how to make my links to use my custom layout when I click any of the links in ./dev/index.html.
How can I create a "link" between the urls in ./dev/index.html to display the ./_layouts/post.html?
Here's what I got so far.
./_data/dev.json:
[
{
"id": 0,
"name": "I am (g)Root",
"link": "parent",
"data": [
{
"id": 0,
"name": "Some kid",
"content": "bla bla bla",
"link": "child"
},
{
"id": 1,
"name": "A desk",
"content": "texty texty",
"link": "desk"
}
]
}
]
./dev/index.html
---
layout: page
title: 'dev'
published: true
date: 2015-10-03 18:48:58 +02:00
category: 'module'
---
{% assign data = site.data.dev.first %}
{% for post in data.data %}
<ul>
<!-- URL will look like this: /parent/child -->
<li>{{ post.name }}</li>
</ul>
{% endfor %}
./_layouts/post.html
---
layout: default
---
{{ content }}
./_config.yml
permalink: /:categories/:title
Data files are just datas that you can consume in loops. Without a generator plugins you're not able to generate pages from them.
In order to generate page from "datas" you can use collections.

Right way to use the data in Jekyll

The goal is to use the variables defined in the front-matter section in a particular page.
Here my structure of the file system:
_Components
c1.html
c2.html
Here I have defined the attributes in the front-matters.
_Includes > Components
c1.html
Here I want to use a loop to refer to a variable defined in the _Components > c1.html page.
How can I achieve this goal ?
In my _Includes > Components > c1.html I have the following code:
<body class="full">
{% assign fullcomponents = site.components %}
{% for component in fullcomponents | where:"title","c1html" %}
{% component.title %}
{% endfor %}
<div class="container-fluid" id="componentscontainer">
<div class="col-md-12">
<div class="panel panel-primary" id ="panelcomponentlarge">
<div class="panel-heading" >
Chart C3 Line
</div>
etc...
Surely I'm missing some trivial things.
SECOND ATTEMPT
I figured out that I can provide a data layer for that so, I tried to split this information into a new data file.
Here the content of components.json
{
"Components": [
"ChartC3Line":{
"component":"ChartC3Line",
"description":"This is an attempt"
},
"ChartC3Lines":{
"component":"ChartC3Lines",
"description":"This is an attempt"
}
]
}
And I'm trying to get this information with the following code:
{% assign comp = site.data.components.Components[ChartC3Line] %}
HTML:
{% highlight html linenos%}
<p> Description: {{ comp.description }} </p>
but anything is coming up.
THIRD ATTEMPT
I found a solution but I don't like it at all here my new json file
{
"ChartC3":[
{
"component":"ChartC3Line",
"description":"This is an attempt"
}],
"ChartC4":[
{
"component":"ChartC3Line",
"description":"This is an attemptSSSSSSS"
}]
}
I don't want to have an object of several arrays of one element!
Here the code to retrieve the right information:
{% assign comp = site.data.components.ChartC4[0] %}
HTML:
{% highlight html linenos%}
<p> Description: {{ comp.description }} </p>
SOLVED
Following the structure of a json file, I changed my structure in an easier way:
{
"ChartC3":
{
"component":"ChartC3Line",
"description":"This is an attempt"
},
"ChartC4":
{
"component":"ChartC3Line",
"description":"This is an attemptSSSSSSS"
}
}
Now I can easily have access to the right object.
{% assign comp = site.data.components.ChartC3 %}
HTML:
{% highlight html linenos%}
<p> Description: {{ comp.description }} </p>