docpad / docpad

Empower your website frontends with layouts, meta-data, pre-processors (markdown, jade, coffeescript, etc.), partials, skeletons, file watching, querying, and an amazing plugin system. DocPad will streamline your web development process allowing you to craft powerful static sites quicker than ever before.
https://docpad.bevry.me
Other
3.06k stars 243 forks source link

Calculating meta-data properties #594

Closed 0xgeert closed 11 years ago

0xgeert commented 11 years ago

I want to be able to calculate certain meta-data properties based on the values of other meta-data properties and/or values set in docpad.coffee / the environment.

I know the docpad.coffee part is possible. (I've read about it on stackoverflow today but can't seem to find it now) . However I'm particularly interested in calculating meta-data properties based on other meta-data properties.

E.g: when an explicit 'url' property is not defined I want to set it based on the sluggified 'title' property if that exists. I tried to quickly hack this using the renderBefore event, which I thought was appropriate but to no avail. (I'm more a javacsript than coffeescript guey so forgive the syntax clashes.. )

   renderBefore: (opts,next) -> 
        col = opts.collection
        col.models.forEach (m) -> 
            attribs = m.meta.attributes
            if(!attribs.url && attribs.title && attribs.layout.trim()=="post")
                attribs.url = "/posts/" + attribs.title.replace(/\ /g,'-')
                console.log attribs.url
        next()

Is this (or something close this this since it's obvisouly not working :), the correct way of doing this, or is there other more robust (declarative?) way to define calculated meta data properties?

BTW: hope you don't mind me flooding the issuelist. Rest assured it's a good thing. I'm pretty excited about Docpad :)

greduan commented 11 years ago

You mean something similar to this? https://github.com/Greduan/eduantech.docpad/blob/master/docpad.coffee#L29-L34

0xgeert commented 11 years ago

ha cool. yes indeed that's half of the equation. The other half would be to call the fictional getPreparedUrl somewhere and assign it to the meta-data property automatically if that isn't explicitly set already.

greduan commented 11 years ago

Well I think that other part would be found here: https://github.com/Greduan/eduantech.docpad/blob/master/docpad.coffee#L42-L46

Now if I understood what you need correctly, you would just need to put these together and get what you need no?

0xgeert commented 11 years ago

Damn I missed that :) Yup it seems trivial now thanks. Giving this a try now.

0xgeert commented 11 years ago

Great working. Thanks @Greduan !

  posts: (database) ->
        database.findAllLive({relativeOutDirPath: 'posts'}, [date:-1]).on 'add', (model) ->
            t = model.get('title')
            if(t)
                url = "/posts/"  + t.replace(/\ /g,'-')
                model.addUrl(url).setMetaDefaults({url:url})
            model.setMetaDefaults({layout:'post'})
0xgeert commented 11 years ago

To also cover the case of changing titles:

     # NOTE: events from http://documentcloud.github.io/backbone/#Collection
    posts: (database) ->
        database.findAllLive({relativeOutDirPath: 'posts'}, [date:-1]).on 'add change:title', (model) ->
            t = model.get('title')
            if(t)
                url = "/posts/"  + t.replace(/\ /g,'-')
                model.addUrl(url).setMetaDefaults({url:url})
            model.setMetaDefaults({layout:'post'})
greduan commented 11 years ago

Glad I was able to help. :)

Also thanks for that code, gives me an idea for something in my website. :)

0xgeert commented 11 years ago

@Greduan you may be interested in the updated version :)

        .on 'add change:title', (model) ->
            t = model.get('title')
            if(t)
                url = "/posts/"  + t.replace(/\ /g,'-')

                explicit_url = model.getMeta().get("url")
                if explicit_url
                    model.addUrl(url)
                else
                    model.setUrl(url).setMetaDefaults(url:url)
greduan commented 11 years ago

Awesome! Thanks!

Whenever I get to using it or something similar I'll be sure to tell you. :)