cliftonc / calipso

Calipso is a simple NodeJS content management system based on Express, Connect & Mongoose.
calip.so
1.7k stars 307 forks source link

How to access custom fields? #117

Open dethe opened 12 years ago

dethe commented 12 years ago

I've created my custom content by following the example at http://calip.so/first-pass-at-configurable-content-types.html and reading through the Form and Content modules. I'm having a bit of trouble figuring out how to access my custom fields in the view, though. I have an over-ridden body.html / body.js but the getBlock() method only seems to return the {content: "" } field. What is the recommended way to access other fields of the custom content?

cliftonc commented 12 years ago

You need to use the getContent helper, not get block when grabbing content - check out the calipso-site-theme from my repo, and you will see the examples of the github and blog landing pages.

getBlock is used to grab pre-rendered html from modules, that you can then just place into a view. If you use getContent, you can get access to the mongoose object directly, then use:

content.get('yourFieldName') will do the trick (or content.yourFieldname as well should work).

Let me know if you're still stuck.

Clifton

cliftonc commented 12 years ago

Just to clarify:

getContentList >> Lets you query to get a list of content (useful for pages like: http://calip.so/section/github, example: https://github.com/cliftonc/calipso-site-theme/blob/master/templates/githubLanding/body.js)

getContent >> Lets you get one piece of content based on its alias useful for pages like: http://calip.so, example: https://github.com/cliftonc/calipso-site-theme/blob/master/templates/home/body.js)

Clifton

dethe commented 12 years ago

Ah, I thought getContentList was for listing a user's content, not a single content object.

Thanks for the clarification.

--Dethe

On 2011-09-28, at 10:37 PM, Clifton Cunningham wrote:

You need to use the getContent helper, not get block when grabbing content - check out the calipso-site-theme from my repo, and you will see the examples of the github and blog landing pages.

getBlock is used to grab pre-rendered html from modules, that you can then just place into a view. If you use getContent, you can get access to the mongoose object directly, then use:

content.get('yourFieldName') will do the trick (or content.yourFieldname as well should work).

Let me know if you're still stuck.

Clifton

Reply to this email directly or view it on GitHub: https://github.com/cliftonc/calipso/issues/117#issuecomment-2234297

dethe commented 12 years ago

So here's the thing. I'm trying to show one item with multiple pieces of content. Displaying this by alias and tracing through what happens: in Content.js::showAliasedContent it retrieves the object from mongodb. Then, at some point before calling my over-ridden it seems to throw the object away. I can't find a path to it from req, res, or options. Is there a reason for this, or is it a bug, or am I missing something? The only paths I can see are to a) modify to the code to stash the object, possibly in the request, since the options seem to go missing at some point, b) strip the .html off of options.getPageId (which appears to not be a function, but a string with the alias appended with ".html") and then use the reconstituted alias to retrieve the object with a getContentList query, or c) other. I'm assuming there is an other, since a CMS has to actually be able to display content. What am I doing wrong?

dethe commented 12 years ago

This work-around got things working for me:

https://gist.github.com/1252291

I still don't understand why we retrieve the object from the DB, then throw it away and I have to retrieve it again later in the render. I realize I'm probably missing something really obvious here, but I have explored and traced through the code without figuring it out.

Also, is the alias stored anywhere? Having to parse the getPageId string doesn't seem right.

I did try using getContent() to retrieve a single object using the alias, but it seemed to return HTML for a missing object.

cliftonc commented 12 years ago

You're not missing anything obvious - it is still early days and the 'make it easy and intuitive' is still very much a work in progress!

The alias will be in req.moduleParams, but only in the context of the content module atm - it won't be there by the time you get to the theme. As all the modules are executed in parallel, and so effectively in their own scope, a lot of the processing is done just in the context of the module and not then aggregated (safely) somewhere (given that modules may overlap in defining params in a route) so you can access it in the theme layer.

So the crux of the problem is that the content functions all execute inside the content module, and from a theme you can only get access to either a) the rendered block, b) the helpers that let you go back to mongodb, or c) the ability to over-ride the show.html template renderer, but that isn't very scalable past 1-2 content types.

For me there are a few important things here:

Does that about sum it up?

ps. getContent should work (because I use it all the time) - but note that if it can't find the alias in MongoDB, it 'helpfully' provides a link so you can create it. Best to console.dir() the alias + returned object from the theme as something doesn't match up.

dethe commented 12 years ago

On 2011-09-29, at 10:11 PM, Clifton Cunningham wrote:

You're not missing anything obvious - it is still early days and the 'make it easy and intuitive' is still very much a work in progress!

OK, well I will stumble about and let you know what corners I crash into.

The alias will be in req.moduleParams, but only in the context of the content module atm - it won't be there by the time you get to the theme. As all the modules are executed in parallel, and so effectively in their own scope, a lot of the processing is done just in the context of the module and not then aggregated (safely) somewhere (given that modules may overlap in defining params in a route) so you can access it in the theme layer.

So the crux of the problem is that the content functions all execute inside the content module, and from a theme you can only get access to either a) the rendered block, b) the helpers that let you go back to mongodb, or c) the ability to over-ride the show.html template renderer, but that isn't very scalable past 1-2 content types.

Ah, I see. Makes more sense now.

For me there are a few important things here:

  • current approach isn't very intuitive, it needs to be clearer and make more sense as well as be better documented so the limitations of the parallel approach are clear or I just work around them
  • any params extracted from the request by modules should all be stored, aggregated and available to the theme layer via a helper (e.g. getParams)
  • we need to allow you to specify the template markup for both the landing page (list) and page (show) for a content type, from within the content type.

Does that about sum it up?

That would be lovely. I could make good progress with that much.

--Dethe

cliftonc commented 12 years ago

getParams is in devel, the second is a bit larger, so I will write up as a feature and add it to the issues list.

cliftonc commented 12 years ago

Hi, most of this is now accessible in the devel branch, if you're still interested (6 months is an awfully long time I know!) then let me know if you can take a look.