Handlebars template with "div" tag instead "script" - template-engine

Actually the question is in the subj...
Is it possible to make handlebars template framework, to recognize templates within a div tag and not in script tag?
For example I would like to create template with this markup:
<style>
div.text-x-handlebars {display:none;}
</style>
<div class="text-x-handlebars-template">
<h2>I'm template</h2>
<p>{{welcomeMessage}}</p>
</div>

Yes you can put your templates in <div>s rather than <script>s, for example:
http://jsfiddle.net/ambiguous/RucqP/
However, doing so is fraught with danger. If you put your template inside a <div> then the browser will interpret it as HTML before you've filled it in; so, if your template's HTML isn't valid until after it has been filled in, the browser may attempt to correct it and make a mess of things. Also, if you have id attributes in your templates, then you will end up with duplicate ids (one in the template <div> and a repeat in the filled in template that you put in the DOM) and that will cause all sorts of strange and interesting bugs. The browser will also try to download any images inside the templates in a <div>, this may or may not be a problem (if might even be desirable but probably not desirable if the image uses a template variable in its src attribute).
Basically, you can do it but you shouldn't, you should put your templates in <script id="..." type="text/x-handlebars-template"> elements instead.

Related

Include blade template without interpreting html

I have a blade template that has some HTML and some JS code. For both case 1 and 2 I'd like to use the same template as it's used in multiple places.
Case 1: include the template with the normal behaviour, so that the code in the template gets executed. This works with the normal behaviour of using #include('template')
Case 2: include the template without the HTML and JS actually being interpreted.
Now I could solve this by making it an x-template component, and then pass a variable to that component that will conditionally wrap the template in <xmp></xmp>.
But the problem is that I use Highlightjs, and that doesn't work if the code is in those xmp tags. It needs to be in <pre><code></code></pre>.
So I'm wondering if you can pass some parameter or do something to include a blade template without actually interpreting the code that's being included.
Update
A bit more clarification. Let's say template.blade.php has this:
<div id="test"></div>
<script>
alert('test');
</script>
In case 1 using #include('template') should alert test when the page is loaded.
In case 2 using #include('template') (but then another way I guess, that's what this question is about) I'd like it to display the code without interpreting it, like would happen when using <code>{{ '<div id="test"></div><script>alert('test');</script>' }}</code>.

How To Emit Only Gallery IMGs from Batflat CMS

If you make a Gallery in Batflat CMS, the template tag it creates will generate its only Bootstrap HTML for a gallery. What if I just want to emit IMG tags for the gallery items, instead?
Create a Gallerymod custom module. That way, your customization may likely survive a Batflat Update.
Copy inc/modules/galleries as inc/modules/gallerymod.
Remove the lang folder and Admin.php in your gallerymod folder.
Change the Name and Description inside the gallerymod/Info.php, as well as the comments. I used static strings instead of code. Also in this file, inside the install function and uninstall function, remove code inside those so that it does nothing on install or uninstall.
In your gallerymod/Site.php, look for the $assign[$gallery['slug']] assignment, and on the following line, add:
$assign[$gallery['slug'] . '-alt1'] = $this->draw('gallery-alt1.html', ['gallery' => $tempAssign]);
Also, where you have the namespace line set as namespace Inc\Modules\Galleries;, change it to namespace Inc\Modules\Gallerymod;.
In your gallerymod/view folder, create a gallery-alt1.html file and add these contents:
{loop: $gallery.items}
<img class="photo-{if: $value.title}{$value.title}{/if}" alt="" class="img-responsive" src="{?=url($value.src.lg)?}">
{/loop}
Now activate this inactive module in Batflat's admin system. You'll notice that it has no admin panel -- because it doesn't need one. You already have the Galleries one. Do not deactivate the Galleries module because the Gallerymod module relies on the Galleries module.
Now, from your custom theme template, you can call this by varying how you called the old slug. So, if your old way of calling the gallery was something like {$gallery.home-photos}, then you would merely tack on the "-alt1" on the end and call it like {$gallery.home-photos-alt1}. I like to wrap these in a DIV wrapper with an ID on it so that I can address it with CSS, jQuery, or Javascript.
In the Batflat Admin system, go back and edit your image titles in the gallery. Treat those titles like a slug (lowercase alphanumeric phrase with dashes) because these are used as class names on the IMG tags in gallery-alt1.html, and you may want to address these individually in CSS, jQuery, or Javascript, later on.
Refresh your browser and you may see the source code display something similar to:
<div id="hidden-images" class="hidden">
<img class="photo-man2" alt="" class="img-responsive" src="https://example.com/uploads/galleries/2/15831273220.jpg">
<img class="photo-woman1" alt="" class="img-responsive" src="https://example.com/uploads/galleries/2/15831272980.jpg">
<img class="photo-man1" alt="" class="img-responsive" src="https://example.com/uploads/galleries/2/15831272540.jpg">
</div><!-- hidden-images -->
Just remember that if you update your version of Batflat, that you may need to reapply this customization again -- it depends on what was done in the update to the existing Galleries module.
If you have different tastes as to how you want to format your images, just edit your gallery-alt1.html file. Plus, you can make multiples of these for different situations, such as gallery-alt2.html, gallery-alt3.html, etc. You can even make it emit JSON instead of html so that you can insert it into a Javascript block in your theme.
Another tip for debugging, in case your site won't load or the admin system breaks, is to edit inc/core/defines.php and change the DEV_MODE to false. That way, PHP will show you every error and that might help you in debugging what might be wrong.

How to create a custom HTML div in Sphinx that isn't automatically nested within a subsubsection?

I'm using the wonderful Sphinx tool to create some documentation and I need to create a custom HTML div so that I can style it apart from Sphinx's other, automatically-created, divs.
This is possible to do using the container directive, but the problem is that if I use this directive below a subsubsection, it automatically nests the div created with the container directive within the subsubsection, like so:
<div id="automatically-created sphinx subsubsection">
...
<div id="my custom container"></div>
</div>
Whereas, I want:
<div id="automatically-created sphinx subsubsection">
...
</div>
<div id="my custom container"></div>
Is there any way to do this? Any help would be greatly appreciated!
Addendum:
One hacky way of potentially solving the problem is to create a new subsubsection so that Sphinx automatically places it on the same level as other subsubsections and then use CSS to hide its header etc. The problem with this approach, however, is that the new subsubsection automatically gets added to the sidebar in the RTD theme (which I'm using) and this is not what I want.
Untested. Try a super-hacky .. raw:: directive, where you would close the current section, then open a new unclosed <div>:
.. raw:: html
</div>
<div id="my custom container">
Then resume using reStructured text markup. This would "trick" Sphinx into thinking that the current section is still open and it would still add a closing </div> after the rest of your markup until it starts parsing the next section.

Passing JSON as HTML element text

Would there be bad consequences from transporting JSON in HTML like this:
<div id="json" style="display: none;">{"foo": "bar"}</div>
assuming HTML chars such as < are escaped as < in the element text?
The JSON could be strictly parsed:
var blah = $.parseJSON($('#json').html())
in a try/catch statement, for example. The rationale is to enable passing of JSON in Ajax'd HTML responses, when script tags are being stripped an not executed. An example would be Ajax requests made using the jQuery .load() special selector syntax:
$('#here').load('some.html #fragment')
...which ditches all script tags and thus prevents the use of:
<script>var blah = {"foo":"bar"}</script>
I've seen JSON being passed around in HTML attributes, and I'd guess this is equivalent - w.r.t. weirdness, security, etc - but is far less readable due to all the additional quote-escaping.
The natural way of passing JS data in HTML is through JavaScript code (if is a part of actual JavaScript code, like in the case of initial values/configuration) or by data- HTML5 attributes (whenever JS code is not necessary; always when data needs to be somehow attached to DOM elements).
In your example this would be probably the best:
<div id="json" style="display: none;"
data-something="{"foo":"bar"}">
</div>
but reorganize your data to actually follow HTML structure:
<div class="profile-container"
data-profile="{"name":"John Doe","id":123}">
... profile 123 ...
</div>
<div class="profile-container"
data-profile="{"name":"Jane Doe","id":321}">
... profile 321 ...
</div>
(quoting should be done server-side, eg. using PHP's htmlspecialchars(...), or Python's cgi.escape(..., True)).
And then you can obtain the data in one of multiple ways, eg. using jQuery's .data() method.
EDIT:
Yes, your approach with embedding JSON as content of HTML tags and hiding it using CSS styles has gotchas. As I said, if you want to pass data in HTML, the only "best practice" way is to attach it to one of HTML elements (you are kind-of doing it anyway, but you use CSS to hide it, while you can use existing solutions for passing JSON/data without affecting clients that could override your styles). The proof for one of disadvantages is here: http://jsfiddle.net/NY7Bs/ (data is passed both ways, but one simple external style overrides your inline styles and shows the content - not mentioning the influence on semantics of your document).
Why not simply use the .ajax() function then, you would get only the string with the json. Then you could parse it as you suggested.

How to modify body class in MVC3 view page

Just wanted to add a class="myClass" in body tag. Is there any html helper or something else can do this in MVC3 view page? Please advise, thanks.
This is very similar to Aaron's solution, but doesn't have the weight of a section (which at least in my mind, are for larger blocks of content than a single string). The simplest way is to pass a variable with the ViewBag.
In your layout, just print out the class for the body tag, plus any other page specific variables (page title, extra css/js scripts, etc...)
_Layout.cshtml:
<html>
<title>#ViewBag.Title</title>#* Can easily add in per page titles too *#
<body class="#ViewBag.BodyClass">
#RenderBody()
</body>
</html>
Then, variables set in your view get passed upwards to the layout:
Index.cshtml:
#model MyViewModel
#{
ViewBag.Title = "This page title!";
ViewBag.BodyClass = "...";
}
While you may have full control of the HTML a solution was what was needed so here is one ;-)
In the _layout.cshtml page
<body class="#RenderSection("BodyClass", false)">
This will look for a section in all the child pages but says don't worry if it can't find one
Then in your child views just do this
#section BodyClass {productList}
Keep it on one line and then the outputted HTML will look fine, also you can then build up the class names as well.
#section BodyClass {productList generic}
This idea goes perfect with DOM-Ready page specific code, why not checkout
http://paulirish.com/2009/markup-based-unobtrusive-comprehensive-dom-ready-execution/
Or my extended version here
https://github.com/AaronLayton/H5BP-Core
My way lets you do page specific code, but allows you to keep all of the Javascript in separate pages so each page becomes easily manageable. The final step would be to concatenate and minify all the JS into 1 file ;-)

Resources