converting a jade if statement to handlebars (hbs) - node.js

I've been following this tutorial and I've been able to convert each jade line to hbs apart from this one;
- if (user_open.id != user.id)
I tried this;
{{#if "user_open.id != user.id" }}
but it doesn't seem to work. Any ideas???

Handlebars is logicless so you can't use the != operator directly. You'll need to pre-compute in javascript a boolean value you can pass to the template when you render such as isOther so you can do {{#if isOther}} in your template or create a block helper function so you can do {{#isOther user user_open}}

Related

Cascading Template Use in mustache-express?

My intent is to define a page_layout template and a form template as well. Within the route handler i was going to parse the inner (form) template and inject into the greater layout than return.
After several plot twists i'm able to use the response.app to get access to my mustache template engine and parse a view, but the HTML is getting escaped :(
let router = require('express').Router();
let mustache = require('mustache');
router.get('/plant', function(request,response) {
response.app.render('plantForm', {pageTitle: "Plant"},function (err, html) {
response.render ('layout', { pageContent : html});
});
});
yields the outer template with escaped html where I expect content:
<div class="form-group">
<label for="plantNameInput">Plant Type</label>
Perhaps I'm misusing the technology?
From the Mustache documentation:
All variables are HTML escaped by default. If you want to return unescaped HTML, use the triple mustache: {{{name}}}.

Call Helper functions inside Twig (Timber)

I try to call a static helper method inside Twig (Timber).
{{ function('Theme\Helpers::get_template_name') }}
Warning: call_user_func_array() expects parameter 1 to be a valid
callback, class 'ThemeHelpers' not found in
/var/www/html/wp-content/plugins/timber-library/lib/Twig.php on line
268.
Does anyone know how to call a method of a different class inside Twig?
As far as I know you can't call PHP classes directly from your twig template.
What you can do is setting up a Twig filter which communicates with your class
and returns the needed value.
You would have this in your php controller file that is responsible to load your twig template:
<?php
function twg_get_template_name() {
# edit this according to the implementation of your class:
return Helpers::get_template_name();
}
function add_to_twig($twig) {
/* this is where you can add your own fuctions to twig */
$twig->addExtension(new Twig_Extension_StringLoader());
$twig->addFilter('twg_get_template_name', new Twig_Filter_Function('twg_get_template_name'));
return $twig;
}
add_filter('get_twig', 'add_to_twig');
In your Twig template you would call the filter like this:
{{ ''|twg_get_template_name }}
Because it's a filter function it expects a value "to filter", so pass at least an empty string.
If I were in that situation I probably would determine the name of the template in your
controller and send the value to your Twig template directly instead of calling the php class
via a filter-function.
You can call static functions from a Twig file in Timber using the array notation, where first item is the name of the class and the second item the name of the static method you want to call:
{{ function( [ 'Theme\Helpers', 'get_template_name' ] ) }}
Thanks for your answer.
I tried your approach - it works. But using a filter feels a little hacky, especially when no value is passed. Why not create a timber function the same way as a filter?
Bridging own functions from plain php into twig is not great, but I also don't see another solution to this.
After playing around a little, I came up with a different approach. I now fixed my need by customizing the Timber Object and adding a template property to the post variable.
Looks something like this:
class OnepagePost extends TimberPost {
var $_template;
// Add template property to Twig Object
public function template() {
return Helpers::get_template_name( $this->custom['_wp_page_template'] );
}
}
Then inside the .php file where the Twig View gets called, I called the custom object like this:
$context['posts'] = new Timber\PostQuery( $args, 'OnepagePost' );
Timber::render('onepager.twig', $context);
Inside the Twig Template I'm able to get my custom property very easy (in my way the template):
{% for post in posts %}
{% include ["section/section-#{post.template}.twig"] %}
{% endfor %}

split string in nodejs

I am working on node js with mongodb. I am getting the value of doc in view file.
{{#each doc}}
<div class="abstract" data-reactid=".1ejbmifi4u8.1.1.0.1.2.0:$35.0.0.1.2.0" id="content">
{{this.content}}</div>
{{/each}}
this will print the value of content.
I want to print only 40 characters of this content on view page and then want to implement "read more" to go to full content page.
Guessing by the syntax, you are using Handlebars or some similar derivative. If it's not Handlebars, you'll have to modify the below a little to match your framework, but it should be similar. Leave a comment if it's not and I'll edit.
Handlebars supports what is known as helpers which allow you to manipulate data fed into your views.
You could write a helper named, for example, excerpt, like so:
Handlebars.registerHelper('excerpt', function(data, url) {
if (data.length > 40) {
return new Handlebars.SafeString(
data.substring(0, 40) + '… Read more"
);
}
return data;
});
You can then use it like {{excerpt this.content this.readMoreUrl}}, where this.readMoreUrl is whichever property provides the relevant URL.
I am not familiar with the JavaScript MVC but You can do something like this in JS:
content = this.content
if(content.length > 40)
content_to_print = content.substr(0,40)
content_to_print = content_to_print+' Read More...'
Hope this helps!

Call function in twig.js file

I'm creating an express application and for the views render I use twig.js.
I'm displaying some posts from mongodb into index.twig file. The question is how can I call a function from a js file(let's call it Utils.js) in the twig file?
My index.twig file looks something like this:
<div class="post-date">{{ post["date"] }}</div>
<div class="post-body">
{{ post["body"] }}
</div>
What I need to do is to format that post["date"] calling a method from Utils.js not just echoing it out as it is. How can I do that ?
P.S. I know that there are filters for date but I want my own data format.
The question was answered here: https://github.com/justjohn/twig.js/issues/206#issuecomment-73443040
To add a filter you can use Twig.extendFilter():
Twig.extendFilter('foo', function (value) {
return util.format(value);
});
After adding a filter you'll be able to use it in your templates:
{{ value|foo }}

Jade helper for FontAwesome

I want to write some helper for FontAwesome in jade template in Express.js, so I did in app.js:
app.locals.icon = function(icon){ return '<i class="fa fa-' + icon + '"></i>'; };
and called in template:
block content
h1= title
p Welcome to #{title}
= icon('users')
however it returns me escaped HTML code. What is a good practise for writing this kind of helpers ? How to return raw HTML ?
Try with != operator
!= icon('users')
Refrence from http://jade-lang.com/
Unescaped buffered code starts with != and outputs the result of evaluating the JavaScript expression in the template. This does not do any escaping, so is not safe for user input.

Resources