Closed hariadi closed 10 years ago
Related: #22
this is possible with custom replacement patterns I think. See:
Haha. I still don't get the right config using custom replacement patterns/structure
Here example file structure I have:
.
└── _posts
├── 2013-10-11-foo.md
├── 2013-12-31-last-year.md
├── 2014-01-01-new-year.md
└── 2014-02-12-bar.md
and we can make Assemble to force handlebars to recognize .md
files as templates.
blog: {
options: {
engine: 'handlebars',
permalinks: {
structure: 'basename/index:ext',
}
},
files: {
'<%= config.dest %>/blog/': ['_posts/*.md']
}
}
result in
_site/blog/2013-10-11-foo/index.html
_site/blog/2013-12-31-last-year/index.html
_site/blog/2014-01-01-new-year/index.html
_site/blog/2014-02-12-bar/index.html
Do you have idea how to result in:
_site/blog/foo/index.html
_site/blog/last-year/index.html
_site/blog/new-year/index.html
_site/blog/bar/index.html
note that page.basename
and page.slug
also change to:
foo
last-year
new-year
bar/index
and page.data.date
property become date object from filename replacement.
Maybe add option filedate
like this (filedate name look weird):
if(options.filedate === true) {
page.basename = page.slug = page.basename.replace(/^(\d+)-(\d+)-(\d+)-?/, function (a, y, m, d) {
page.data.date = (page.data.date) ? page.data.date : new Date([y,m,d].join('-'));
return [].join('/');
});
}
So we get new page.basename
and page.slug
property. Also page.data.date
available for plugins/helpers.
@hariadi did you try adding your filedate
thing as a custom pattern? Technically, the pattern is just a regex so you should be able to do that and you could pass in a function as the replacement...
options: {
permalinks: {
patterns: [
{
pattern: /^(\d+)-(\d+)-(\d+)-?/,
replacement: function (a, y, m, d) {
page.data.date = (page.data.date) ? page.data.date : new Date([y,m,d].join('-'));
return [].join('/');
}
}
]
}
}
After typing that out, I'm not sure how to get access to page.data.date
inside the replacement function. We were talking about this type of thing today and how we can make this work in our strings library.
exactly what I was thinking @doowb
I'm not sure how to get access to page.data.date inside the replacement function.
I think if it's on the context, it should be usable this way. I'm pretty sure the tests show data from YFM being used with replacement patterns like this. @hariadi if that doesn't work I'd consider it a bug.
Thanks @doowb, @jonschlinkert! Tried that but doesn't work:
patterns: [
{
pattern: /^(\d+)-(\d+)-(\d+)-?/,
replacement: function (a, y, m, d) {
return [].join('/');
}
}
]
still resulting:
Running "assemble:blog" (assemble) task
Assembling _site/blog/2013-10-11-foo.html OK
Assembling _site/blog/2013-12-31-last-year.html OK
Assembling _site/blog/2014-01-01-new-year.html OK
Assembling _site/blog/2014-02-12-bar.html OK
>> 4 pages assembled.
Done, without errors.
Using code above I'm able to modify page.basename
, page.slug
and page.data.date
to make use of preset
for example :
permalinks: {
//structure: ':category',
preset: 'pretty',
filedate: true
}
@doowb for some reason this
doesn't return the context in replacement patterns. The other day I tried it and this
returned the actual regex replacement patterns and the page/yfm context. but for some reason it's not working in my current setup. permalinks are working, this is the only thing that isn't. I haven't looked at Strings yet
this
is returning the context used in Strings and for permalinks part of that context is from the page/yfm context. Other than that, the context is technically the regex patterns due to how everything is passed to frep. I'm not sure how to extract the regex into actual keys.
This might have to be changed up to work differently for permalinks (maybe remove the this
from strings and just bind it in permalinks)
I have confirmed that this already works. You need to use this.src
, since the context is available to the patterns, not just the src
.
Here is an example, given you have a filename like 2014-03-27-test-blah-something.md
, you can create a function like this:
var toPost = function(str) {
var path = require('path');
var name = path.basename(str, path.extname(str));
var re = /(\d{4})-(\d{2})-(\d{2})-(.+)/;
return name.replace(re, '$1/$2/$3/$4');
};
Then use it in the replacement patterns:
options: {
permalinks: {
structure: ':post/index.html',
patterns: [
{
pattern: ':post',
replacement: function() {
return toPost(this.src);
}
}
]
}
}
Resulting in: 2014/03/27/test-blah-something/index.html
I'm updating the docs for this. Cosing since I think it's resolved, but reopen if necessary.
actually, just remembered that there are other things in this pr we can use! @hariadi would you want to do a new pr with the fixtures etc, using the example I gave?
Parse a filename structure like this:
2014-02-11-foo.{hbs,md}
and convert it to something like this:dest/blog/2014/02/11/foo/index.html
(or depends onpreset
)Update
I'll attach commit to add filename replacement option with two test using
preset
andstructure
.When this option
true
, the date will be stripped from filename and then modifypage.basename
andpage.slug
to use replacement version.And then date strip from filename added to
page.data.date
property if it not exist in yfm data.