Nodejs Handlebars Dynamic Partials use - node.js

I have a main hbs, which is the main layer of my layouts. In this hbs I want to set one partial hbs based on if a person is logged in or not. If he's logged in I want to show a userInfo partial if he's not I want to see the >navbar partial for example. The main problem is, that if I render again this main giving a value to the userInfo partial (and checkig if the userInfo #eq value) the main page is rendered twice. How can I set and switch from between these two partials properly based on some value? Thank you very much.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{{ title }}</title>
<link href="/style.css"
rel="stylesheet"
type="text/css">
</head>
<body>
{{> userInfo}}
{{> nav}}
{{{ body }}}
</body>
</html>

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{{ title }}</title>
<link href="/style.css"
rel="stylesheet"
type="text/css">
</head>
<body>
{{#if userInfo}}
{{> userInfo}}
{{else}}
{{> nav}}
{{/if}}
{{{ body }}}
</body>
</html>
Can you try this one? I think this will help you. You can also add this condition to server side to make this decision.

Related

How to make nav bar common for all pages in thymeleaf

I am using thymeleaf for my front end design ,I create a nav bar and
I want this nav bar work for all pages, my Requirement is make one nav
bar and use this nav bar in every page ,with out define another nav
bar in separate page .
I create a nav bar inside my fragments folder that situated inside
template folder
When i call my nav bar in my index page it is not working
Here is my code of index page
index.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Coursel</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" ></script>
<script type="text/javascript" src="/static/demo.js"></script>
</head>
<body>
<nav th:replace="/fragments/nav :: nav-front"></nav>
<div class="container-fluid">
here my register form codes
</div>
</body>
</html>
nav.html
<nav class="nav">
<a class="nav-link active" th:href="#{/templates/index.html}">Active</a>
<a class="nav-link active" th:href="#{/templates/index.html}">Register</a>
<a class="nav-link active" th:href="#{/templates/index.html}">Login</a>
<a class="nav-link active" th:href="#{/templates/index.html}">AboutUs</a>
</nav>
Here is my project structure
I use IntelliJ IDEA as code editor.
It is possible, look into Thymeleaf Layout Dialect.
In short:
you create some layout.html in your templates folder. In it:
<!DOCTYPE html>
<html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<!-- all common head tags - meta etc. -->
<title layout:title-pattern="$CONTENT_TITLE - $LAYOUT_TITLE">App name</title><!-- define title in your page template and it will be added too your app name, e.g. 'Home - My App' -->
</head>
<body>
<nav>
<!-- your nav here -->
</nav>
<section layout:fragment="content">
<!-- don't put anything here, it will be replaced by the page contents -->
</section>
</body>
</html>
And in you page templates:
<!DOCTYPE html>
<html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{/path/to/layout.html}">
<head>
<title>Page name</title>
</head>
<body>
<section layout:fragment="content">
<p>This will be added into your layout!</p>
</section>
</body>
</html>
In order to make it work, you will need to add it to your templateEngine() bean definition:
#Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver( thymeleafTemplateResolver() );
templateEngine.addDialect( new LayoutDialect() );
return templateEngine;
}
See mvnrepository to import this dialect using maven.

Adding CSS File to ejs tempelate using variable from server side

I am trying to add css file dynamically in ejs tempelate.
I know how to include ejs file but not getting how to add css file dynamically.
Code :-
Index.js
router.get('/', function(req, res, next) {
res.render('template', { title: 'abc',page:'index',cssa:'home'});
});
template.ejs
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="/stylesheets/style.css">
<!-- Here I want to add home.css file -->
</head>
<body>
<!-- including my ejs file -->
<%- include(page) %>
</body>
</html>
I tried :
<link rel="stylesheet" type="text/css" href="/stylesheets/\<%= cssa %>\" >
<% include %><%= cssa %><% .css %>
Goal:
to pass the server side received variable(cssa) in stylesheet source.
Don't need to concat the css path and variable, you can also do it as follows:
<link rel='stylesheet' href='/stylesheets/<%= yourVariableName %>.css' />
Method to include :
<% var css_link = '/stylesheets/' + cssa + '.css'; %>
<link rel="stylesheet" type="text/css" href="<%= css_link %>" >
Credit goes to #SpiRT
Alternatively :
<link rel="stylesheet" type="text/css" href="/stylesheets/<%=cssa%>.css">
I've found it most convenient to inject custom css scripts through an array which can then be processed in the ejs template.
This method would allow you to render any amount of CSS files that are additionally required (example, you have a site that uses 1 standard css across all pages but have 1 or 2 page specific ones which can then be included in the model passed through the ejs renderer to that specific page/route).
In the example it's a given that the css files are in the same folder, however that can be changed to each one's liking:
router side:
router.get( ... {
model = {};
model.Stylesheets = [];
model.Stylesheets.push("stylefile");
res.render("view",{model:model});
});
with the custom stylesheets being pushed though to the view, then the ejs files can be something like:
<%
var customStylesheets = "";
model.Stylesheets.forEach(function(style){
customStylesheets+='<link type="text/css" rel="stylesheet" href="css/'+style+'.css">';
})
%>
<!DOCTYPE html>
<html>
<head>
<title><%= model.title %></title>
<link type="text/css" rel="stylesheet" href="css/standard.css">
<%- customStylesheets %>
...
</head>

html-webpack-plugin output html , interior body empty

use html-webpack-plugin output html page , but in output page lost body inner html element , like <div id="app"></div> , here is my input output and webpack.config file :
input
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
<link rel="icon" href="static/pic/logo.png" type="image/x-icon">
<link rel="stylesheet" href="static/weui/weui.min.css">
<link rel="stylesheet" href="static/index.css">
<title>APP</title>
</head>
<body>
<div id="app"></div>
<script src="./dist/vendor.js"></script>
<script src="./dist/app.js"></script>
</body>
</html>
output
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>SPA</title>
<link href="/dist/style.df241090c6a9e0a6bf26.css" rel="stylesheet"></head>
<body>
<script type="text/javascript" src="/dist/vendor.df241090c6a9e0a6bf26.js"></script><script type="text/javascript" src="/dist/app.df241090c6a9e0a6bf26.js"></script></body>
</html>
part webpack.config.js
const htmlWebpackPlugin = require('html-webpack-plugin');
plugins: [
new htmlWebpackPlugin({
title:'SPA',
filename: 'assets/index.html'
})
],
The filename option is simply used as the output file, it won't read and modify the existing file, if one exists. Because if it did that, every new build would just append to it, unless you cleaned it manually. To use your input as the base, you need to use it as a template.
new htmlWebpackPlugin({
title:'SPA',
filename: 'assets/index.html',
template: 'path/to/template/index.html'
})
The template should not be the same as the output filename, otherwise it gets overwritten. See also Writing Your Own Templates. The template can be a regular HTML file and it will inject the necessary assets.

Thymeleaf layout dialect and th:replace in head causes title to be blank

I'm following this tutorial: http://www.thymeleaf.org/doc/layouts.html (got to Thymeleaf Layout Dialect section).
In there you can find an example:
<!DOCTYPE html>
<html>
<head>
<!--/* Each token will be replaced by their respective titles in the resulting page. */-->
<title layout:title-pattern="$DECORATOR_TITLE - $CONTENT_TITLE">Task List</title>
...
</head>
<body>
<!--/* Standard layout can be mixed with Layout Dialect */-->
<div th:replace="fragments/header :: header">
...
</div>
<div class="container">
<div layout:fragment="content">
...
</div>
<div th:replace="fragments/footer :: footer">© 2014 The Static Templates</div>
</div>
</body>
</html>
Footer and header are replaced by th:replace tag in above example, while <head> has <title> tag in layout file.
Basically, I want to replace whole <head> tag with th:replace.
Therefore, I have:
My layout file:
<!DOCTYPE html>
<html>
<head th:replace="/html/components/head :: head">
</head>
<body>
<div layout:fragment="content">
</div>
...
<div th:replace="/html/components/footer :: footer" />
</body>
<html>
My content file:
<!DOCTYPE html>
<html layout:decorator="/html/layouts/layout">
<head>
<title>My content title</title>
</head>
<body>
<div layout:fragment="content">
...
</div>
</body>
</html>
And finally my /html/components/head.htm file:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head th:fragment="head">
<meta charset="utf-8" />
<title layout:title-pattern="$CONTENT_TITLE">Layout Title should be replaced by Content Title!</title>
...
</head>
<body>
</body>
</html>
Content is alright. Footer and head are included (replaced) from files as expected but page title is blank!
I get:
<!DOCTYPE html>
<head>
<meta charset="utf-8" />
<title></title>
...
What's wrong?
Finally, I've found a way to achieve what I wanted.
In layout file <title> tag must stay. All other tags I grouped with <object> tag and annotated it as follows:
<head>
<title layout:title-pattern="$CONTENT_TITLE">Layout Title will be replaced by Page Title!</title>
<object th:include="/html/components/head :: head" th:remove="tag" />
</head>
In my html/components/head.htm file I had to remove <title> tag so it won't be duplicated after include.
<head th:fragment="head">
<meta charset="utf-8" />
<!-- NO TITLE TAG HERE -->
...
</head>
This way head fragment is included in <object> tag and thanks to th:remove="tag" <object> tag gets removed and my final HTML output is:
<head>
<title>My content title</title>
<meta charset="utf-8" />
<!-- NO TITLE TAG HERE -->
...
</head>
Obviously, I removed NO TITLE TAG HERE message too, once I got it working.
I think I found a slightly less verbose way to for using th:replace and th:fragment together, e.g. to include common <head> metadata and static resource includes in your pages.
Put the th:remove="tag" in the fragment definition, so you don't have to repeat the th:remove="tag" everytime including it.
fragment_head.html
<thymeleaf xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
th:fragment="head" th:remove="tag">
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" th:href="#{/css/vendor/bootstrap.min.css}"/>
</thymeleaf>
mypage.html
<head>
<thymeleaf th:replace="fragment_head :: head" />
</head>
You can replace whole head tag.
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head lang="pl" th:replace="fragments/head :: head">
</head>
<body>
...
</body>
</html>
resources/templates/fragments/head.html:
<head lang="pl">
<title>Title</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<link href="http://cdn.jsdelivr.net/webjars/bootstrap/3.3.5/css/bootstrap.min.css"
th:href="#{/webjars/bootstrap/3.3.5/css/bootstrap.min.css}"
rel="stylesheet" media="screen" />
<script src="http://cdn.jsdelivr.net/webjars/jquery/2.1.4/jquery.min.js"
th:src="#{/webjars/jquery/2.1.4/jquery.min.js}"></script>
<link href="../static/css/mycss.css"
th:href="#{css/mycss.css}" rel="stylesheet" media="screen"/>
</head>

Text following the center of a page

i'm trying to make a simple header (HTML) with some text ( one word ). I would like the text to follow the center of the page, i mean that when i shrink the page width with the mouse i want the text change its position to the new center of the page.
Please help, thanks
Below is the sample code. The important thing is the CSS "text-align". Does this help?
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
</head>
<body>
<style type="text/css">
p.centerPara{text-align: center}
</style>
<p class="centerPara">Hello world!</p>
</body>
</html>
Try this sample code. It might be a little simpler. :)
<!DOCTYPE HTML>
<html>
<head>
<title>Title goes here</title>
<style type="text/css">
#banner{
width:100%
/*Additional banner code */
}
#banner h1{
text-align:center;
}
</style>
</head>
<body>
<div id="banner">
<h1>OneWord</h1>
</div>
</body>
</html>
Basically, the same thing. Text-align:center is the most important thing.

Resources