0

I have DocPad documents that look like this:

---
categories: [{slug: ""}, {slug: ""}, ...]
---

Document content.

How can I query all documents which have a predefined slug value in the meta.category array?

Havvy
  • 1,471
  • 14
  • 27
Ashnur
  • 366
  • 3
  • 20

3 Answers3

3

There's a few ways we can go about this.

Via a Template Helper and Query Engine's setFilter

https://gist.github.com/4556245

The most immediate way is via a getDocumentsWithCategory template helper that utilises Query Engine's setFilter call that allows us to specify a custom function (our filter) that will be executed against each model in the collection and based on it's boolean return value keep the model or remove it from the collection.

The downsides of this solution are:

  • We have to redefine our category information in each post
  • We have no immediate method of being able to get information about all the categories available to us

Via Template Helpers and the parseAfter event

https://gist.github.com/4555732

If we wanted to be able to get information on all the categories available to us, but still had the requirement of defining our categories every single time for each post, then we can use the parseAfter event to hook into the meta data for our documents, extract the categories out into a global categories object, and then update our document's categories with id references instead.

Downside is that we still have to have redundant category information.

Via Template Helpers and a global categories listing

https://gist.github.com/4555641

If we wanted to only define our category information once, and then just reference the categories ids within our posts, then this solution is most ideal.

balupton
  • 47,113
  • 32
  • 131
  • 182
1

I manage to create a "foo" collection for a given slug value "bar in docpad.coffee:

collections:
  foo: (database) ->
    database.findAllLive().setFilter("search", (model, value) ->
      categories = model.get('categories')
      return false unless Array.isArray categories
      for category in categories
        if (category.slug and category.slug == value)
          return true
      return false
    ).setSearchString("bar")

but when I try to create a helper function that returns a collection given the array meta ("categories"), the key ("slug") and value ("bar") of the object :

createCollection: (meta, key, value) ->
  result = @getDatabase().createLiveChildCollection()
    .setFilter("search2", (model, searchString) ->
      objects = model.get(meta)
      return false unless Array.isArray objects
      for object in objects
        if (object[key] and object[key] == searchString)
          return true
      return false
    ).setSearchString(value)

i get an empty collection when i try to call it.

Dharma
  • 118
  • 1
  • 7
  • This is interesting. I've been trying this, but got stuck because i missed the model.get method. I've been trying to create a helper function, so I've not even tried the static(?) collection version. What is different is that I only have to provide the `searchString` because for me the meta is always categories and the key is always slug. I will try to debug this and see if I can manage it working. I will report back anyhow. Thanks. – Ashnur Jan 16 '13 at 23:37
0

I don't have a drop in solution, but have you seen the source code for the blog of docpad's author? There are some examples of querying for the existence of a metadata object attribute. Hope that helps!

Corey
  • 5,133
  • 3
  • 23
  • 24
  • Yes, that is a query. My question though is not about existence of a metadata attribute. In my case the attribute is actually an unknown number of objects, and I am interested in their properties. – Ashnur Jan 16 '13 at 15:26