Extend base template in Smarty - templates

Is it possible to extend a base template with another template in Smarty?
I know this is possible in Django using the {% entend %} tag. Is there an equivalent (or workaround) in Smarty?
Thanks

Although this question is a bit old, I thought that maybe someone looking for this information as of august 2011 would benefit to know that this can be done now with Smarty 3.
Example With Inheritance
layout.tpl
<html>
<head>
<title>{block name=title}Default Page Title{/block}</title>
</head>
<body>
{block name=body}{/block}
</body>
</html>
mypage.tpl
{extends file="layout.tpl"}
{block name=title}My Page Title{/block}
{block name=body}My HTML Page Body goes here{/block}
output of mypage.tpl
<html>
<head>
<title>My Page Title</title>
</head>
<body>
My HTML Page Body goes here
</body>
</html>
Taken verbatim from: http://www.smarty.net/inheritance

There is no build-in template inheritance in Smarty. But you can do similar thing with {include} and {capture}.
Your page template can look like:
{capture assign="context"}
<h2>Here is my page</h2>
{... some other smarty suff here ...}
{/capture}
{assign var="title" value="Just simple title text here"}
{include file="base.tpl"}
And base.tpl can look like following:
<html>
<title>{$title}</title>
<body>
{$context}
</body>
</html>

Related

Django 3.0: How to use different Boostrap versions in same template

I have made a template (Base.html) in my django project, of Bootstrap 4 which working is fine independently.
I have also made another template (Child_Base.html) which is made with Bootstrap 3 and supposed to be injected in Base.html.
But what happening here is, when I include BS3 template in first one it is ruining many things. So, I am looking for a solution in which both co-exist and doesn't spoil other one.
Code of Base.html is supposed as follows:
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<p>
{% block bodyblock %}
Hello World!
{% include "Child_Base.html" %}
{% endblock %}
</p>
</body>
</html>
Code of Child_Base.html is supposed as follows:
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
</head>
<body>
<p>
{% block bodyblock %}
Good Morning!
{% endblock %}
</p>
</body>
</html>
In actual scenario, there is product page, displaying all the books available for user to add in cart (made in BS4) in which I want to include search box (made in BS3). But code is tangled and not so self-elaborated so I have used above examples. Thanks.
why you want this?
you either include CSS files in your templatename.html file or in a different name.css file that is linked to your template, when you include bt3 and bt4 browser DOM looks like this:
pages:
index.html
files:
bt3.min.css
bt4.min.css
and then it gets crazy cause two different CSS files with same tags are in browser DOM.
I'm not telling this is not possible cause in frontend frameworks like vue.js you can config it to use CSS locally just for one component, but Django doesn't generate files like that so you can't have two different CSS files isolated from each other for one HTML page.
on second Thought:
maybe if you make your page.html with a scheme like this:
headers and other head tags...
<body>
<section>
<style>
include the entire bootstrap 4 css here
</style>
enter your bt4 elements here
</section>
<section>
<style>
include entire bootstrap 3 css here
</style>
enter your bt3 elements here
</section>
</body>
you should put .min.css in this may cause the browser to render the page with your desired styles as always CSS files are overwritten by lower CSS's in the file.

Removing newlines from the end of base.html file makes some elements disappear from DOM

This is a strange bug. I have an html file that extends a base template called base.html. I noticed that a script tag right before the end body tag in the base template doesn't show up in the DOM in the Elements tab of the Chrome dev tools, and the tag is cut off completely along with the rest of the html file in the Sources tab. This happens in Chrome, Mozilla, and Safari, so it must be a problem on the Django side. And obviously the observable effects on the page that the script should create aren't happening either.
Here's the end of the rendered html in the Sources tab:
<section>
what is going on
</section>
<footer></footer>
<script src="/static/home/js/ba
Completely cut off. Here's the end of that base template:
{% block main %}{% endblock %}
<footer></footer>
<script src="{% static 'home/js/base.js' %}"></script>
{% block js %}{% endblock %}
</body>
</html>
Now, here's where it gets funny. The trouble is at the end of the file, so I just added some newlines to see if there's any difference in the DOM is rendered:
{% block main %}{% endblock %}
<footer></footer>
<script src="{% static 'home/js/base.js' %}"></script>
{% block js %}{% endblock %}
</body>
</html>
And the Sources tab showed a cut off later in the tag:
<section>
what is going on
</section>
<footer></footer>
<script src="/static/home/js/base.j
I won't paste it here, but I added about 35 newlines to the end of the file before I got what I wanted in the Sources. It seems that every newline cuts off the rendered html one character later.
<section>
what is going on
</section>
<footer></footer>
<script src="/static/home/js/base.js"></script>
</body>
</html>
And the effects from the script finally worked. This feels like a temporary solution to something deeper that needs to be fixed. Anybody have any clue what the hell is going on or where to look?
Edit: Here's the template (located in the work app) that extends base.html (located in the home app), called work.html:
{% extends 'home/base.html' %}
{% block css %}
<link rel="stylesheet" href="{% static 'work/css/work.css' %}">
{% endblock %}
{% block main %}
<section>
hello
</section>
{% endblock %}
And here is the view that renders it:
from django.shortcuts import render
def work(request):
return render(request, 'work/work.html', {})
Edit 2: some more unexpected results:
When I deleted the script (so that I can paste it in head as suggested in the comments), the end of the rendered html was this:
<section> what is going on </section>
And pasting right before the </head> tag resulted in:
<section> what is going on </section>
<
Same result above when I commented it out in head.
Commenting out the script when it's before the </body> results in this:
<section> what is going on </section>
<footer></footer>
<!-- <script src="/static/home/js/base.j
And replacing single quotes with double quotes resulted in the rendered html showing double quotes instead of single quotes as the only difference. :/
Then I deleted almost everything so that my code was this:
<!DOCTYPE html>
<html lang="en-US">
<head>
</head>
And that rendered:
<!DOCTYPE html>
<html lang="en-US">
<head>
<scrip
I added back some tags:
<!DOCTYPE html>
<html lang="en-US">
<head>
</head>
<body>
</body>
</html>
And the result:
<!DOCTYPE html>
<html lang="en-US">
<head>
<script src="http://127.0.0.1:357
For some reason, the script tag generated by django-livereload-server remains. This is what the full script tag looks like:
<script src="http://127.0.0.1:35729/livereload.js"></script></head>
Mystery's over everybody. The problem is that you should not pip install django-livereload-server. I don't know what it does behind the scenes but some of my html disappear based on some weird algorithm.
So, to uninstall django-livereload-server, remove 'livereload', from your INSTALLED_APPS, remove 'livereload.middleware.LiveReloadScript', from your MIDDLEWARE, hit Control-C to get out of that livereload terminal process, Control-C in the window running the runserver process to apply the changes (because livereload latches onto runserver like a leech, so you have to restart), and enjoy expected output. And pip uninstall django-livereload-server. If anybody has any suggestions for a livereload type of app that works (where the browser reloads the page when you type something new in your html/js/css), let me know. For now I guess it's back to the old manually typed Command-R.

Ember js/Handlebars

I have an Ember application running with hadlebars. I have several ember templates in my HTML page, but I ran into a slight dilemma - I can't escape an HTML code within script tag. I am looking to insert a non-working raw HTML into script tag for illustrative purposes. Will it be of help by using .hbs file method? I would prefer not to use .hbs method.
<script type="text/x-handlebars" data-template-name="name">
<html>
<head>
so on....
</head>
</html>
</script>
Thank you.
You can do this exactly the same way you would do it in normal HTML: escape the HTML entities:
<script type="text/x-handlebars" data-template-name="name">
<html>
<head>
so on....
</head>
</html>
</script>

smarty3 display not working

I post my code here first
index.php:
<?php
require('class/smarty/Smarty.class.php');
$smarty = new Smarty;
$smarty->setTemplateDir('./templates/');
$smarty->setCompileDir('./template_c/');
$smarty->setCacheDir('./cache/');
$smarty->setConfigDir('./configs/');
$smarty->assign('name','Dan Brown');
$smarty->display('tpl_1.tpl');
?>
template file, tpl_1.tpl:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>demo/title>
</head>
<body>
<h1>
hello,{$name}
</h1>
</body>
</html>
everything looks well, but the result is output blank page, smarty can't display or call the templates file, where is wrong in my code.
I really confuse this problem and waste too much times
Try this,
<?php
require('class/smarty/Smarty.class.php');
$smarty = new Smarty();
$smarty->setTemplateDir('./templates/');
$smarty->setCompileDir('./template_c/');
$smarty->setCacheDir('./cache/');
$smarty->setConfigDir('./configs/');
$smarty->assign('name','Dan Brown');
$smarty->display('tpl_1.tpl');
?>

include scala.html files in play 2.0 scala

I am trying to learn Play 2.0 with scala but I dont think i quite understand how the template system for play 2.0 works. I have used play 1.2 before and i am sort of looking for an equivalent to the #{include 'views/blah.html' /}. I essentially want to create a navbar that is rendered on all the pages.
Essentially in main.scala.html i have
#(title: String)(navbar: Html)(content: Html)
<!DOCTYPE html>
<html>
<head>
<title>#title</title>
<link rel="stylesheet" media="screen" href="#routes.Assets.at("stylesheets/main.css")">
<link rel="shortcut icon" type="image/png" href="#routes.Assets.at("images/favicon.png")">
<script src="#routes.Assets.at("javascripts/jquery-1.7.1.min.js")" type="text/javascript"></script>
</head>
<header>
This is my header
</header>
<section class="navbar">#navbar</section>
<section class="content">#content</section>
<footer>
This is my footer
</footer>
and in my index.scala.html:
#navbar = {
<h1>Index</h1>
<ul>
<li>
<a href=#routes.Application.tasks>Tasks</a>
</li>
</ul>
}
#main("Home")(navbar){
content
}
in task.scala.html:
#(tasks: List[Task], taskForm: Form[String])
#import helper._
#main("Home") {
<h1>Index</h1>
<ul>
<li>
<a href=#routes.Application.tasks>Tasks</a>
</li>
</ul>
} {
task code
}
Now to include this navbar it seems i have to repeat this in every page this way i would have to hard code this navbar into every page. Is there a way to do this without without writing the whole navbar in every page?
I have also tried creating a navbar.scala.html file that contains
<h1>Index</h1>
<ul>
<li>
<a href=#routes.Application.tasks>Tasks</a>
</li>
</ul>
and saving under views/ then importing that using #import views.navbar but then i get an error stating 'navbar is not a member of views'. I am writing this in Eclipse Java EE IDE indigo if that helps.
Dont import it but just call it:
#navbar()
To include any other views template into another views template,
you simple call it using: #views.html.[location].[location].[location]()
Where [location] is just a break down of it's path.
for example:
#views.html.users.interface()
Be sure to put the "()" ie the brackets at the end of the statement if it does not take any parameters. Without the "()" you will get an error message like this:
"BaseScalaTemplate(play.api.templates...)"
If your template has parameters, be sure to include them when you call it, like this:
#views.html.users.interface( "name" )