Extending template blocks in Phoenix framework for custom css/js in the templates [duplicate] - templates

I am looking to add additional layout parameters like the #inner for the layout. For example #title for the <title>#title</title> and an area for onload javascript for individual pages.
window.onload = function () {
#onload_js
}
These are set in the layout, so I am not sure the best way to handle these in Phoenix. Thanks :D.

For the page title, you can simply pass a value through from your controller:
def edit(conn, params) do
render(conn, "edit.html", page_title: "Edit The Thing")
end
<head>
<title><%= assigns[:page_title] || "Default Title" %></title>
</head>
Note that this uses assigns[:page_title] instead of #page_title or assigns.page_title as they will error if the :page_title key is not present in assigns.
For including templates (your script example) there is render_existing/3 (and the docs for the same function in the latest version of Phoenix).
The documentation gives a similar example to what you requested so I have copied it here for convenience:
Consider the case where the application layout allows views to dynamically render a section of script tags in the head of the document. Some views may wish to inject certain scripts, while others will not.
<head>
<%= render_existing view_module(#conn), "scripts.html", assigns %>
</head>
Then the module for the #inner view can decide to provide scripts with either a precompiled template, or by implementing the function directly, ie:
def render("scripts.html", _assigns) do
"<script src="...">"
end
To use a precompiled template, create a scripts.html.eex file in the templates directory for the corresponding view you want it to render for. For example, for the UserView, create the scripts.html.eex file at web/templates/user/.

Related

Set the <head> and <body> from the same eex file

In a particular new website using Elixir and Phoenix, there is lots of boilerplate in order to make the pages have a consistent style. Hence there is a "layout" template whose inner_content delegation is inside the html <body> tag (and a couple <div>s for styling). However, some parts of the <head> actually do change page-to-page, and these aren't just a few trivial values like the <title/>, there's a bunch of SEO metadata too.
Worse yet, there's probably enough visible boilerplate in each page, that significant nontrivial parts of the <body> probably ought to be factored out of the individual templates and into the layout, yet those parts might also contain title-like values.
How do I specify arbitrary extra content for the <head>, or for other places outside the one place where the vast majority of page-to-page-variable content goes, without getting an unmaintainable anti-DRY mess? (Where I come from, a child template could divide itself up into multiple named blocks that a layout template could substitute by-name at multiple different places within itself.)
I believe the correct thing to do is to use assigns field on the [Plug.Conn][1]
In my Pheonix (v 1.6.10) there's pre-decided page_title assigns, so just do this:
conn
|> assign(:page_title), "My Special title")
and it just works, because my root.html.heex has this:
<%= live_title_tag assigns[:page_title] || "Rumbl", suffix: " · Phoenix Framework" %>
And I suppose this is the right thing to do with any other custom stuff, like SEO medatada:
conn
|> assign(:my_seo_metadata), "Whatever")
and add in your template
<whatever>
<%= assigns[:my_seo_metadata] %>
</whatever>

Django template blocks: how can i reuse them and how do i pass HTML into them?

Being a frontend dev familiar with Ruby, i'm trying to learn Django templating system.
It appears to be an inside-out version of what i'm used to. I struggle to comprehend its reverse ideology: instead of declaring reusable blocks and including them where necessary, in Django you mark some parts of your template as overridable.
Here are two things that i don't understand about this.
With Ruby's Padrino, i would declare a partial (a reusable snippet of templated HTML) and then include it in multiple places. Wherever i call it, it would output its HTML.
According to Django's templating documentation, each block can be used on a page only once: Finally, note that you can’t define multiple block tags with the same name in the same template.
Another feature of Padrino that i find extermely useful is that partials can accept HTML and output (yield) it in a certain place inside them. Below are a couple examples, one for Padrino and one for Jade.
Please note that partails HTML not as a string (awkwardly passed via an argument) but in a template language via nesting.
Padrino (Ruby) example
With Padrino i can pass HTML template code into partials:
_container.erb
<div class="container <%= myclass %>">
<div class="container-inner">
<%= yield %>
</div>
</div>
layout.erb
<%= partial 'container', locals: { myclass: 'container--header' } do %>
<h1><%= Sitename %></h1>
<p>Welcome to my humble place</p>
<% end %>
Resulting HTML
<div class="container container--header">
<div class="container-inner">
<h1>Sitename</h1>
<p>Welcome to my humble place</p>
</div>
</div>
Jade example
In Jade, partials are called mixins and are processed directly by the template engine rather than the backend framework:
Jade source
mixin article(title)
.article
.article-wrapper
h1= title
if block
block
else
p No content provided
+article('Hello world')
p This is my
p Amazing article
Resulting HTML
<div class="article">
<div class="article-wrapper">
<h1>Hello world</h1>
<p>This is my</p>
<p>Amazing article</p>
</div>
</div>
Is it possible with Django?
Questions:
How do i reuse a block multiple times in Django? I would like to declare a snippet of template code and include it in multiple places on the page.
How do i pass HTML (template code) into a block? I would like to reuse it with different content.
The use case that i'm trying to cover is a reusable partial/mixin/block that would serve as a container wrapper for each section of the site.
Note that with Padrino, i can even make the partial in such a way that it will let me choose which wrapper tag (div, nav, header...) should be used for each instance of the partial, by passing an argument when including the partial:
<% partial 'container', myclass: 'container--header', tag: 'nav' %>
I wonder how to do that with Django.
In your answer, please comment on whether it is possible with both a) basic Django functionality; b) some Django extensions.
Thank you.
I’m not familiar with Padrino, so I’m not 100% sure I understand what you’re looking for.
However, Django template blocks definitely aren’t the equivalent of Padrino’s partials. From your description, I think the equivalent would be custom template tags.
In outline, to create a custom template tag, you:
Create a templatetags module within your Django app, with a file in it to contain the Python code for the tags e.g.
yourapp/
models.py
templatetags/
__init__.py
mytemplatetags.py
Within that file, create a variable called register that’s an instance of django.template.Library:
# mytemplatetags.py
from django import template
register = template.Library()
Within that file, write a function for each custom tag that you want.
For a tag that includes a template snippet, you’d want to write an inclusion tag.
Inclusion tags can take arguments, which could include HTML (but only as a string).

backbone/marionette attaching HTML into a region

I'm beginning to use Marionette within an existing backbone application. I've got some HTML which I want to append into a region. In pure backbone, I could just do this.$el.append(html_code) and that was all. As far as I can see, marionette regions allow only to operate on views (which have to implement the render method). Calling append on marionette region throws 'undefined method' errors.
Is it possible to attach plain HTML to a marionette region?
No, it's not possible to inject plain html into a Marionette.Region.
Theoretically you could access a regions DOM element with someRegion.el or someRegion.getElement(), but this must be done after rendering (which at least isn't possible inside a Marionette.View with standard behaviour).
But you can achieve the desired result by using a specially crafted Marionette.ItemView:
#someRegion.show(new Marionette.ItemView({template: '<h1>gach</h1>'}));
You maybe also should have a look at Marionette.Renderer .
a Marionette ItemView will look for a template and will call render on that template, so when you show the view in the region the html will be displayed just fine with out the need of you defining a render method.
MyImtemView = Backbone.Marionete.ItemView.extend({
template : "#myTemplate"
});
var myItemView = new MyItemView();
myLayout.aregion.show(myItemview);
this should work if you save your html in a template like this
`<script id="myTemplate" type="text/template">
<div><p>your html<p>
</div>
`
EDIT
you can also declare a render function in your view in case you need to generate and modify your html like this.
MyImtemView = Backbone.Marionete.ItemView.extend({
template : "#myTemplate",
render : function (){
this.$el.append(HMTL); //so here you work your html as you need
}
});
var myItemView = new MyItemView();
myLayout.aregion.show(myItemview); //the render function of your view will be called here
I ran into the same problem and tried the answers explained here, but I'm also using require.js and kept getting an error for the #my_view template not being found. If anyone can clarify where does Marionette look up the templates by default, that would be great.
Instead, I solved it by using the text.js plugin for underscore.js. This way you actually can use a plain html file as the template, without the need for nesting it in a script tag. Here's how I did it.
define(['backbone', 'underscore', 'marionette', 'text!tmpl/my_view.html'], function(Backbone, _, Marionette, view_t){
var MyView = Backbone.Marionette.ItemView.extend({
template : function(serialized_model) {
//define your parameters here
param1 = erialized_model.param1;
return _.template(view_t)({
param1: param1
});
}
});
return MyView;
});
I placed the text.js plugin in the same lib directory as all my other js libraries and my main.js for require declares the path to the templates as
'tmpl': '../../templates',
My project structure looks like this
root
index.html
js
main.js
app
App.js
views
MyView.js
lib
require.js
text.js
backbone.js
underscore.js
jquery.js
backbone.marionette.js
templates
my_view.html
My template 'my_view.html' simply looks like this.
<h1>THIS IS FROM THE TEMPLATE!!!</h1>
Worked perfectly. I hope you find it useful.
Using a view
var myHtml = '<h1>Hello world!</h1>';
var myView = new Marionette.ItemView({template: _.constant(myHtml)});
myRegion.show(myView);
Marionette.Renderer.render takes either a function or the name of a template (source code). _.constant creates a function that returns the passed-in parameter.
Attaching HTML
Alternately, the docs for Marionette.Region mention overriding the attachHtml method, see Set How View's el Is Attached.

Wrapping a Joomla website into a div

I have a pretty straight forward question, in regards to joomla templates.
The end result being : http://css3playground.com/flip-card.php
What I want to do is simple, in a sense, but need to know where to look;
I want to have the entire page wrapped in two divs, all the PHP code, to which class i can define in css and drop in some javascrpt so I can apply page transitions to that div. All of which I know how to do except for where to do it in, the PHP structure of joomla is new to me.
and also, after the first step is accomplished, create a second div after the content that would be dynamically loaded with content from clicked links on the page from within the template, but thats two questions at once lol.
Any ideas on the first part?
If you just want to use a div to encompass the entire template, do exactly that: wrap the template in a div and give it a custom class or id:
<html>
<head>
//stuff here
</head>
<body>
//insert the wrapper here
<div id="wrapper">
//template structure here
</div>
</body>
</html>
The file you want to edit will likely be named index.php located at public_html/templates/your_template/index.php.
For some templates, such as those by Yootheme, you will instead want to edit the file at public_html/templates/your_template/layouts/template.php (or /public_html/templates/your_template/styles/current_profile/layouts/template.php if you're using a profile other than the default).

Conditionally including content into Django 1.2 templates

How can I include with Django what Symfony calls 'components' - bits of logic and a template that's not associated with the content of the current page?
For example I want to include a sidebar that displays a list of the top 10 articles on the site. It should always be displayed if the user is looking at either an 'article' page or a 'video' page. Also, the top 10 articles component needs its own CSS and JS as well as producing content.
If I have a base template that contains sections for "content", "css" and "js", and 'article' and 'video' templates that extend the base template and then define "sidebar" blocks inside "content", what's the 'Django' way of going about this?
Thanks
Custom tags are what you want - specifically, inclusion tags that let you render another template within the current one.