How can I put Jekyll content a multiple column layout? - jekyll

How can I put markup around specific sections within my markdown file? e.g. put divs around two lists and then another div around the rest of the content.
Using this as an example:
Markdown
* Eggs
* Flour
* Sugar
Text goes here
Output
<div class="section1">
<ul>
<li>Eggs</li>
<li>Flour</li>
<li>Sugar</li>
</ul>
<div class="section2">
<p>Text goes here</p>
</div>

I guess you want something like this:
First, a "regular" layout file for the pages where you don't want to show ingredients and preparation:
/_layouts/default.html :
<!DOCTYPE html>
<html>
<head>
<title>{{ page.title }}</title>
</head>
<body>
<h1>{{ page.title }}</h1>
{{ content }}
</body>
</html>
Nothing special here, just a very basic layout file.
Then, a second layout file for the pages where you actually want to show recipes:
(I'll call it "recipes", because "ingredients" and "preparation" sounds like you're building a site about cooking)
/_layouts/recipe.html :
---
layout: default
---
<div class="ingredients">
<ul>
{% for item in page.ingredients %}
<li>{{item.name}}</li>
{% endfor %}
</ul>
</div>
<div class="preparation">
{{ content }}
</div>
Now you can create pages like this, where you put the list of ingredients into the YAML front-matter and the preparation in the content:
---
layout: recipe
title: Cake recipe
ingredients:
- name: sugar
- name: milk
- name: eggs
---
Here's the "how to prepare the cake" text
This will generate the following HTML:
<!DOCTYPE html>
<html>
<head>
<title>Cake recipe</title>
</head>
<body>
<h1>Cake recipe</h1>
<div class="ingredients">
<ul>
<li>sugar</li>
<li>milk</li>
<li>eggs</li>
</ul>
</div>
<div class="preparation">
Here's the "how to prepare the cake" text
</div>
</body>
</html>
EDIT:
Concerning your question:
I'm not sure though if it will work as I need to format the ingredients list with some bolding, e.g.:100ml water and I don't think I can do this in YAML?
You could separate the ingredient and the amount in the front-matter of the page:
---
layout: recipe
title: Cake recipe
ingredients:
- name: sugar
amount: 1 pound
- name: milk
amount: 100ml
- name: eggs
amount: 3
---
Here's the "how to prepare the cake" text
And the new layout file /_layouts/recipe.html:
---
layout: default
---
<div class="ingredients">
<ul>
{% for item in page.ingredients %}
<li>{{item.amount}} <b>{{item.name}}</b></li>
{% endfor %}
</ul>
</div>
<div class="preparation">
{{ content }}
</div>
The generated HTML:
<!DOCTYPE html>
<html>
<head>
<title>Cake recipe</title>
</head>
<body>
<h1>Cake recipe</h1>
<div class="ingredients">
<ul>
<li>1 pound <b>sugar</b></li>
<li>100ml <b>milk</b></li>
<li>3 <b>eggs</b></li>
</ul>
</div>
<div class="preparation">
Here's the "how to prepare the cake" text
</div>
</body>
</html>

Related

Adding multiple images to a html file using Jinja2

I am trying to load and add multiple figures from disk to a HTML file
For adding a single image, I tried the following (ref.: Jinja2/Python insert a image(s) into html)
import jinja2
env = jinja2.Environment(
loader=jinja2.FileSystemLoader('.'),
trim_blocks=True,
lstrip_blocks=True,
)
template = env.get_template("template.html")
template_vars = {"title":"TITLE", "graph":'obj.png'}
text = template.render(template_vars)
with open("test2.html", "w") as f_out:
f_out.write(text)
The template looks like the below
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>TITLE</title>
</head>
<body>
<h2>Graph Goes Here</h2>
<img src="obj.png">
</body>
</html>
To extend this to add multiple images, I made the following modification in the template
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>{{ title }}</title>
</head>
<body>
<h2>Graph Goes Here</h2>
<dl>
{% for key, value in template_vars.items() %}
<img src="{{value}}.png">
{% endfor %}
</dl>
</body>
</html>
I would like to know how
template_vars = {"title":"TITLE", "graph":'obj.png'}
has to be modified to pass multiple figures.
You will need to update the object type used for your variable template_vars to make things simpler to iterate. Instead of a dictionary, you likely want a list of dictionaries so that you will be able to loop over each image and get multiple attributes for each one (in your case, a value for the key title and another one for the key graph). You should also refer to your variable when calling template.render so that Jinja2 knows what you are writing about (i.e., replace template.render(template_vars) with template.render(template_vars=template_vars)).
Your updated template might look like this:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>TITLE</title>
</head>
<body>
<h2>Graph Goes Here</h2>
<dl>
{% for image in template_vars %}
<dt>{{ image.title }}</dt>
<dd><img title="{{ image.title }}" src="{{ image.graph }}"></dd>
{% endfor %}
</dl>
</body>
</html>
Then, the part of your Python code that needs to be changed would look as follows:
template_vars = [
{"title": "TITLE", "graph": "obj.jpg"},
{"title": "TITLE2", "graph": "obj2.jpg"},
]
text = template.render(template_vars=template_vars)
This will result in the following HTML source output:
<html>
<head lang="en">
<meta charset="UTF-8">
<title>TITLE</title>
</head>
<body>
<h2>Graph Goes Here</h2>
<dl>
<dt>TITLE</dt>
<dd><img title="TITLE" src="obj.jpg"></dd>
<dt>TITLE2</dt>
<dd><img title="TITLE2" src="obj2.jpg"></dd>
</dl>
</body></html>

Gin gonic templates overwriting partial templates

I am using gin gonic and it's features. One if them being html template rendering.
So in spirit of DRY I wanted to create a base.html template with all common html tags etc. with a
slot for different page bodies.
In essence, this is the base.html
{{define "base"}}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
{{ template "main" . }}
</body>
</html>
{{end}}
Then I created a "child" template called home.html:
{{template "base" .}}
{{define "main"}}
<div class="container mt-5">
Hello
</div>
{{end}}
I followed this wonderful guide on this page and it worked like a charm.
The problem
But when I tried adding another page with different body in subpage.html eg:
{{template "base" .}}
{{define "main"}}
<div class="container">
<div>
<h2>This page is still in progress</h2>
</div>
</div>
{{end}}
the last template that is picked by gins LoadHTMLFiles or LoadHTMLGlob, is then displayed on every page. In this case this is subpage.html content.
How do I fix this. Is it even possible to achieve this behaviour by default?
You could do something like this:
base.html
{{ define "top" }}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
{{ end }}
{{ define "bottom" }}
</body>
</html>
{{ end }}
home.html
{{ template "top" . }}
<div class="container mt-5">
Hello
</div>
{{ template "bottom" . }}
subpage.html
{{ template "top" . }}
<div class="container">
<div>
<h2>This page is still in progress</h2>
</div>
</div>
{{ template "bottom" . }}
Then make sure you're using the file's base name:
// in the home handler use the following
c.HTML(http.StatusOK, "home.html", data)
// in the subpage handler use the following
c.HTML(http.StatusOK, "subpage.html", data)

Inherit/extend equivalent in handlebars

I am working on a static template and decided to use handlebars and gulp to generate the html part.
I have read several examples and I understand the concept of importing a partial like:
partial.hbs
<h1>Contents of the partial</h1>
index.hbs
<html>
<head></head>
<body>
{{> partial }}
</body>
</html>
which would yield:
<html>
<head></head>
<body>
<h1>Contents of the partial</h1>
</body>
</html>
What I can't seem to find is extending a base file instead of importing into it. What I mean is this:
base.hbs
<html>
<head></head>
<body>
{{ contents }}
</body>
</html>
index.hbs
{{extend base}}
{{ contents }}
<h1>Contents of the partial</h1>
{{ end contents }}
What is the proper way to do this in handlebars?

What is difference between ng-init and ng-bind?

Below is the code using ng-init:
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="" ng-init="names=['Jani','Hege','Kai']">
<p>Looping with ng-repeat:</p>
<ul>
<li ng-repeat="x in names">
{{ x }}
</li>
</ul>
</div>
</body>
</html>
Below is the code using ng-bind:
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="" ng-bind="names=['Jani','Hege','Kai']">
<p>Looping with ng-repeat:</p>
<ul>
<li ng-repeat="x in names">
{{ x }}
</li>
</ul>
</div>
</body>
</html>
Both give the same output, with different formats.
What exactly is happening here ?
Please help!
The purpose of ng-init is initialize a property in template.
The purpose of ng-bind is replace the text content of the specified HTML element with the value of a given expression.
But you should initialize the variable in controller and use {{variable}} and donĀ“t use ng-init or ng-bind for this.
ng-bind and ng-init have very different use cases.
ng-bind is for assigning inner text to element, like:
<div ng-bind="'hi'"><div>
results in:
<div>hi</div>
ng-init directive is executed once and is mainly useful for declaring variables. So in your case you shall use ng-init.

Sublime autocomplete scope is "source, text", but not working in html string

I have this autocomplete file:
{
//"scope": "text.html.django",
"scope": "source, text",
"completions":
[
{ "trigger": "variable, curly curly: {{ ... }}", "contents": "{{ $1 }}$0" }
]
}
And I'm working in this file, whose syntax is set to HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<title>My user profile</title>
</head>
<body>
<h1>My user profile</h1>
<ul>__SPOT_ONE__
<li>Username: {{ user.username }}</li>
<li>Email: {{ user.email }}</li>
<li>Profile picture: <img src=" __SPOT_TWO__ " alt=""></li>
</ul>
</body>
</html>
And this is my user-setting:
"auto_complete_selector": "text, source",
When I type "varcc" at __SPOT_ONE__, the variable, curly curly: {{ ... }} autotext pops up as expected, but at __SPOT_TWO__, it doesn't--whether I press ctrl+space or not. Why is this? I thought the source, text scope meant everywhere.
Is it possible to get this autotext to also popup in spot two?