-
-
Notifications
You must be signed in to change notification settings - Fork 2
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
migration .0.4.42 to 0.7.0 each pages #8
Comments
This is the page i am currently migrating http://www.edc4it.com/blog/index.html. In Assemble 0.4.42 the following works (out of the box) For the category buttons (each blog has {{#each categories}}
<label class="btn btn-{{category}} ">
<input class="chkbx-filter" type="checkbox" autocomplete="off" value=".cat-{{category}}">{{category}}
</label>
{{/each}} To render to the blog tiles {{#each pages }}
{{#is data.published true}}
<a href="{{relative ../../page.dest this.dest}}" >
<div class="grid-item {{#each data.categories}} cat-{{this}} {{/each}}"
data-date="{{formatDate data.date '%Y%m%d'}}" data-categories="{categories}}">
<span class="title">{{data.title}}</span>
</div>
</a>
{{/is}}
{{/each}} I found some related issues |
kind of, but primarily it's just because the properties on the context object are no longer the same. the following might cast some perspective on all of the linked issues. (TLDR: depending on the type of "list" you want to generate with the How Assemble 0.6.0 is different than 0.4.x In grunt-assemble (assemble 0.4.x), we were adding both the context for the current The implication being that we needed to:
There were advantages to this, like making it easier to do simple things with pagination, use the In Assemble 0.6.0, we don't assume that this is always what the user wants or need, but it's still possible (and maybe easier in some ways). Regardless of how we approach the solution, to generate a list of pages (or posts, or widgets, etc), the entire "list" must be loaded first. Once that's done, we can easily render the list using helpers. If you're using However, this is easily solved by building up the list in the flush function of a plugin, or by not using ExampleTry something like the following in your /**
* Helper for showing the context in the console
*/
app.helper('log', console.log.bind(console));
/**
* Middleware
*
* Add the `pages` collection to `view.data`,
* which exposes it to the context for rendering
*/
app.preRender(/./, function(view, next) {
view.data.pages = app.views.pages;
next();
});
/**
* Task for rendering "site"
*/
app.task('site', function() {
app.pages('src/pages/**/*.hbs');
app.partials('src/partials/*.hbs');
app.layouts('src/layouts/*.hbs');
// use the `toStream` method instead of `src`
// so that all pages are available at render time
return app.toStream('pages')
.pipe(app.renderFile())
.pipe(extname())
.pipe(app.dest('_build'));
}); Layout: <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{ title }}</title>
</head>
<body>
{% body %}
{{> list }}
</body>
</html> Partial: {{#each pages}}
{{log .}}
{{@key}}
{{/each}} Inspecting the contextSince views are vinyl files, you'll need to inspect them to see what's available to use. To make this easier, you might also try adding a helper to see what's on the context: Example Create a helper, arbitrarily named app.helper('ctx', function(context) {
console.log(arguments);
console.log(context); // the object passed to the helper
console.log(context.hash); // hash arguments, like `foo="bar"`
console.log(this); // handlebars context
console.log(this.options); // assemble `options`
console.log(this.context); // context of the current "view"
console.log(this.app); // assemble instance
}); Then use the {{#each pages}}
{{ctx .}}
{{/each}} And try it outside the loop: {{ctx .}} |
Thanks for the excellent explanation. I was indeed fairly easy to push in collection into the view's data. The difficulty was mostly in creating the relative link to the page. The destination for the outer page has not yet been set when rendering the page ( // hack for now
module.exports = function(basedir){
return function(context){
return "/"+path.relative(basedir,context.path)
}
}; It works, but now have to enable permalinks and see if still works. I forgot i also have that obstacle: permalinks. (that then need to create and push the category collection into the page as well) Thanks again for your thorough explanation. |
try this (ironically I just created this, literally right before I read your message! lol): // somewhere on the assemble options, define a `dest`
app.option('dest', '_build');
// relative path helper
app.helper('relative', function(item) {
var view = this.context.view; // this is the "current" view being rendered
var from = rename(this.options.dest)(view);
var dest = rename(this.options.dest)(item);
return relative(from, dest);
});
// "rename" function
function rename(dest) {
return function(file) {
// return if dest is defined, so we don't calculate the
// dest path for a file more than once
if (file.dest) return file.dest;
var fp = path.join(dest || file.base, file.relative);
file.dest = fp.replace(path.extname(fp), '.html');
return file.dest;
};
} Also, add .pipe(app.renderFile('hbs')) Then define the following in your template: {{#each pages}}
<a href="{{relative .}}">{{data.title}}</a>
{{/each}} |
Thanks.. Could you not just use |
Meaning That won't work for two reasons:
This is why I'm using a custom rename function and intentionally avoiding updating any vinyl properties. You would see the following if you use
|
That explains why the "index" page was still referring to the template. But would this solution not conflict with gulp extname / permalinks / gulp rename? |
As long as the same destination path is generated in both places it should work. I don't use gulp-rename, but out of curiosity what permalinks solution are you using? |
Nothing yet i am trying to figure out assemble-permalinks. I was expecting i could just use that on my view collection. Working my way through the tests and example on that repo. (BTW one tests fails, i'll report it over there) |
sounds good, thx |
@doowb put that |
@rparree @jonschlinkert is referring to this... app.helper('posts', function(options) {
var list = this.app.list(this.app.views.posts);
return list.items.map(function(post) {
return options.fn(post.data);
}).join('\n');
}); I haven't completely tested it yet, but I think that will get you close to what you're looking for on your tiled posts page... <ul>
{{#posts}}
<li>{{title}}<li>
{{/posts}}
</ul> |
much better solution! but now you see multiple ways to do it :) |
That looks very clean, i'll give it a try tomorrow... Thanks guys! |
I've tried this approach but it does not work for me. The hbs {{#posts}}
{{title}}
{{/posts}} The helper: app.helper('posts', function(options) {
var list = this.app.list(this.app.views.blogs); // shows list {"options":{"/home/rparree/projec....
console.log("list", JSON.stringify(list.items)) // shows []
return list.items.map(function(post) {
return options.fn(post.data);;
}).join('\n');
}); The list has values, it's items not. |
BTW for reference...the list of catagories i've solved like this: {{#categories}}
{{category}}
{{/categories}} The helper "categories" : function(options) {
var cats = _.chain(this.app.views.blogs)
.values()
.map(function(v){return v.data.categories})
.flatten()
.uniq()
.value()
return cats.map(function(cat){
return options.fn({category : cat})
}).join('\n') I guess i can do something similar for an improved page list |
that's great! I'd love to see what you come up with for the page list too |
My '{{#each pages }}' no longer works. Guessing from the fact collections became first class citizens i tried creating a view collection:
I have tried many variations like
{{#each blog }}
etc. Also my{{#each categories}}
is not working.The text was updated successfully, but these errors were encountered: