-
-
Notifications
You must be signed in to change notification settings - Fork 278
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Is it possible to define and pass data to an Assemble partial inline? #228
Comments
Currently we're limited to valid Handlebars syntax, so that wouldn't work with partials. But you could easily create custom helpers to do what you're trying to accomplish. With helpers, you're really only limited by the JavaScript you write. You can also use underscore templates (lodash) in YAML front-matter (or in separate JSON or YAML files), so you could almost do what you're suggesting. It's not quite the same as defining data inline, but for example, you could do something like this: ---
title: Home
list: <% _.forEach(people, function(name) { %><li><%= name %></li><% }); %>
people:
- Jon Schlinkert
- Brian Woodward
---
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{title}}</title>
</head>
<body>
<section class="people">
<ul>
{{{list}}}
</ul>
</section>
</body>
</html> And of course, the data could be supplied from anywhere. I'm just using YAML front matter as the example. You can also mix and match whatever helpers, lo-dash templates, partials, etc. Here are some links to related docs:
Let me know if you aren't able to find a way to accomplish what you need. There is a good chance we'll be able to figure out something idiomatic. |
Hi @jonschlinkert, Thanks for the reply. It looks like Handlebars is not designed for the problem I'm trying to solve. I could write a simple custom helper such as: helpers.inputtext = function(id, label) {
return '<div><label for="' + id + '">' + label + '</label><input type="text" id="' + id + '" /></div>';
}; Which I could then use with:
But I don't like this solution because it requires me to put my HTML for the component in a JavaScript file. Do you know of another way to make templates for interface components in Grunt? |
I have come up with another solution which I think does the job OK. I'm probably not using Handlebars the way it was intended though. I have a normal partial set up like this: <div>
<label for="{{id}}">{{label}}</label>
<input type="text" id={{id}} />
</div> I have a block helper set up like this: helpers.parseJSON = function(data, options) {
return options.fn(JSON.parse(data));
}; Then I include my partial like this:
The helper parses my JSON and passes it into the partial. |
It all depends on what you're trying to get accomplished and what the most pragmatic trade-off is. In all proposed solutions you're doing something that isn't quite idiomatic. E.g. is it better to have a little HTML in your JavaScript, or have a data model (and data) in your markup? That's an interesting solution you came up with, you have me really curious how you're using this. Also, do you mind if I add that as a helper to our handlebars-helpers library? thanks for the update |
Hey Jon, yes of course you are welcome to use the helper in the handlebars-helpers library. I'd be honoured! We will use this pattern to build interface components and enforce consistency where these components are used. For example, we might build an input text component to ensure that all input text fields in the website:
Instead of having to write out the same HTML over and over again, we can define it once in a partial and then include that partial inline whenever we need it. Typically Handlebars requires data to be defined separately from templates. But in this use case it is easier to define the options for the partial where we include the partial. These options aren't "data" that should be separated from the template; they are really just options for the template. |
Very clever, thank you for sharing this and providing insight on why you're using it. Sounds like we share some common goals. I saw some of the projects you've created, also very interesting. You have some great ideas, let me know if Assemble doesn't do something you need and we'll get it figured out. |
IMHO, this parseJSON inline magic is very useful! |
The context seems to become limited to that JSON object that gets passed in however - my root data scope is not available. Is there a variable like 'root' or something I can call in my partial to get back to accessing the root context? I have a 'settings' object that gets lost as soon as I use parseJSON. If I could reference it as 'parent.settings' or 'root.settings' that would be one work around. Hmm. |
I'll need to look at the helper again to see what's happening to the context, but this should be a relatively easy thing to fix. also related: assemble/assemble-handlebars#18 |
I just had the same problem as jfroom described. The handler works but the root data is not available. I did you figure something out? Also I would like to use translations in that partial (using this https://github.com/assemble/assemble-middleware-i18n), but I get an error message that "The language parameter is not defined" |
How to implement this with assemble.io? nav.hbs <ul class="nav">
<li{{#if active "home"}} class="active"{{/if}}><a href="/">Home</a></li>
<li{{#if active "about"}} class="active"{{/if}}><a href="/about">About</a></li>
</ul> index.hbs ...
<section class="page-home">
{{> nav active: "home" }}
</section>
<section class="page-about">
{{> nav active: "about" }}
</section>
... |
How about the ability to pass to a partial a reference to a json file that is in your data folder. We have a scenario where we want to share a partial between a styleguide and our actual application with different data. However, we are unable to do so unless we use YAML which feels kind of dirty adding the data in the page. Some times there is a lot of data, so we don't want to have to scroll the page to get to the actual markup. An ExampleWe have a template inside our application which includes a partial named navigation which in turn references app-navigation.json app-template.hbs
but then we also want to use the same partial but with slightly different data in the styleguide. We'd want to do something like this: styleguide-template.hbs
Both partials would populate themselves with the different [context]-navigation.json which sits inside the data folder. Is this currently possible? |
@owzzz yes, that's possible. You can create another |
So the above way of including a specific json is correct?
If not, how do you "pass any object into the partial"? Could you give me an example of how I'd do this? |
That's the correct way. |
Perfect, will try this out. Thanks. |
This didn't seem to work for me, how would you reference the data inside the template? I tried
but it did not output anything. |
What's the data in the If {
"title": "This is the title"
} Then inside the <h1>{{title}}</h1> |
This is the data structure:
This has worked for me
Now I am trying to do something similar, but with an array of data.
This returns the following error:
When I change the data to:
This will work:
Is there any way to get around this without having to add a sub-key "content" to the data? |
SOLVED
Will allow the array data to be passed by index So if you do not want to loop through the array with an {{#each array}}, you could do:
|
that's great! thanks for sharing the solution here! |
Out of interest, is it possible to have nested partials with each partial needing different data to populate them. Layout
Page Partial
I cannot seem to get this to work, I'm wondering if it only works with one data context. |
Yes... but, it can be a little tricky because of how handlebars manages context. your best bet is to look for handlebars documentation on the |
Thanks, will investigate.. |
Another useful function:
This allows passing has options:
|
@tuxsudo yeah that's nice and simple, thanks for sharing it! |
assemble v0.1.6.2
<button class="{{modifier}}">
{{text}}
</button>
{{> btn-basic modifier="btn btn-danger btn-lg" text="click me"}}
<button class="btn btn-danger btn-lg">
click me
</button> |
@onokumus this is a good question for stackoverflow, fwiw it's more of a handlebars questions |
@onokumus is it possible to set default options with this method? If so, how? |
<button class="btn {{#if modifier}}{{modifier}}{{else}}btn-default{{/if}}">
{{text}}
</button> {{> btn-basic text="button 1"}}
{{> btn-basic modifier="btn-danger btn-lg" text="button 2"}}
<button class="btn btn-default">
button 1
</button>
<button class="btn btn-danger btn-lg">
button 2
</button> |
@onokumus thank you so much, great solution! |
In ERB, I can do it like this:
I know I can pass data to an Assemble partial if it is already defined, e.g:
But can I define the data inline?
The text was updated successfully, but these errors were encountered: