We have a common header/footer template as parent template which we will reuse for 100 of sub templates. Extends directive is not supporting this...
When i go over the Rythm documentation, i found a way to achieve this by include/invoke directives but the primary purpose of include/invoke directive is to invoke common function. Extends directive is supporting in a reverse way by putting main template content with a render directive as a parent and header/footer template as a subtemplate but the realtime usecase is totally different
Is that my understanding right? Is there a way to solve my problem?
Edited:
I have coded like below to achieve it:
footer.html
#def header1() {
<h3>This is footer1 section</h3>
}
#def header2() {
<h3>This is footer2 section</h3>
}
template1.html
#include("footer.html")
#args String who
<html>
<head>
<title>Hello world from Rythm</title>
</head>
<body>
<h1>Hello #who</h1>
#if(footer.equals("footer1){
#header1();
} else {
#header2();
}
</body>
</html>
What i have done is with the help of include/invoke method invocation i have got the result but when i use extends it doesn't work. If it is possible can u solve my case using extends?
To use #extends to achieve the same effect, you should have:
layout.html
<html>
<head>
<title>Hello world from Rythm</title>
</head>
<body>
#render()
</body>
</html>
header1.html
<h3>This is footer1 section</h3>
header2.html
<h3>This is footer2 section</h3>
template.html
#extends(layout)
#args String who, String footer
<h1>Hello #who</h1>
#if(footer.equals("footer1")){
#header1();
} else {
#header2();
}
Related
is there a library on Java to help me to achieve custom tags replacement in html
like for example here is a simple template :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>
<p>$welcome_title</p>
<p>$email_body</p>
<p>$footer_text</p>
</div>
</body>
</html>
Can i replace this custom tags ($welcome_title,$email_body,$footer_text) with values from java ?
The idea is to have template with tags which can be replaced at runtime with values from java objects :)
Also maybe (if there is a library) to generate straight away from html an PDF doc
Thanks :)
In Java world you can use https://www.thymeleaf.org/ or https://freemarker.apache.org/
I try implementing a base template for CSS style for all my templates.
I read documentation and found info about {% super %} use, but I don't understand how to use it.
Do you have an experience of use it?
If all you want to do is reuse some common template code, you have a number of options.
{% super %} is really just for override layers, which you would only use if you had finished the layout for an entire app and wanted to maintain another version with slightly different content or layout.
You could have all templates include a header that pulls in a common css file (or keep it super-simple and define a few css classes here, using <style>...</style> tags instead of the <link rel>).
header.chtml
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="{$base_url}/css/common.css" />
</head>
about.chtml
{.include header}
...
Or you could create a template to use as a "shell" macro and exec it from other pages.
shell.chtml
<!DOCTYPE html>
<html>
<head>
<title>{$page_title}</title>
<link rel="stylesheet" href="{$base_url}/css/common.css" />
</head>
<body>
{$body}
</body>
</html>
about.chtml
{% exec shell %}
{$page_title=About Us}
{$body=}
<div>
...
</div>
{=}
{% endexec %}
I have been using Sitemesh 3 for my project and so far it's been working great. Recently I came across a situation where I am stuck.
My final view has to be composed of 2 html files, both have their own and tags.
File1:
<html>
<head>Head1</head>
<body>body1</body>
</html>
File2:
<html>
<head>Head2</head>
<body>body2</body>
</html>
I am composing a view using freemarker include tag. So, the composed HTML looks like:
<html>
<head>Head1</head>
<body>body1</body>
</html>
<html>
<head>Head2</head>
<body>body2</body>
</html>
Following is my decorator:
<html>
<head>
<sitemesh:write property='head'/>
</head>
<body>
<div class="container">
<sitemesh:write property='body'/>
</div>
</body>
</html>
But once decorated, the final output I am getting is:
<html>
<head>
<head>Head1</head>
</head>
<body>
<div class="container">
<body>body1</body>
</div>
</body>
</html>
But the expected output is
<html>
<head>
<head>
Head1
Head2
</head>
</head>
<body>
<div class="container">
body1
body2
</div>
</body>
</html>
I came across a similar question, but that solution won't work for me because I don't want to create multiple decorators.
I just want to know if it's possible in Sitemesh 3. If yes, then how.
Thanks.
If you don't mind extending Sitemesh 3 then this is fairly easy to do by adding support for server side includes in your decorator template. I do exactly this in another library (UtterlyIdle).
I'm using StringTemplate as my decorator language but this should work in Freemarker or any other templating tool. I add in a PageMap and then in my decorator template call
$include("someUrl").body$
This does a include and then parses the output with the Sitemesh 3 engine. This allows you to have as many includes as you like.
Hope that makes sense
I'm planning my website structure as following:
header.scala.html
XXX
footer.scala.html
now, instead of "xxx" there should be a specific page (i.e. "UsersView.scala.html").
what I need is to include (like with well-known languages) the source of the footer and the
header into the the middle page's code.
so my questions are:
How do you include a page in another with scala templating?
Do you think it's a good paradigm for Play! framework based website?
Just call another template like a method. If you want to include footer.scala.html:
#footer()
A common pattern is to create a template that contains the boilerplate, and takes a parameter of type HTML. Let's say:
main.scala.html
#(content: HTML)
#header
// boilerplate
#content
// more boilerplate
#footer
In fact, you don't really need to separate out header and footer with this approach.
Your UsersView.scala.html then looks like this:
#main {
// all your users page html here.
}
You're wrapping the UsersView with main by passing it in as a parameter.
You can see examples of this in the samples
My usual main template is a little more involved and looks roughly like this:
#(title: String)(headInsert: Html = Html.empty)(content: Html)(implicit user: Option[User] = None)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>#title</title>
// bootstrap stuff here
#headInsert
</head>
<body>
#menu(user)
<div id="mainContainer" class="container">
#content
</div>
</body>
</html>
This way a template can pass in a head insert and title, and make a user available, as well as content of course.
Play provide a very convenient way to help implement that!
Layout part from official docs:
First we have a base.html (that's we call in django -_-)
// views/main.scala.html
#(title: String)(content: Html)
<!DOCTYPE html>
<html>
<head>
<title>#title</title>
</head>
<body>
<section class="content">#content</section>
</body>
</html>
How to use the base.html?
#main(title = "Home") {
<h1>Home page</h1>
}
More information here
I want to create a master template that every other view page will inherit.
So the master template will have:
HEADER
--CONTENT--
FOOTER
the header will optionally show (if the user is logged in), the username and other user object properties.
the --CONTENT-- is a placeholder that other 'inheriting' view pages will inject their content into.
So my questions are, is this possible with freemarker? If so, any guidance?
How would I pass the user object to the header from my controller actions? ideally the object would be passed in somewhere OTHER than each and every view page (to avoid having to maintain this code on each and every view page).
Yes, it's possible. In our applications things like the user object exist in session scope, but this could be any scope freemarker has access to:
<#if Session.the_user?? && Session.the_user.loggedIn>
<#-- header code -->
</#if>
You can omit the Session. and Freemarker will search the various scopes for the given variable name.
To inject the content, include this at the point in the master template where you'd like the view page to put its content:
<#nested>
The view pages then declare their use of the master template as follows:
<#import "/WEB-INF/ftl/path/to/template/master.ftl" as com>
<#com.template>
View page content
</#com.template>
I made Freemarker template inheritance - https://github.com/kwon37xi/freemarker-template-inheritance
I think it's what you want. It is tested on freemarker 2.3.19.
I implemented something like this:
base.ftl
<#macro page_head>
<title>Page title!</title>
</#macro>
<#macro page_body></#macro>
<#macro display_page>
<!DOCTYPE html>
<html lang="en">
<head>
<#page_head/>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<#page_body/>
</body>
</html>
</#macro>
then index.ftl will inherit the boilerplate templates as:
<#include "base.ftl">
<#macro page_head>
<title>Welcome studs!</title>
</#macro>
<#macro page_body>
<h1> Welcome user</h1>
</#macro>
<#display_page/>
this site was helpful for the above code reference
https://nickfun.github.io/posts/2014/freemarker-template-inheritance.html
In newer Freemarker versions, the <#nested> element is extremely useful:
base.ftl:
<#macro layout>
<html>
<body>
<p>OptaPlanner AI</p>
<#nested>
</body>
</html>
</#macro>
baseWithDownloadButton.ftl:
<#import "base.ftl" as base>
<#base.layout>
${content.body}<#-- Only applicable for jbake -->
<p>Download button</p>
</#base.layout>