Best way to use Block Settings?
# help-with-umbraco
p
I want to make use of the block settings to enable some basic styling for all blocks like: background color, spacing top & bottom, padding. Is there a way to make it available for all blocks and a simple way to update the code which makes it work for all blocks.cshtml?
d
Hey Pascal, composition document types are the way to do this. You'd create a composition document type, add all of the settings properties to it (bg colour, spacing options etc) then add that composition to all of your block document types.
p
But stil then i'll have to edit every single block to apply it to them? I thought of adding it to the items.cshtml with the block settings. But the problem i have now is that it wont show in the blockpreview plugin in the backoffice. For the frontend it works
d
Please take a look at UmBootstrap - I have examples of setting for background colour, opacity, images on layouts, areas and features It takes seconds to install
Copy code
dotnet new umbootstrap
https://umbootstrap.com/
d
On the front-end, it all depends on the detail, but if your block settings share a composition then there might be something you can do using Partials or View Components, or even Tag Helpers to render wrapper mark-up around the block mark-up so that your settings classes/attributes/etc are only in one place. I'm not sure about accessing settings properties in the BlockPreview package, unfortunately.
p
Thanks everyone for your responses! I'm doing it with the umbraco block preview plugin. My problem is now that it shows me in the frontend but not in the umbraco backoffice preview.
Copy code
C# 
@using Umbraco.Cms.Core.Models.Blocks
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<IEnumerable<BlockGridItem>>
@{
    if (Model?.Any() != true)
    {
        return;
    }
}

<div class="umb-block-grid__layout-container">
    @foreach (var item in Model)
    {
        var itemSettings = item.Settings as BlockSettings;
        var spaceTop = itemSettings?.SpaceTop ?? 0;
        var spaceBottom = itemSettings?.SpaceBottom ?? 0;
        var padding = itemSettings?.Padding ?? 0;

        <div
            class="umb-block-grid__layout-item"
            data-content-element-type-alias="@item.Content.ContentType.Alias"
            data-content-element-type-key="@item.Content.ContentType.Key"
            data-element-udi="@item.ContentUdi"
            data-col-span="@item.ColumnSpan"
            data-row-span="@item.RowSpan"
            style=" --umb-block-grid--item-column-span: @item.ColumnSpan; --umb-block-grid--item-row-span: @item.RowSpan; ">
            @{
                var partialViewName = "blockgrid/Components/" + item.Content.ContentType.Alias;
                try
                {
                    <div class="mt-@(spaceTop) mb-@(spaceBottom) p-@(padding)">
                        @await Html.PartialAsync(partialViewName, item)
                        
                    </div>
                }
                catch (InvalidOperationException)
                {
                    <p>
                        <strong>Could not render component of type: @(item.Content.ContentType.Alias)</strong>
                        <br/>
                        This likely happened because the partial view <em>@partialViewName</em> could not be found.
                    </p>
                }
            }
        </div>
    }
</div>
The div with the classes (spacetop, spacebottom) does it for the frontend. But i cannot see it in the backoffice.
d
In default.cshtml, items.cshtml, areas.cshtml and area.cshtml have you changed :
@await Html.GetBlockGridItemsHtmlAsync(Model)
to
@await Html.GetPreviewBlockGridItemsHtmlAsync(Model)
?
not sure if this is correct
The others i've got changed
d
Pretty much the same (sorry Items did not need the
GetPreviewBlockGridItemsHtmlAsync
) except I have a
@foreach (var item in Model)
Copy code
<div class="@(layout ? "layout-" : "feature-")items d-flex flex-column @(layout ? "gap-0" : "gap-3")">
@foreach (var item in Model)
{
    {
        var partialViewName = "blockgrid/Components/" + item.Content.ContentType.Alias;
        try
        {
            <!-- START - ITEM -->
            @await Html.PartialAsync(partialViewName, item)
            <!-- END - ITEM -->
        }
        catch (InvalidOperationException)
        {
            <p>
                <strong>Could not render component of type: @(item.Content.ContentType.Alias)</strong>
                <br />
                This likely happened because the partial view <em>@partialViewName</em> could not be found.
            </p>
        }
    }
}
</div>
p
@User hmmm any idea where i could build in the div with the margin and padding and still only have to do it in one file and not every block? And also see it in the backoffice preview?
d
Have you got Block Preview working?
p
no currently not, i think i have to move it ouside of the items.cshtml but i dont know where :/
to make it work in block preview @Dean Leigh
d
Have you installed a copy of UmBootstrap? I literally copied my code from default.cshtml, items.cshtml, areas.cshtml and area.cshtml files to another site and it worked first time.
p
@User Where did you implement your Settings? Did you also make it work in the items.cshtml or did you implement all the settings in every component for its own?
d
I created _Layout files for Layouts and Features then grabbed the settings in there:
Copy code
// Get the layout settings
    var hasSettings = Model.Settings != null;

    var backgroundColour = hasSettings ? Model.Settings.Value<ColorPickerValueConverter.PickedColor>("layoutSettingsColourPicker") : null;

    var colorLabel = backgroundColour?.Label;

    var colorShades = hasSettings ? Model.Settings.Value<decimal>("layoutSettingsColourShades") : (decimal?)null;

    var colorOpacity = hasSettings ? Model.Settings.Value<decimal>("layoutSettingsColourOpacity") : (decimal?)null;

    var backgroundImage = hasSettings ? Model.Settings.Value<Umbraco.Cms.Core.Models.MediaWithCrops>("layoutSettingsBackgroundImagePicker") : null;
https://cdn.discordapp.com/attachments/1252602283733024798/1252959948095225917/image.png?ex=66741d62&is=6672cbe2&hm=7d5ba23499cb9268c45933883010d5f76844d7624c531e1e0a58826160c5ebe3&
p
mhh i like this approach, and how do you integrate it into the blocks?
@Dean Leigh
d
All layout blocks use
_Layout_Layouts.cshtml
and all Feature Blocks use
_Layout_Features.cshtml
e.g. the RTE Block
Copy code
@{
    Layout = "_Layout_Features.cshtml";
}

@Model.Content.Value("richTextContent")
p
mhhh i get it! i think that'll do the trick! Thank you so much!!!
I didn't know i could do a layout for a block but this absolutely makes sense!
I've always worked this way in the old days using server side includes so was very happy to learn this whilst learning basic Razor Pages
p
Do you nowa days youse something different for the frontend instead of razor pages?
d
I have made an Astro version and HTMX version but just for fun. Tbh Razor pages do everything I need for most sites
p
Nice! If you have some in dept infos about astro let me know! 🙂 And again thanks for your expertise!
38 Views