Bag (OrchardCore.Flows)¶
The BagPart is part of the Flows module, and is a content part that can contain multiple types of content items directly within it.
They are stored in the database as one single document, which makes them very powerful.
The BagPart shares a lot of similarities with the FlowPart in design, the difference is that with the BagPart you are able to specify exactly which content types can be contained within it.
This is done through the Settings for the BagPart.
BagParts may also be added to a Content Type Definition as a NamedPart. This allows one container item to have multiple BagParts.
An example of this can be found in TheAgencyTheme where four Named BagParts are used.
- Services
- Portfolio
- About
- Team
Blocks Editor¶
The blocks editor provides an alternative editor for BagPart that uses a modal-based content type picker instead of the standard dropdown menu. Content types displayed in the picker can be organised with categories and thumbnails. See Content Type Settings for Block Pickers for configuration details.
Enabling the Blocks Editor¶
To enable the blocks editor for a BagPart, set the Editor option to Blocks in the content type definition.
This can be done in the admin UI:
- Navigate to Content Definition → Content Types
- Edit the content type containing the BagPart
- Click Edit on the BagPart
- Set the Editor field to
Blocks
Or programmatically using a migration:
_contentDefinitionManager.AlterTypeDefinition("MyContentType", type => type
.WithPart("BagPart", part => part
.WithEditor("Blocks")
)
);
Blocks Editor Settings¶
When the blocks editor is enabled for a BagPart, additional settings become available in the part editor options:
| Setting | Description |
|---|---|
| Add Button Text | Custom text for the "Add" button. Defaults to "Add Block". |
| Modal Title Text | Custom title for the content type picker modal. Defaults to "Select Block". |
Templating in a decoupled manner¶
When templating in a decoupled manner the content items are accessed directly through the name of the BagPart.
{% for service in Model.ContentItem.Content.Services.ContentItems %}
<h4 class="service-heading">{{ service.DisplayText }}</h4>
<p class="text-muted">{{ service.HtmlBodyPart.Html | raw }}</p>
{% endfor %}
@foreach (var item in Model.ContentItem.Content.Services.ContentItems)
{
<h4 class="service-heading">@item.DisplayText</h4>
<p class="text-muted">@Html.Raw(item.Content.HtmlBodyPart.Html)</p>
}
In this example Services is a Named BagPart.
Templating with Display Management¶
When templating with Liquid the shape_build_display filter is used on the contained items to build
the display shapes for the content items, then the shape_render filter is used to render these shapes.
When templating with Razor the IContentItemDisplayManager is used on the contained items to call BuildDisplayAsync
to build the display shapes for the content items, then DisplayAsync is used to render these shapes.
<section class="flow">
{% for item in Model.ContentItems %}
{{ item | shape_build_display: "Detail" | shape_render }}
{% endfor %}
</section>
@using OrchardCore.Flows.ViewModels
@model BagPartViewModel
@inject OrchardCore.ContentManagement.Display.IContentItemDisplayManager ContentItemDisplayManager
<section class="flow">
@foreach (var item in Model.BagPart.ContentItems)
{
var itemContent = await ContentItemDisplayManager.BuildDisplayAsync(item, Model.BuildPartDisplayContext.Updater, Model.Settings.DisplayType ?? "Detail", Model.BuildPartDisplayContext.GroupId);
@await DisplayAsync(itemContent)
}
</section>
Template Alternates¶
The BagPart supports standard alternates and for a Named BagPart, you can include the name of the part, in the alternate.
MyBag-BagPart.liquid
MyBag-MyNamedBagPart.liquid
In the first example we have an alternate specifying the Content Type MyBag and the BagPart.
In the second example we have an alternate for the Content Type MyBag, and the Named BagPart MyNamedBagPart
The templates and alternate names for the Content Items contained in a BagPart are the same as standard Content Items.
Note
More alternates are available. You can examine these using the ConsoleLog Razor Helper or console_log liquid filter.
Placement Differentiator¶
The name of a BagPart is used as the differentiator in placement.json
{
"BagPart": [
{
"differentiator": "MyNamedBagPart"
}
]
}