Umbraco Flavoured markdown on Settings

Hi all,

I have a setting which allows the block to be enabled or disabled. I have created a UFM for it which works great, when I have the property directly on the block. Is there a way of using this with a property on the setting node?

Thanks

Matt

So I have been playing with that an gotten close :frowning:

The following code results in an emoji if its on a block as normal, however for the setting the console.log shows the emoji correctly BUT the back office shows [Object, Object]

    @property()
    alias?: string;

    @state()
    private settings: UmbBlockDataModel | undefined;

    constructor() {
        super();
        this.consumeContext(UMB_UFM_RENDER_CONTEXT, (context) => {
            this.observe(
                context?.value,
                (value) => {

                    if (this.alias !== undefined && value !== undefined && typeof value === 'object') {

                        if (value?.hasOwnProperty(this.alias)) {
                            this.value = this.toEmoji((value as Record<string, unknown>)[this.alias]);
                        }
                        else if (this.settings) {
                            const settingValue = this.settings.values.find(v => v.alias === this.alias);
                            console.log(this.toEmoji(settingValue?.value))
                            this.value = this.toEmoji(settingValue?.value);
                        } else {
                            this.value = value;
                        }
                    } else {
                        this.value = value;
                    }

                },
                'observeValue',
            );
        });
        this.consumeContext(UMB_BLOCK_ENTRY_CONTEXT, (context) => {
            // Access settings values
            this.observe(
                context?.workspaceEditSettingsPath,
                (_) => {
                    console.log("settings refreshed");
                    this.settings = context?.getSettings();
                },
                'observeSettings'
            );
        });

    }

Hi Matthew

I think I need a bit more context to know what to pinpoint, so lets try aligning by me asking some questions:

Would you like this code to also work on a normal Document Node(Item)?
And is that the case where it turns [Object, Object]?

I am currently only considered about blocks and block settings.

As you can see in the image below its working great if the property is on the main block

However in when its in settings:

Interesting, I think you need to investigate what you get back from getSettings — An easy way to do that would be to output the settings right after you got them. like console.log(this.settings).

Now that we are at it, I just looked it up and it should give you an object of this interface:

key: string;
contentTypeKey: string;
values: Array<UmbBlockDataValueModel>;

In that light, it makes sense that it outputs [Object, Object]

And then I would assume your code was slightly different when it did work having the Property on the Content part of the Block. — But that surely does not matter now :wink:

Looking at your code, there are a few things to be aware of:

First, you are observing the workspaceEditSettingsPath , but that is not what you are using.
Instead, I would observe the values, and then your code would also reactively. in other words update if values update. So you could do this instead:

 this.consumeContext(UMB_BLOCK_ENTRY_CONTEXT, async (context) => {
            // Access settings values
            this.observe(
                await context?.settingsValues(),
                (settings) => {
                    console.log("settings retrived:", settings);
                    this.settings = settings;
                },
                'observeSettings'
            );
        });

And then in that light, you need the value update to be executed when you retrieve new settings?
Well maybe that is already a lost journey, cause looking at your code it seems like you replace the value? maybe thats not the best approach but I dont know enough to judge at this moment. Anyhow I hope the guidance was valueable and I do think the problem is caught.

Did you consider registering a custom UFM Component, instead of manipulating the UFM value?

If you where to observe just one value you could do this instead:

this.consumeContext(UMB_BLOCK_ENTRY_CONTEXT, async (context) => {
            // Access settings values
            this.observe(
                await context?.settingsPropertyValueByAlias('my-alias'),
                (value) => {
                    console.log("got setting value of 'my-alias':", value);
                    this.settings = settings;
                },
                'observeSettings'
            );
        });

That would be a better fit if you are only using one of the Settings properties.

With some more help from the great @nielslyngsoe :slight_smile:

We have two things!

await context?.settingsPropertyValueByAlias(this.alias), currently returns undefined which I will raise an issue for :slight_smile:

and maybe more importantly a solution, which is less performant as it updates on any settings change. This UFM will work for settings or a normal property

import { UMB_BLOCK_ENTRY_CONTEXT } from '@umbraco-cms/backoffice/block';
import { customElement, property } from '@umbraco-cms/backoffice/external/lit';
import { UMB_UFM_RENDER_CONTEXT, UmbUfmElementBase } from '@umbraco-cms/backoffice/ufm';

@customElement('ufm-mya-active-value')
export class MyaActiveValueElement extends UmbUfmElementBase {
    @property()
    alias?: string;

    constructor() {
        super();
        this.consumeContext(UMB_UFM_RENDER_CONTEXT, (context) => {
            this.observe(
                context?.value,
                (value) => {
                    if (this.alias !== undefined && value !== undefined && typeof value === 'object') {

                        if (value?.hasOwnProperty(this.alias)) {
                            this.value = this.toEmoji((value as Record<string, unknown>)[this.alias]);
                            return;
                        }
                    } else {
                        this.value = value;
                    }

                },
                'observeValue',
            );
        });
        this.consumeContext(UMB_BLOCK_ENTRY_CONTEXT, async (context) => {
            // Access settings values
            this.observe(
                await context?.settingsValues(),
                (settings) => {

                    if (this.alias && settings && settings.hasOwnProperty(this.alias))
                        this.value = this.toEmoji(settings[this.alias]);
                },
                'observeSettings'
            );
        });

    }
    toEmoji(value: unknown) {
        return value ? '💚' : '🙈';
    }
}

export { MyaActiveValueElement as element };

declare global {
    interface HTMLElementTagNameMap {
        'ufm-mya-active-value': MyaActiveValueElement;
    }
}

Which is called from a custom UFM:

import { Tokens } from '@umbraco-cms/backoffice/external/marked';
import { UmbUfmComponentBase } from '@umbraco-cms/backoffice/ufm';


import './may-active-value.element.js';

export class MyaActiveUfmComponentApi extends UmbUfmComponentBase {

    render(token: Tokens.Generic) {
        // You could do further regular expression/text processing here!
        const value = super.getAttributes(token.text);
        return `<ufm-mya-active-value alias="${token.text}" ${value} text="${value}"></ufm-mya-active-value>`;
    }
}

export { MyaActiveUfmComponentApi as api };

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.