We use this syntax to include partial during run time:
{{> (lookup . 'file') }}
file is a var name from the parent file.
I tried to add a prefix to the file name, So I tried:
{{> lookup . 'path/file'}}
{{> (lookup . (strmerge 'path/' 'file')) }}
Note: I made a helper method to merge strings
I tried those and others but nothing worked for me.
Does any one know how to do this?
Thanks
In the code {{> (lookup . 'file') }} we are telling Handlebars that the name of our partial is to be found at the file property of the current context object.
Assuming a context object like { file: 'myPartial' }, the result of the lookup is {{> myPartial }}, which tells Handlebars to render a partial called "myPartial".
If we want to add a prefix to our partial, so that Handlebars will register a partial called "path/myPartial", the simplest way to do this would be to add that path to the value of the file property in the context object. The context object would become: { file: 'path/myPartial' }.
If, for some reason, the "path/" prefix must be added to the template and not the data, then we will need to determine a way to produce the String "path/myPartial" from our current data.
Both of your attempts put "file" in the name of the property to be looked-up. Your code will try to find the property path/file on the context object and this will fail. We will definitely need a helper to concatenate Strings, but it must concatenate "path/" with the value of file, not the literal String, "file".
To achieve our goal we will no longer require the lookup helper. The lookup was needed only because you can't write {{> (file) }} in Handlebars, because Handlebars will treat file as a helper instead of as a variable. However, since we are using a concatenation helper, strmerge, we can use the String it returns as our partial name, without any need for a lookup. The correct code becomes:
{{> (strmerge 'path/' file) }}
It's important to note that file in this example is not in quotes. It is a variable, not a String.
I have created a fiddle for your reference.
Related
I'm trying to reference a Twig expression inside another expression:
{{ dbquery('name', 'product_manufacturer_translation', {'product_manufacturer_id =' lineItem.payload.manufacturerId} ) }}
Here, lineItem.payload.manufacturerId is the Twig expression I'm trying to put into the dbquery - but this does not work. Thanks for sharing your thoughts!
Edit: this query does not yield a result. What I would expect is a product manufacturer name, based on the product manufacturer ID. The manufacturerId experssion itself, when used on its own, does yield a result. I know there is a database record that should match this query, too.
I wrote a helper function to help me format URL, which is the combination of some object attributes. How do I concatenate this attribute in handlebars view?
Helper function
const url = (link)=>{
return process.env.URL+'/'+link.replace(/ /gi,'-').toLowerCase();
};
My view
{{this.name}}
What you can do to accomplish this is to create a helper to concatenate your strings and pass the concatenated string to the url helper.
In JavaScript, every non-arrow function has a local variable named arguments assigned an object, in this object you'll find (you guessed it) the arguments passed to the function when it was invoked.
Using this arguments object we can create a helper for Handlebars.js that lets us concatenate as many strings as we want.
Because (as described by the documentation) the arguments object is an array-like object, we have to create an actual array from it that we can use to concatenate everything together using Array.join to make it as simple as possible.
Handlebars.registerHelper('concat', function() {
return [...arguments].join('');
});
But why would it be that simple, right?
What I discovered when I was trying out this solution is that the last element in the arguments object is an object with some information about the helper that was used, like the name.
To make this work with that little bit of information in mind we have to slice the array so that the last element gets removed and then concatenate it.
Handlebars.registerHelper('concat', function() {
arguments = [...arguments].slice(0, -1);
return arguments.join('');
});
We now have a helper that we can use to concatenate whatever we want, the only thing left to do is pass it to the other helper, the url helper in this case.
{{url (concat 'samples/' this.name '/' this.class '/' this.id)}}
^ I found a comment on an GitHub issue regarding chaining helpers and that Handlebars.js apparently has native support for this.
I hope this helped and that I didn't spoon-feed to much without explaining it properly.
I'm working with expressJS and handlebar as an engine template in my index.hbs I have a JS script in which I need to get a value of an array of object, here is the code of my script
<script >
new Morris.Line({
element: 'myfirstchart',
parseTime:false,
data: {{graph}},
xkey: 'version',
ykeys: ['success'],
labels: ['Success']
});
</script>
but the array graph does not pass, in my log console it is shown like
this
What should I do to get the value of my {{graph}} ?
Please add a sample of your data in {{graph}} and also what you expect instead of [object Object]. You'll need to format your data with the handlebar template {{graph}} contains one array of 5 elements containing objects.
If your data is let say {'x': '100', 'y':200} and that you want the same output with handlebar then you should put this instead of {{graph}}:
[{{#each graph}}{'x': {{x}}, 'y': {{y}} }{{/each}}]
If you put your data and the expected output format I'll may give a more accurate answer.
You need to stringify your array object i.e. JSON.stringify(graph) from server side and while accessing it use triple brackets {{{graph}}} in your javascript script tag code.
I am creating an application where the site menu would be dynamically loaded from JSON file. Each menu may correspond to an action that would be defined inside the ng-click directive. This would look something like this
<li ng-repeat="menuItem in menuContainer.menus" class="{{menuItem.cssClass}}">
<a href="{{menuItem.url}}" ng-click="{{menuItem.clickAction}}">
<i class="{{menuItem.iconClass}}"></i>{{menuItem.name}}
<span class="badge">{{menuItem.subMenus.length}}</span>
</a>`enter code here`
<li>
Now the problem is ng-click does not recognize the clickAction as a function, I believe this is due to linking process. I want to know is there any way to evaluate a string to method. I tried do $eval but it executes the function on load.
How do I do this?
Define methods not as strings, but as functions and replace ng-click="{{menuItem.clickAction}}" to ng-click="menuItem.clickAction()". Another way to define function on $scope, like:
$scope.executeString = function(body){
eval(body);
};
and replace your ng-click to ng-click="executeString(menuItem.clickAction)". Anyway, use eval is antipattern;)
Remember, that ng-click and other directives, like that, takes angular expression as parameter. And if body of you expression is a = b + c than angular convert it in javascript like $scope.a = $scope.b + $scope.c
Is there a better way to capitalize the first character of a string in Jade than this?
for list in project.lists
- list.name = list.name.charAt(0).toUpperCase() + list.name.slice(1);
li #{list.name}
Doing this every time I want to capitalize a variable is ugly, is there any way in Jade that I can define a custom function that I have available in every template like:
for list in project.lists
li #{ucfirst(list.name)}
Thanks in advance!
The contents of #{} are executed as standard JS, so you can pass in helper functions for use with things like that. You haven't specified, but assuming you are using Jade along with Express, you can do something like this:
app.locals.ucfirst = function(value){
return value.charAt(0).toUpperCase() + value.slice(1);
};
That will expose a function called ucfirst within the Jade template. You could also pass it in as part of locals every time you render, but if you are using Express it will do it automatically.
If you're willing to resort to CSS, you can create a class that capitalizes the first letter of every word within the target element.
CSS
.caps {
text-transform: capitalize;
}
Jade
div.caps
each foo in ['one', 'two', 'three']
span #{foo}
Resulting HTML
<div class="caps"><span>one</span><span>two</span><span>three</span>
Resulting view
One Two Three
If you are using pug with gulp, this can be helpful:
mixin ucfirst(text)
- text = text.charAt(0).toUpperCase() + text.slice(1);
.
#{text}
Simply call this as any other mixin:
li
+ucfirst(list.name)