Inherit/extend equivalent in handlebars - gulp

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?

Related

Can I use Rust / Yew / Trunk to generate just a DOM node and script for use in HTML templates?

TLDR
Total n00b with rust, yew and trunk.
I want to find out how to rust, yew and trunk to build an HTML file containing just one DOM node, not a whole HTML page.
Background
Day-to-day, I use Django, the python web framework. Its admin console uses HTML template rendering, and an example of a template might look like this:
{% extends 'django_twined/question_changeform.html' %}
{% block object-tools-items %}
{% if show_set_active %}
<li>Set active</li>
{% endif %}
{{ block.super }}
{% endblock %}
Where in this example the {% %} and {{ }} get evaluated at render time into a valid HTML structure (from other template files), and the <li> is an extra node that gets added to the DOM.
Instead of a vanilla li element, I want to build a complex DOM node using Rust/Yew/Trunk. Then I can include the resulting head and body elements file in a django template, something like:
{% extends 'django_twined/question_changeform.html' %}
{% block head %}
{{ block.super }}
<!-- Include the scripts generated by trunk build -->
{% include 'my-dom-node-head.html' %}
{% endblock %}
{% block object-tools-items %}
<!-- Include the elements generated by trunk build -->
{% include 'my-dom-node-body.html' %}
{{ block.super }}
{% endblock %}
Where I'm at
I've used the yew starter app to get myself to an app. The input index.html is:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Yew App</title>
</head>
</html>
And the main.rs file looks like:
use yew::prelude::*;
enum Msg {
AddOne,
}
struct Model {
value: i64,
}
impl Component for Model {
type Message = Msg;
type Properties = ();
fn create(_ctx: &Context<Self>) -> Self {
Self {
value: 0,
}
}
fn update(&mut self, _ctx: &Context<Self>, msg: Self::Message) -> bool {
match msg {
Msg::AddOne => {
self.value += 1;
// the value has changed so we need to
// re-render for it to appear on the page
true
}
}
}
fn view(&self, ctx: &Context<Self>) -> Html {
// This gives us a component's "`Scope`" which allows us to send messages, etc to the component.
let link = ctx.link();
html! {
<div>
<button onclick={link.callback(|_| Msg::AddOne)}>{ "+1" }</button>
<p>{ self.value }</p>
</div>
}
}
}
fn main() {
yew::start_app::<Model>();
}
After trunk build, the output index.html looks like:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Yew App</title>
<link
rel="preload"
href="/yew-app-caccf6c60742c530_bg.wasm"
as="fetch"
type="application/wasm"
crossorigin=""
/>
<link rel="modulepreload" href="/yew-app-caccf6c60742c530.js" />
</head>
<body>
<script type="module">
import init from "/yew-app-caccf6c60742c530.js";
init("/yew-app-caccf6c60742c530_bg.wasm");
</script>
</body>
</html>
Where next?
So basically I need to get the <link> and <script> elements added by trunk build and put them into my template.
What should I do next? Would you suggest I try to:
Get trunk build --filehash false to output deterministic .js and .wasm file names without the hash (caccf6c60742c530 in this case) so that I can directly write the includes into my template (I'm concerned this will cause me development problems down the road)?
Get trunk build to output separate head link and body script?
Post-process the output index.html to extract the inserted scripts?
Alter main.rs in some way to output only what I need/want?

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)

Django not working with Angularjs

When I open the file angular.html the angularjs with Chrome, the html work normally, showing the array of information in the table. However, when I use Django, the same angular.html file, angularjs does not show the array of information in the table. I do not know what can I do?
File angular.html
<html ng-app>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.28/angular.min.js"></script>
<script>
function tabela($scope){
$scope.linhas2=[["Nexus S1","Oi1"],["Nexus S2","Oi2"],["Nexus S3","Oi3"]]
}
</script>
</head>
<body>
<div ng-controller="tabela">
<table>
<tr ng-model="item2" ng-repeat="item2 in linhas2">
<td ng-repeat="item3 in item2">{{ item3 }}</td>
</tr>
</table>
</div>
</body>
</html>
File views.py
from django.shortcuts import render_to_response
def ang(request):
return render_to_response("angular.html")
File urls.py
from django.conf.urls import patterns, include, url
urlpatterns = patterns('',
url(r'^angular/','bvmfconsulta.views.ang'),
)
The Django finds angular.html but shows a blank page.
The problem is that both Django and AngularJS share the same syntax for variable substitution in templates.
The easiest option would be to tell Django not to use it's syntax in places you need to use angularjs variable substitution - in other words, use verbatim tag:
{% verbatim %}
<div ng-controller="tabela">
<table>
<tr ng-model="item2" ng-repeat="item2 in linhas2">
<td ng-repeat="item3 in item2">{{ item3 }}</td>
</tr>
</table>
</div>
{% endverbatim %}
See other options at:
Integrate AngularJS with Django
Indeed, you can use the {% verbatim %} tag. There is another way: you can change the AngularJS tags:
var app = angular.module('dashboardApp').config(function($interpolateProvider) {
$interpolateProvider.startSymbol('{$');
$interpolateProvider.endSymbol('$}');
});
Your code will transform to:
<html ng-app>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.28/angular.min.js"></script>
<script>
function tabela($scope){
$scope.linhas2=[["Nexus S1","Oi1"],["Nexus S2","Oi2"],["Nexus S3","Oi3"]]
}
</script>
</head>
<body>
<div ng-controller="tabela">
<table>
<tr ng-model="item2" ng-repeat="item2 in linhas2">
<td ng-repeat="item3 in item2">{$ item3 $}</td>
</tr>
</table>
</div>
</body>
</html>
This way you can visually distinguish between Angular and Django Template tags. Cheers!

ASP javascript write at the point of execution

I am trying to develop a simple back-end widget for asp. Since, I am new to ASP, I chose JavaScript as ASP language. I think I don't have the right tool to write to output. Response.Write() sends output directly to the start of the page. What I am missing here?
Hers is the code that I made:
<!DOCTYPE html>
<html>
<body>
<h2>Hello world</h2>
<script language=Javascript runat=server>
Response.Write("Hello JS");
</script>
</body>
</html>
which is giving the following output:
Hello JS <!DOCTYPE html>
<html>
<body>
<h2>Hello world</h2>
</body>
</html>
There is a great answer on the subject here but basically if you want this to work change the above code block as follows;
<!DOCTYPE html>
<html>
<body>
<h2>Hello world</h2>
<% Call Response.Write("Hello JS"); %>
</body>
</html>
You can also replace the above line of code with <%= "Hello JS" %> as a shortened form of Response.Write() method.
if you want to use javascript then it should be like this:
<script language=Javascript>
alert("Hello JS");
</script>
or
<script language=Javascript>
alert('<%=SomeVarfromASP%>');
</script>
Those will give you POP up boxes with your message or in your case value of your variable in it.
Basically when you put "<%=" it is pretty much like you say please write this...
If you need something to be typed/printed on the page by JavaScript you will need to use more specialized functionality such as getelementbyid or similar.
Your code would look like:
<html>
<head>
<script type="text/javascript">
function ChangeGreet()
{
var vgreet = document.getElementById("JSGreet");
vgreet.innerHTML = 'Hello JS';
}
</script>
</head>
<body onload="ChangeGreet()">
<div>Hello MS</div>
<div id="JSGreet"> </div>
</body>
</html>
JavaScript and VBScript(Classic ASP) have their own syntax. Look it up at http://www.w3schools.com/js/DEFAULT.asp. It has great tutorials for beginners in both languages.