# Content Groups in Layout Descriptor
This article details the customization options offered by the layout descriptor for content groups. The Content Group Layout extends the default Layout and Layout Attributes and adds fields to easily configure them.
There are specific core mixins available to style a content group.
# Declare a Content Group
A content group is always declared with the name balcon
instead of a layout name:
"layouts": [
{
"name": "balcon",
...
}
]
Balcon?
Balcon is the deprecated name for Content Groups. You will find it widely used in the codebase.
There are 2 ways to declare a Content Group's layout:
# balconLayout
balconLayout
lets you reuse Content Groups already defined in Marfeel codebase.
Content group templates are stored in a special balcon
folder, in Marfeel's default theme (opens new window). For example:
themes/default/balcon/balcon_photo_slider.jsp
To reference a template, drop the balcon_
prefix:
"layouts": [
{
"name": "balcon",
"attr": {
"count": 4,
"balconLayout": "photo_slider"
}
}
]
Refer to the Content Groups catalog, to know what is available.
Dependencies
The layouts that a predefined content group depends on (here photo/photo
and photo/photo_slider
) must be added to an extraLayouts.json
file.
# layouts
layouts
lets you define custom Content Groups, where you specifically define each layout it will use:
"layouts": [
{
"name": "balcon",
"attr": {
"layouts": ["newspaper/thumb", "photo/photo"],
"count": 2
}
}
]
In its simplest form, layouts
is an array of strings, containing all the layouts used for the content group. You can combine any existing layout into a Content Group.
layouts
can also become more complex, just like the main layouts
object of the content group:
"layouts": [
{
"name": "balcon",
"attr": {
"layouts": [
"newspaper/thumb",
{
"name": "photo/photo_grid_2",
"attr": {
"count": 2
}
}
],
"count": 3
},
}
]
# Fill a Content Group with articles
Content groups are available with any ripper (WhiteCollar, JSOUP...), but it is optimized for the WhiteCollar.
# Top-level section
For all rippers, you can select which articles fit in a content group with the section
property.
Use the section name
value from the definition.json
file to get articles from that section fed into a Content Group:
"layouts": [
{
"name": "balcon",
"section" : "sports",
"attr": {
"count": 4,
"pocket" : {
"balconLayout": "slider",
"title" : "Sports news"
}
}
}
]
# section
inside pocket
With the MarfeelPressRipper, sections that are not in definition.json
are also available. Declare the section name nested inside the pocket
object:
MarfeelPressRipper uses the value to find the articles associated with this category or tag as fallback.
It is equivalent to the WhiteCollar key
method, and used the same way in the backend which is why it requires a key
property, identical to the section
value:
"layouts": [
{
"name": "balcon",
"key" : "sports",
"attr": {
"count": 4,
"pocket" : {
"balconLayout": "slider",
"section" : "sports",
"title" : "Sports news"
}
}
}
]
# Top-level key
The WhiteCollar can group items by key
. Use those groups in the layout descriptor with the corresponding key
property:
{
"name": "newspaper/thumb_card",
"key": "most-read"
}
# key
operations: startsWith
You can prefix the value by startsWith:
. It retrieves all the groups which key has a common prefix.
For example, this selection will retrieve all the groups which key starts with news-
, such as news-sports
, news-movies
, news-politics
...:
"layouts": [
{
"name": "balcon",
"key": "startsWith:news-",
"attr": {
"balconLayout": "photo_slider"
}
}
]
With this feature, the layout is repeated for each group of items separately. In this case, we obtain 3 different sliders.
The order of rendering between content groups in the same startsWith
block is defined by the items extraction.
AdDealer and `startsWith`
You can’t manually control ads display between content groups using the startsWith
feature.
The only way to render an ad between those content groups is by activating the adDealerMosaic
flag in features.json
.
WhiteCollar extensiblity
With this feature, when a tenant adds or modifies an existing content group on their website, we only need to update the item selection in the WhiteCollar. The rendering will work out-of-the-box for the new selection.
# count
This attribute is valid for any layout but is mandatory for content group. It is particularly important for layouts where the amount of items is not fixed, such as a slider:
{
"name" : "balcon",
"key": "people",
"attr": {
"count" : 8
},
"pocket": {
"balconLayout": "slider"
}
}
# Content Group title
A Content Group can have a visible header if one of these conditions is met:
- A
section
is defined: the Content Group header will be the section's title (as defined indefinition.json
).
"layouts": [
{
"name": "balcon",
"section": "someSection"
...
}
]
- The
pocket
contains atitle
property: the Content Group header will use it.
"layouts": [
{
"name": "balcon",
...
"attr": {
"pocket": {
"title": "Example title"
}
}
}
]
Hide the Content Group header with the showTitle
attribute if it is undesirable:
"layouts": [
{
"name": "balcon",
...
"attr": {
"showTitle": false
...
}
}
]
# "Ranking" Content Groups
Some content groups are of type "ranking". Those layouts have two optional features, to configure in the pocket
:
disableCounter
: boolean. Default isfalse
. Removes the counter number from the layout.showRankingAd
: boolean. Default isfalse
. Adds an ad after the second article.
{
"layouts": [{
"name": "newspaper/ranking",
"attr": {
"count": 12
},
"pocket": {
"disableCounter": true,
"showRankingAd": true
}
}]
}
# Use an image
The logo
property can be defined for any Content Group, replacing the title or supporting it.
The logo can be a svg
, png
or jpg
.
- Logo with a title:
{
...,
"pocket": {
"title": "Group title",
"img": "https://example.com/files/example-logo.svg",
}
}
- Logo instead of a title:
Make sure the title
property is a blank space:
{
...,
"pocket": {
"title": " ",
"img": "https://example.com/files/example-logo.svg",
}
}
TIP
UX team usually prepares those logos, if they don’t already have an appropriate size on the tenant’s website.
# Additional class
Optional. You can add a className
property inside the attr
, which will be appended to the Content Group root in Marfeel:
{
"name": "balcon",
"attr": {
"title": "Group Title",
"balconLayout": "slider",
"className": "mrfdocs-group"
}
}
Result in the Marfeel version:
<section class="mrf-balcones slider mrfdocs-group">
...
</section>
# ExtraLayouts
When using content groups, extraLayouts.s.json
and extraLayouts.xl.json
files must be created in LayoutDescriptor
folder.
It contains a layouts
array, holding a list of layouts, for example:
extraLayouts.s.json
{
"layouts": [
"photo/photo",
"photo/photo_slider",
"newspaper/pill"
]
}
extraLayouts.xl.json
{
"layouts": [
"photo/photo_sky300",
"photo/photo_slider",
"newspaper/pill_sky300"
]
}
The layouts can be declared in any order, and won't display anywhere. Content groups are usually importing several existing layouts, which have their own CSS. However, we must declare those dependencies for the build system to include those additional CSS files.
It is not necessary to include this file if no content group has hidden dependencies.
Some widely-used content groups benefit from an ad-hoc solution, and it is not necessary to add anything if you use them:
newspaper/text_slider
newspaper/opinion_slider
sliders/tag-slider
sliders/pill-slider
← Lateral Menu Iframe →