Content
Structure / Tree
As Cloudrexx is a native multilingual content management system, a website consists of just one content tree that is being used by all localized versions of it. The content tree consists of nodes (\Cx\Core\ContentManager\Model\Entity\Node
) which do determine the structure (branches) of the site. As only one tree is being used, the site structure on every locale is identical. Each node contains a set of localized pages (\Cx\Core\ContentManager\Model\Entity\Page
).
Note
There exists a special node called root node. It has no content (meaning no assigned pages), it's just the invisible root of the node tree.
Pages
Each node can contain a page for every set up locale. A page's behavior is defined by its type. Available types are as follows:
Name (GUI) | Name (CODE) | Description | Comment |
---|---|---|---|
Content Page | CONTENT | A normal content page | |
Redirect | REDIRECTION | A redirection to another node or website | |
Application | APPLICATION | A module page | |
Use Fallback Version | FALLBACK | A page using the content of another language | |
ALIAS | An alias for a page or website | This is a special case. Alias pages are not shown in Content Manager (more information at Find an alias). |
Status Icons
Depending on the page's type and its publication state, it will be displayed in the Content Manager by a specific icon:
Slugs / URLs
Definition: a slug is a part of an URL: https://www.example.com/thisIsASlug/andAnotherSlug
URLs are built by traversing the node tree from the root down to the desired page. For all parent nodes we visit, the slug of the assigned page in the same language as the target page is appended to the url.
Example (see figure):
- Assume the german Page assigned to node B has the slug 'Level1'
- Assume the german Page assigned to node A has the slug 'Level2a'
- Assume the german Page assigned to node C has the slug 'Level2b'
The following URLs would then be valid:
- Node B is available via https://example.com/Level1
- Node A is available via https://example.com/Level1/Level2a
- Node C is available via https://example.com/Level1/Level2b
Every page stores it's slug name. The slug is automatically set when first giving the page a title.
Nodes
Node-URL Notation
Areas of application
- The MediaBrowser uses the Node-URL Notation to link to a internal webpage
- Internal redirections (page type: REDIRECTION) should use the Node-URL Notation
Schema definition
A node URL can be represented by the following placeholder notation:
func_url(<componentName>, <cmd|nodeId>, <urlArgs>, <anchor>, <lang>)
All arguments except <componentName>
are optional.
Part | Description |
---|---|
<componentName> |
Name of the component to get URL to. Empty for an URL to a node. |
<cmd|nodeId> |
Additional CMD of the page's application. Node ID for empty component name. |
<urlArgs> |
Query string to append to the URL. |
<anchor> |
URL anchor to append to the URL. |
<lang> |
A specific language version of the page. |
The old placeholder format is still valid but its use deprecated. It is
transparently rewritten to the new one by the Legacy component.
Here's the old notation:
[[NODE_(<node_id>|<module>[_<cmd>])[_<lang_id>]]]
Part | Description |
---|---|
<node_id> |
ID of the page's node |
<module> |
name of the page's application |
<cmd> |
additional CMD of the page's application |
<lang_id> |
a specific language version of the page |
Resolving the Node-URL Notation
Normally it's better to store the Node-URL placeholder instead of an URL and parse it when generating the output, since the placeholder is more flexible!
Use \Cx\Core\Routing\NodePlaceholder
to convert from and to placeholder format. See the API documentation for further details.
Examples
Node Placeholder | Description |
---|---|
func_url("", 2) |
URL pointing to the page of the current (requested) locale of node having ID 2 |
func_url("Shop") |
URL pointing to the application Shop |
func_url("Shop", "cart") |
URL pointing to the application Shop that uses the area (cmd ) cart (i.e ?section=Shop&cmd=cart ) |
func_url("Shop", "cart", "", "", 2) |
same as above, but localized version of the page having ID 2 |
Model
Concept of owning or inverse side of a relation
In the context of the Doctrine the page model is owning side and the node the inverse side.
Database Structure
Warning
This diagram is outdated.
Class diagram
Warning
This diagram is outdated.
Integration
Find Pages
Find the actual page
Find a single page
Find a list of pages
Find an alias
Aliases have the language id 0 which is not assigned to the active languages. For this reason you can't find them by passing the criteria "'lang' => 0". But you have the possibility to pass the boolean "true" as second parameter of "findOneBy()" which causes that the page repository also searches in the inactive languages.
Move an existing node
Creating a Page
Delete a single page
Delete a node with all its pages and subnodes
Translating a Page
Every page with a language L must have all of it's parent pages available in translation to language L. If that is not the case, the page is lost and invisible. Remember how URLs are built - we can't build an URL for a page where we do not find the slugs in language L for the parent pages.
Example
Look at the figure again. If we want to translate the german page on node A to english, we also need to insert a translated page on node B. As this is a common task, the PageRepository provides a method for translating a page in language X to language Y and automatically inserting the needed parent pages. The slugs of the translated parent pages are taken from the pages in language X.