How to define a html subtemplate inside a PlayFramework view? - templates

From a master html template I'm calling #{doLayout} which renders my view html. I'd like to call a custom html template as well such as #{happyHeader} which I'd like to define inside my view html file. Something like this:
<html>
<body>
#{happyHeader}
<hr/>
#{doLayout}
</body>
</html>
And in my index.html have something like this:
<p>My happy doLayout main content here</p>
#{define happyHeader}
<h1>Nice header</h1>
#{/}
I've looked around StackOverflow and couldn't find a similar question, and neither do the custom template solutions in the Play Framework docs seem to cover this.

You do this with #{set} and #{get}.
You set the value in your index.html like this:
#{set 'happyHeader'}
<h1>Nice header</h1>
#{/set}
And you get it in your main.html like this:
#{get 'happyHeader' /}

Related

Mako inhereting from multiple files

I have a pyramid application with multiple views each depending on a single mako template. The views are quite complicated and bug free, so I don't want to split or merge views, and by extension, the corresponding templates.
However, I would like a single view to represent all the others. Merging all the pyramid views and templates is practically not an option.
For example, I have a login view & template and a signup view & template. Now I want my root page to contain both of them. Both login and signup inherit from base.mak, which contains common scripts and style sheet imports. The following is a pictorial representation of the mako import structure I want.
base.mak
/ \
login.mak signup.mak
\ /
root.mak
Alternatively, I tried chaining them as such:
base -> login -> signup -> root
However, I think that the views no longer talk to their respective templates.
My problem comes in when I do the 3rd chain (login.mak -> signup). I'll post analogous and extract code below, since my full code is a bit long (If more code is needed, feel free to shout).
base.mak:
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>
${next.title()}
</title>
#Imports
${next.head()}
</head>
<body>
<div id = "content">
${next.body()}
</div>
</body>
</html>
login.mak:
<%inherit file="base.mak"/>
<%def name="title()">
${next.title()}
</%def>
<%def name="head()">
${next.head()}
</%def>
<div id="login">
<div id="message">
${sMessage}
</div>
<div id="form">
<form action="${url}" method="post"> <--- url returned in views.py
...
</div>
${next.body()}
signup.mak:
<%inherit file="login.mak"/>
<%def name="title()">
</%def>
<%def name="head()">
</%def>
<div id="box">
...
</div>
Now my problem here is that my url returned from my views is undefined when I try to inherit as in above.
Then of course if I get this working, adding base.mak to to inherit from signup should be trivial.
I assume that there is a simple fix for this, but I can't find an example/explanation on how to do this in pyramid, where the templates actually do stuff.
Alternatively, Is there another way to bring together multiple pyramid views and templates into a single view?
Ok, I figured it out. One has to use mako's <%include/>, and then there is no complicated inheritance structure. So, now my files look like this:
root.mak
<%inherit file="base.mak"/>
<%def name="title()">
Welcome
</%def>
<%def name="head()">
</%def>
<%include file="login.mak"/>
<%include file="signup.mak"/>
login.mak:
<%inherit file="base.mak"/>
<%def name="title()">
</%def>
<%def name="head()">
<link rel="stylesheet" type="text/css" href="${request.static_url(...
</%def>
<div id="login">
<div id=".....
</div>
and the same structure with signup.mak. base.mak still looks the same as in the question above.
Now, if you're using pyramid (I assume another framework will work the same), and you have views that receive and pass information from forms for example, then turn them into normal functions (without #view_config(renderer='path/file.mak') and place their functionality into the parent view function, in my case root. In other words:
#view_config(renderer='pyramidapp:templates/root.mak',
context=Root,
name="")
#forbidden_view_config(renderer='pyramidapp:templates/root.mak')
def root(self):
xLoginRet = login(self)
xSignupRet = signup(self)
#logic and functionality for both, return stuff to go to base.mak

How to provide canonical URL with Django HttpResponseRedirect?

This question is very similar to one I just asked href: Can I get Google search results to use/display the final redirect url?, but now the question is specific to Django.
My site has webpage urls that use the following format:
www.mysite.com/id/pretty_title
The front page links to these pages, but the href actually contains some parameters:
www.mysite.com/id/?some_ugly_parameters_to_let_me_know_what_search_it_is_from
This then redirects to
www.mysite.com/id/pretty_title
which shows the page.
My issue is that Google's search results show the link to the page as the ugly url instead of the pretty redirected one.
What I have learned is that I need to provide a canonical link. But how can I do this when the ugly url page never really exists, at least not as one that I have written?
What happens server side is that the view of the ugly url does a redirect:
return HttpResponseRedirect(pretty_url)
I think this is the correct built template tag that you're looking for.
{{ request.build_absolute_uri }}
You can just put it as part of the HTML returned from the Django template, in the <head> section.
Do you have a base.html in your Django? You can setup a {% block %} as a placeholder for the canonical URL and then set that value in each individual page that {% extends base.html %}
base.html
<html>
<head>
<link rel="canonical" href="{% block canonical_url %}{% endblock %}">
</head>
...
A lot of these proposed solutions have issues if (1) you want your www subdomain to be the canonical one and (2) there are URL params in the request path.
I would actually propose to hard code it in the base template and append request.path.
<link rel="canonical" href="https://www.example.com{{ request.path }}">
If you do end up wanting to use build_absolute_uri, I would do it as follows in your view (or you could create a template function):
canonical_url = request.build_absolute_uri(request.path)
Calling build_absolute_uri() without an argument will call request.get_full_path() and append that to your domain. If a user finds your site via https://www.example.com/?param=123, your canonical URL will include that param.

Possible ways of reusage of views in Angular

Lets say I have html view like <div ng-controler="contr">....</div> and a js controler. Supposed that i want to use this view on bottom left and right top of my main page, in the center of one of the sub pages and so on... What are my best options of reusage? I saw that i can inject the whole html into a string and call "compile" like this but this does not seem "elegant"
Put it in a spearate html file, or add to the template cache, and include it with the ng-include directive. I'll automatically create a new scope.
<ng-include src="'template.html'"></ng-include>
<ng-include src="'template.html'"></ng-include>
<script type="text/ng-template" id="template.html">
<div ng-controler="contr">....</div>
</script>

Is it possible to use django's custom template tags to insert code in other blocks in the template?

I'm writing a custom template tag that wraps an HTML element with some code to make it editable. This is backed up by some CSS, and JS that takes care of sending the data to the server to save it.
This component requires the inclusion of
<script type="text/javascript" src="../myscript.js"></script>
at the bottom of the page and
<link rel="stylesheet" type="text/css" href="../mystyle.css">
at the top.
I already have two "js" and "css" template blocks in the page template.
My question - is there a way for for the custom template tag to include these scripts once in the relevant page blocks, if my tag is present?
IE I put in:
{ % mytag %} <div>editable element</div> { % endmytag %}
and the "js" and "css" template blocks gets populated with the relevant script\link tags?
(I don't want to preinclude those in every page, as only some of my pages will use this tag)
You might try using Django-Sekizai from within the template your custom tag renders to add CSS and JS files to another block, which is what Sekizai is designed to do. I use it extensively with Django-CMS based projects, but I haven't tried your use case.

How to change a css item in a template using django admin?

I would like to know if there is some way to change a css class from a template page using django admin.
I would like to put the django tag inside of css file.
example:
body {
    background-color: {{ body.color }};
   width: {{ body.width }};
}
You could also include your CSS file using template tags. That would demand a style tag but considering the dynamic approach here it's really not much of an issue:
<html>
<head>
<style type="text/css">
{% include 'templates/mytemplate.css' %}
</style>
</head>
<body></body>
</html>
The template could then be what you described above. Then the CSS template would have access to whatever data your base template has access too.
Depending on your use case you might also do something with blocks but I'm not sure that is worth exploring at this point.
Just off the top of my head:
Create a Model to store the CSS values you want
Register the Model to show up in the Admin Screens
In your views, return these values as a dictionary
In the template, use the values as you suggested