Content modelling - normalisation
Hi,
Is is possible to model a object hierarchy for content?
For example, say I am modelling a News Article and all News Articles have an author and we'd like to store the author's first name, surname and their base location. The same author may write many of these articles. Is there a way to select an author which has already been created instead of creating the same author details more than once?
Can I set up a widget on my creation\edit screens for News Articles to browse existing people records for selection?
Thanks, Lynn
If I understand correctly:
- You would like to store the author's first name, last name and base location in each article?
- Or you just want to reference the author?
In both case, here is something that can achieve this. It should a blog actually because it's a long, long answer, but it will be faster to write an answer here ;-).
- Have an
Author
document type. with author:first_name, etc. - (Create some authors anywhere you wish)
- In
NewsArticle
(or in an inherited schema), add theauthor_ref
field, which will hold the id of the relatedAuthor
document. If you plan to query theNewsArticle
on the author name, first name or location, then you must also add the corresponding fields (maybenewsarticle:author_first_name
,newsarticle:author_last_name
andnewsarticle:uthor_base_location
- In a
NewsArticle
creation layout, add a “Single Document Suggestion” widget and let all the properties with their default values except:- NXQL Query, enter:
SELECT * FROM Author WHERE author:last_name LIKE ?
- Possibly, for quick testing and with few authors, I also set “Minimum characters” to 0
- NXQL Query, enter:
So, at this step, you can test with:
- (update your Studio config on the server)
- Create some Author
- create one NewsArticle and use the single document suggestion document to select an author
Now, if you want to query NewsArticle
on author's first name or last name or both, you have to duplicate the values:
- Create a new Event Handler. Say “NewsArticle_AboutToCreate”
- Select the “About to Create” event
- Select
NewsArticle
as “Current document has one of the type” - Select “Mutable document” as “Current document is”
- Create a new chain, say “NewsArticle_AboutToCreate”
Here is this chain:
1. Fetch > Context Document(s)
2. Push & Pop > Push Document
3. Fetch > Document
value: @{Document["newsarticle:author_ref"])
4. Execution Context > Set Context Variable
name: firstName
value: @{Document["author:first_name"]}
5. Execution Context > Set Context Variable
name: lastName
value: @{Document["author:lasst_name"]}
6. Execution Context > Set Context Variable
name: baseLoc
value: @{Document["author:base_location"]}
7. Push & Pop > Pop Document
8. Document > Update properties
properties: newsarticle:author_first_name=@{firstName}
newsarticle:author_last_name=@{lastName}
newsarticle:author_base_location=@{baseLoc}
save: UNCHECKED
Some explanations on the lines:
- Line #1: We need to Push/Pop the original document, because we are going to cvhange the context document when getting the
Author
- Line #2: The query on
Author
uses the id stored by the user when selecting an author via the suggestion widget - Lines #5-7: We store the values of
Author
in context variables, that will be used when saving these value in theNewsArticle
- Line 7: We make original
NewsArticle
the current context document - Line #8: And update it's field
- It is very important to leave the “Save” box unchecked, because this chain is called in the context of an “About to create” event. It means nuxeo will save the document after the call, and forcing it to save it “now” will lead to the hell of erros in server.log :-)
Now, you can also query on articles based on the author. Either via it's ref. or, if you build a custom “Faceted search” for example, by using the fields (news article:author_last_name
etc.), or via NXQL (SELECT * FROM Document WHERE dcm:primaryType = "NewsArticle" AND news article:author_last_name = "TheAuthorLastName"
), or. etc.