[contentbox 1.6.0] Utilizing the contentStore....

I think that’s the right version. I downloaded it just a few days ago.

Are there any good examples of how to use the ContentStore? There’s a lot of documentation, but it’s just straight class info (javadocs style), which I can get by digging into the code or dumping the objects. (Good stuff, don’t take that wrong.)

Let’s say I have a Coldbox view, a normal one. But I want to pull a named ContentStore item. So far I’ve been able to get a ContentStore component from the ContentService@cb. But while it seems to have some stuff in it, there’s things I can’t seem to find. Like “getRenderedContent()” returns nothing. The renderContent (not a function, not sure what it is) doesn’t have/do anything. In addition, when I call things like getAuthorName() or even look in the getMemento() values, there isn’t one. Yet the admin-ui seems to show who created the store item. How do I get the values of the custom fields added to the item?

So…I’m used to Coldbox documentation. There’s probably 75% coverage in Luis’s “get funky this, try that to get funkier” type documentation and examples. But I’m just not finding what I seem to need for ContentBox. The one area I did stumble on had a lot of “coming soon” type language.

Please help…wanting to use ContentBox for “content storage”, but not necessarily for managing full pages.

Thanks, - WB

The ContentStore was recently renamed, dont recall from which version.

Basically it is just a collection of Content, that can be included via widgets or other means into your pages or entries.

Hi Will–

We use the ContentStore a ton on the http://www.intothebox.org/ site to handle speaker details, session information, sponsors, etc.

In this particular example, we are using it like Andrew suggested, as a widget. So for example, there is a “speakers” widget which grabs all the speakers (they’re organized by categories, but that could be by any criteria), loops over them and creates html based on their data. The session list is almost identical, just a different collection of ContentStore items.

We are using both the regular “content” section as well as the custom fields. To get at these custom fields is pretty straightforward. Each content item (page, entry, contentstore) has a customFields property, so to get all the custom fields as an array of objects, you can simply do:

myContentStoreItem.getCustomFields(); → Array of CustomField objects

Of course, if you don’t need to deal with the custom fields as objects, you can also call the getCustomFieldsAsStruct:

myContentStoreItem.getCustomFieldsAsStruct(); → ColdFusion struct

This will give you a collection of key/value pairs for all of the custom fields for the given content item.

Here’s a stripped down example:

// array of session data
var sessions = [];
// get content store items by category
var sessionData = contentStoreService.findPublishedContent( category=“Schedule” );
// loop over results
for( var item in sessionData.content ) {
// get root details that we care about
var data = {
“title” = item.getTitle(),
“content” = item.getContent(),
“contentID” = item.getContentID(),
“slug” = item.getSlug()
};
// check that there are custom fields first
if( item.hasCustomField() ) {
// get custom field data as a struct and append it to our data
var custom = item.getCustomFieldsAsStruct();
structAppend( data, custom );
}
// add details to our array; now we have a nice array of structs to use however
arrayAppend( sessions, data );
}

Obviously, this is just a simple example and doesn’t cover the numerous ways that you can interact with the ContentStore. For example, I could have bypassed that process above and just done item.getMemento() to retrieve a flattened representation of the entire entity (including custom fields). In this example, I didn’t do that because I only wanted very particular things (and wanted to keep it trim for use in AJAX requests). However, it’s another option.

Please post back if you have additional questions.

Also, sometime in the near future we will be doing a ContentBox connection focused specifically on how we built the http://www.intothebox.org/ site, so keep an eye out for that.

Good luck!

"Exist": that's great for examples. Will be trying out your suggestions shortly.

Okay, so here’s where I was stumbling. And I can see my mistake, but not sure how to handle it. In the ContentBox admin, I create a content store item of ‘test-content’. I save, I publish. I then run this [partial] code snippet in my regular view:

<cfset oCS = getModel(‘ContentStoreService@cb’) />
<cfset oPC = oCS.findBySlug(‘test-content’) />

I get an item, no problem. Now…I go back into the admin, I edit the content, essentially add a new version. I hit “Save”. I do not hit “Publish”. Uh, oh. Now line 3 above breaks. I get why, though. It’s not published, so no date. What is the correct way to get the ‘test-content’ item, whatever the last published version is? Do I have to manually loop through the versions of the item trying to find the most recent published version?

If my editor goes in, makes changes to the item and saves, but isn’t ready to publish (or more likely doesn’t remember to hit the dang Publish button), I don’t want my usage of the item to break. I just want the most recent an d best (published) version available.

E/D: Can you assist with this question? You seem to have some good experience working with ContentBox ContentStore. (Luis: If you’re seeing this…go write some of that great documentaion you do so well! I’m sure it’ll be “funky flavored”.)

Will, the best thing to do is to wrap an isPublished around it.

oCS = getModel(‘ContentStoreService@cb’) ;
oPC = oCS.findBySlug(‘test-content’) ;
if(opc.isPublished()) {
stData.publishDateDisplay = oPC.getDisplayPublishedDate() ;

}

As simple as 123.

Was just flipping back to email to send additional findings. Actually, it seems that oPC.isLoaded() is right…seems to serve the same purpose. I don’t think I have an isPublished() function there. And you’re right, that will let me know whether I can show it or not. What that test doesn’t do is get me the last published version, if available.

I tried this:

<cfset versions = oPC.getContentVersionService().findRelatedVersions(ContentID = oPC.getContentID()) />

Now, that works great if the current state is a published state. If the current version being pulled from findBySlug() is not published, then getContentID() returns a NULL! OMG. I can’t even go look to FIND the latest version. Is this a bug? I know it has a content ID. But findBySlug() doesn’t populate it unless it’s published?

Luis, Brad or Joel will have to pipe in here as the work flow for all this is changing and something that has been requested already.

However if you follow the parent / child relationship, contentStoreService extends contentStore which in turn extends baseContent, which has the method isPublished()

So yes it is very much there, if it wasn’t then certain parts of ContentBox would not work.

<cfset oCS = getModel(‘ContentStoreService@cb’) />
<cfset oPC = oCS.findBySlug(‘test-content’) />

Error Messages: component [ContentStore] has no function with name [isPublished]

Sorry my bad, I was looking at it wrong.

Try this instead.

ocs.findbySlug(‘test-content’, true);

Then check to see if the date field is null. This will return the object whether it is published or not, if the content has only been saved then the date should be empty or null.

Nope, same thing. FYI, version (according to CB admin) is: 1.6.0.00037

<cfset oCS = getModel('ContentStoreService@cb') />
<cfset oPC = oCS.findBySlug(slug='test-content', showUnpublished=true) />
<cfdump var="#oPC.isPublished()#" />
*Error Messages:* component [ContentStore] has no function with name
[isPublished]

However, I did just stumble on the function isContentPublished(). Now
*that* one works. I get a false, though. I'm currently in the process of
trying to loop through the versions manually and find the right damn one
that has been published.

I'll report back.

I should've done this HOURS ago. I looked at the database. This makes
MUCH more sense. Yoda's "Do or do not. There is no try" has a corollary
to ContentBox. "There is no last published version, there is only
published or not published." On the ContentVersions, there's an
"isActive", but that's almost always going to be the last version, unless
you're jacking with rollbacks and such.

Clearly, if I want what I want here, I'm going to have to completely extend
this to my own stuff. I'll have to tap into the interception points or
something and try to capture and store the content from any publishing
actions. Then, when retrieving the ContentStore item, if
isPublished=false, I can go look in my own tables for the last published
version, if it exists.

Thanks for y'all's help, guys. Good to know you're out there supporting
the community.

- WB

FYI, this seems to boil down to the fact that you cannot have a “Saved” “Work in Progress” version of your content. As a CMS, you’ll simply have to pull all your HTML out into some other editor and edit, save, edit, save. When you’re done, you go replace the content in ContentBox. This would be a really needed functionality change, I would think.

Again, thanks gang!

no, you will need to remove the isPublished() as you are right it doesn’t exist.

A simple isNull() on the datefield should be sufficient.

The code I demonstrated using getDisplayPublishedDate() was just to illustrate the issue I was having.

The end goal here is to get the most recently published content for a given ContentStore item.

Now I’m trying so solve how to get the interception point in Coldbox to be accessible from my outer app. How to get it to “bubble up”, if you will.

No I am talking about this post you made, you still have the isPublished() when you should be checking the datefield on the entities date property.

Andrew, is there some reason I shouldn’t use the isContentPublished() field? Again, not really looking for the date so much.

no, sorry I was going by your earlier post where you just had isPublished with the error again. It sounds like you have gone past that now.

As for your question, no there is not. It does exactly the checks you need to do.

Will

Did you see the apidocs for the content store? Basically find by slug is a convenience method for published only items. Therefore you will never see unpublished items with it.

There are more methods you can use to get content site items no matter what state they are on which includes all of the base orm methods as well

Find by slug has a second argument called show unpublished.

Yah, I just spent the past 8 hours writing a new system. (Well, part of that 10 hours was realizing I couldn’t do what I needed to do.)

I now tap into the post save interception point. If the Content item is published, I copy it to my own table. If not, I ignore the interception. Then I pull from my table by slug.