Extending Handlebars.js templates - javascript

Is there a way to extend templates like in Django? My base template has a header that only needs to be a few pages. I'd like to change that for the the other templates.
Something similar to
{% extends "base.html" %}
...
{% endblock %}
I'm using Ember.js.

As far as i know this notation does not exist, also i haven't seen the concept of inheritance on handlebars templates layer.
However, i can think of two ways to achieve what you want,
1. using the {{partial}} helper http://emberjs.com/guides/templates/rendering-with-helpers/
The {{partial}} helper can render the header part and it can be included only on those templates of the pages that require the header.
2. using layouts http://emberjs.com/guides/views/adding-layouts-to-views/
Have two layouts one with the header and another without it, then specify on the pages/views that need the header the corresponding layout using the layoutName property.

I was looking for the same as I come from the same Django background. Here I've found exactly what you are looking for. It uses another module from npm called Handlebar-layouts. which is really useful.

Related

Sylius: How to modify/customize app.js?

I'm overriding the general theme in Sylius with my custom theme, which is working fine so far. I created a new theme in app/themes/myCustomTheme and am overwriting e.g. the twig templates in /SyliusShopBundle/views/.
Now I want to override the general app.js located in vendor/sylius/sylius/src/Sylius/Bundle/ShopBundle/Resources/private/js/. E.g. instead on line 18:
$('.ui.accordion').accordion();
I would like to use a different selector to initialize the accordion:
$('.my-custom-accordion').accordion();
Assume this is the only change I want to do in the whole javascript code. What is the best and most efficient way to do this? I would like to have as minimum conflicts as possible when there is a Sylius version update and therefore touch as less files as possible. And of course, not have to rewrite the whole javascript functionality by myself.
I can think about different ways to do this, but I hope there's an even better one:
Duplicate everything. Copy all the UiBundle & ShopBundle javascript code to my theme and modify the necessary parts. Update the global gulpfile to no longer use the gulpfile in vendor/sylius/sylius/src/Sylius/Bundle/ShopBundle/Gulpfile.js and instead use the duplicated one /myCustomTheme/SyliusShopBundle/Gulpfile.js. Downside: duplicated code, javascript updates no longer possible.
Add custom path to existing gulpfile. Update the gulpfile in vendor/sylius/sylius/src/Sylius/Bundle/ShopBundle/Gulpfile.js, which means removing the line which includes the app.js: vendorShopPath + 'Resources/private/js/**' and instead reference all single files without the app.js AND reference to the customized app.js in my theme folder. Downside: Changes to the gulpfile are probably overwritten by the next update.
How do I efficiently modify/customize/extend the existing javascript code in Sylius?
I solved this for me creating a custom gulpfile in my bundle (AppBundle) and adding it to the global gulpfile in the same way of "admin" and "shop". After that you can include your custom app.js in the layout or whatever template. In my case I modified the Product/show.html.twig to add my custom .js:
{% block javascripts %}
{{ parent() }}
{% include '#SyliusUi/_javascripts.html.twig' with {'path': 'assets/app/js/app.js'} %}
{% endblock %}

Ember js link templates includes

I am working on constructing simple Ember js template links and since I am somewhat new to Ember and I come from PHP background I tried building the idea from PHP experience on including ember templates in another template such as this:
<script type="text/x-handlebars" id="top-nav">HTML HEADER</script>
<script type="text/x-handlebars" id="index">{{render 'top-nav'}} HTML body</script>
The idea behind it is that I want 'top-nav' template to be included in every ember template. I know {{outlet}} works in the similar matter, but it won't provide the flexibility of having few lines of code.
My question: Is there a more plausible way to insert templates into templates?
Thank you.
The best way to insert a template inside of another template is simply to use a view.
{{view 'top-nav'}}
define your template like:
<script type="text/x-handlebars" data-template-name="top-nav">
... template markup
</script>
and then define your view in js
Ember.View.extend({
templateName: 'top-nav',
});
and that is it. you can find more documentation on it here: http://guides.emberjs.com/v1.10.0/views/inserting-views-in-templates/
EDIT
as #GJK pointed out views have been deprecated as of Ember 1.13 if you are using Ember 1.13 or later I would recommend using a component instead.
{{top-nav}}
components work in a similar way that a view used to work. you can find more information about them here. ultimately it depends on what version of Ember you are using.
http://guides.emberjs.com/v2.0.0/components/
Is there a more plausible way to insert templates into templates?
This is exactly what partials are for. You can read up more on partial templates here. The gist is that you want to create your re-usable part using a filename that starts with _. For example:
{{! _header.hbs }}
<header>
<nav>...</nav>
</header>
Then, you can use {{partial 'header'}} to drop that code right into another template (with the same context).
That being said, having a header on every page is usually a scenario where the application template is most useful. You can define your application template like so:
{{! application.hbs }}
<header>
<nav>...</nav>
</header>
{{outlet}}
This will ensure that all of your pages have the header you desire because every top-level template will be rendered inside of the outlet.
If you're having trouble deciding what to use, use partials until you run into issues. At that point, you'll probably be more equipped to deal with the application template and complex template structures.

Django Client Side Filtering

I'm pretty new to Django and I'm working on a site where I want the user to be able to filter out objects based on the objects' timestamp. I could easily do the filtering in views.py and reload the template, but how should I do this filtering client side?
Would it be a good idea to just load everything:
{% for obj in all_objects %}
<p>{{obj.time}}</p>
{% endfor %}
and then use javascript to hide and show the relevant objects? I don't expect more than 1,000 objects.
I've taken a look at this:
http://dustindavis.me/dynamic-filtered-drop-down-choice-fields-with-django.html
and the author says that he would use AngularJS instead of a custom AJAX solution.
Is Angular my best choice or are there other frameworks that are easier to integrate with Django?
You don't need a whole framework such as Angular to filter your results, though I'd certainly recommend using one of the popular MVC frameworks.
However, if you go that route you will significantly change the architecture of your django application since Angular and such are really built for single-page applications, and would suit you best if your django project was exposing an API rather than rendering HTML.
Having said that, to solve your problem, I would continue to use the same django template, and load the content of the list into a hidden HTML element.
Then in your page's Javascript code, you can extract the relevant items from the list based on user selections. That code would be entirely Javascript, though.
As a tip, i would use the django template to insert the filtering parameters as data attributes of your hidden HTML tags. An example:
{% for obj in all_objects %}
<p data-time='{{obj.time}}' data-somefilter='{{obj.somefiter}}'>{{obj.time}}</p>
{% endfor %}
This way you can easily use Jquery selectors to filter the data based on the requirements and then copy over the results to the visible HTML section where you display the filtered list

What is the difference between an include, a partial, and/or a block in templating. EJS / ejs-locals

I have been using EJS with Express and Node.JS for a little while now and I think I understand the basics. I have experimented with the EJS include function which has allowed me to include one template inside of another. I have also used a library called ejs-locals which provides easy true layout support. One thing I noticed is that ejs-locals also defines partial and block functions which may be used with EJS. I cannot seem to find a good explanation on what the differences between these three concepts are. As far as I can tell they are general concepts to templating and not only EJS. It seems to me that both partial and block are still ways of including other template files, but how do they differ?
include: Simply takes the content from the given file and places it where your include statement is. In other words: The file has access to all variables defined in the file it has been included from.
partials: Pretty much the same as include, with the difference that the partial has only access to the variables that you pass to it when rendering.
blocks: In your layout you define locations where your blocks' content should be. In the file you render, you define contents for these blocks and define the layout you would like your block content to be rendered to.

When using (only) a templating system, how should I manage CSS, javascript etc for sub-templates?

I've had this same question when working with different templating systems in different languages in the past, so first,
The general question
I want to use a sub-template to include a certain UI component which might appear in different places on a number of different pages. This UI component requires certain CSS and JS files.
I want to Do The Right Thing with CSS and JS resources, which, as far as I know and in broad terms, is to a) combine as many as possible b) minify as much as possible and maybe c) put what I can at the end of my markup so the browser doesn't have to wait for them to load before displaying content.
So, if I've got various different UI components, as well as different headers and sidebars in different sections of the site, which all require their own special CSS and JS to function correctly, what's the best way for me to manage them through a templating system so that the final markup is as small and well-organised as possible?
Specifics of my situation
I'm working on a large legacy PHP site, on which, to give the original authors the benefit of the doubt, development may have begun before MVC became really mainstream, and before there were so many choices of frameworks around to use. So there is no consistent MVC framework, no routing, no templating (no ORM either, but that particular curse isn't as relevant here).
I'm going to have to keep things ticking over, squashing bugs and adding a few new features until a complete rewrite is usable, so I'm trying to breathe some sanity into things as I go along.
The easiest place to start seemed to be the views layer, for which I'm using TinyButStrong. An example of their sub-templates can be found here, but like I said, I think this is a very general question.
Things I've considered
With a more integrated framework I'd like to be able to do something like $view->add_js($foo), but transitioning to a full-blown framework is what other people are doing while I try keep the existing codebase seaworthy. There isn't even really enough consistent organisation of files to roll something like this by hand.
At the moment the best thing I can come up with is making a DOMDocument out of the view right before it's output and manipulating <link> and <script> tags at that point. I don't know if that's a bit crazy though. Given the generality of the problem I'd like to think that there's a known sensible way to go about it.
Many thanks for your input.
It's hard for the reader to know what can or cannot be done with your code base. A common way to handle this situation would be to pass parameters to the view template, and the template can then include conditional chunks or include sub-templates based on your parameters. This does not require a full-fledged framework, a stand-alone template engine should do. If your template engine supports inheritance there is a nice pattern for handling assets in your templates - check here for example http://symfony.com/doc/2.0/book/templating.html.
Manipulating the Dom for each request to handle this kind of thing seems bit unorthodox.
What you want in this situation is some form of template inheritance; that is, technology whereby a sub-template has access to areas in a 'parent' template, and can edit or replace content in those areas. Using this ability, CSS and JS required for a component included via a sub-template can be added in to the <head> element of the parent page.
In Twig, this is achieved using named blocks. First, you create your parent template (or layout, as it's called in Twig), e.g. index.html.twig. You include in it a named block like {% block myCss %}.
Next, to create a sub-template, you begin the template with the line {% extends ::index.html.twig %}. Then, the content of a block defined in the sub-template with the same name as a block in the parent template (in this case {% block myCSS %}) will get substituted into the parent template. To append rather than replace content in the parent template, use {{ parent() }} to include content already existing in the parent.
An example of this with code is available at the link given by #Basel Shishani. I've heard that Twig is modelled after Django, and template inheritance in Django looks very similar (with the exception of using {{ block.super }} instead of {{ parent() }}. There is a discussion of how to achieve the same ends in TinyButStrong.
As a wider point, the Assetic library looks like a very promising solution for managing CSS and JS assets, in order to avoid duplication (e.g. where the same JS file is required by multiple components/subtemplates), enable concatenation and minification of assets, and more. This presentation of its features gives more details.

Categories

Resources