Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • ivan valadares 6 posts 86 karma points
    Nov 13, 2024 @ 15:46
    ivan valadares
    0

    Umbraco 14, Custom view with web component for a media picker block

    Hi, I have a block grid with an "image picker" block that has a property named "images," which is a multiple-image media picker.

    I have created a custom view for the block, but I can only access the media keys and not the media URLs to display the images.

    import { customElement, LitElement, property, css } from '@umbraco-cms/backoffice/external/lit';
    import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api';
    import type { UmbBlockDataType, UmbBlockEditorCustomViewElement } from '@umbraco-cms/backoffice/extension-registry';
    
    @customElement('imagespicker-block-view')
    export class RichTextBlockView extends UmbElementMixin(LitElement) implements UmbBlockEditorCustomViewElement {
        @property({ attribute: false })
        content?: UmbBlockDataType;
        override render() {
            var id = `image_gallery_${Math.floor(Math.random() * Number.MAX_SAFE_INTEGER)}`;
    
            var result = `
                 <div class="image-gallery" id="${id}">
                    <div class="image-gallery-container">
                        <div class="image-gallery-stack">`;
                            for (var i = 0; i < (this.content as any).images.length; i++)
                            {
                                var image = (this.content as any).images[i];
                                result += `<div class="image-gallery-item" data-img-idx="${i}">
                                    <img src="${image.key}">
                                </div>`;
                            }
            result += ` </div>
                    </div>
                </div>
                 `;
            return result;
        }
        static override styles = [
            css`
    
            `,
        ];
    }
    export default RichTextBlockView;
    

    In this line <img src="${image.key}"> i don't want the key property but the url property that does not exist in that object. How can i get it?

    Thanks in advance

  • Afreed 54 posts 261 karma points
    Nov 14, 2024 @ 10:04
    Afreed
    101

    Hi Ivan,

    To clarify the usage and types for this.content?.images, you'll need to typecast it to either UmbMediaPickerPropertyValue or a custom type, as Umbraco's media picker typically returns an array of objects with mediaKey (GUIDs) rather than URLs. You'll fetch the URL using these GUIDs.

    you need to retrieve the URL for each media key. In Umbraco, this can be done by using UmbImagingRepository, to fetch the media URLs based on the keys provided by the media picker.

    here is the example for this:

    import { html, customElement, LitElement, property, css, state } from '@umbraco-cms/backoffice/external/lit';
    import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api';
    import { UmbImagingRepository } from '@umbraco-cms/backoffice/imaging'; // Import the repository
    import type { UmbBlockDataType } from '@umbraco-cms/backoffice/block';
    import type { UmbBlockEditorCustomViewElement } from '@umbraco-cms/backoffice/block-custom-view';
    import type { UmbMediaPickerPropertyValue } from '@umbraco-cms/backoffice/media';
    
    @customElement('example-block-custom-view')
    export class ExampleBlockCustomView extends UmbElementMixin(LitElement) implements UmbBlockEditorCustomViewElement {
    
        @property({ attribute: false })
        content?: UmbBlockDataType;
    
        @state()
        logos: UmbMediaPickerPropertyValue[] = [];
    
        @state()
        logoUrls: Map<string, string> = new Map();
    
        #imagingRepository = new UmbImagingRepository(this);
    
        async updated(changedProperties: Map<string | number | symbol, unknown>) {
            super.updated(changedProperties);
            if (changedProperties.has('content') && this.content?.logo) {
                this.logos = this.content.logo as UmbMediaPickerPropertyValue[];
                await this.fetchLogoUrls();
            }
        }
    
        async fetchLogoUrls() {
            for (const logoItem of this.logos) {
                if (logoItem.mediaKey && !this.logoUrls.has(logoItem.mediaKey)) {
                    const url = await this.resolveMediaUrl(logoItem.mediaKey);
                    if (url) {
                        this.logoUrls.set(logoItem.mediaKey, url);
                        this.requestUpdate(); // Trigger a re-render to update URLs
                    }
                }
            }
        }
    
        async resolveMediaUrl(mediaKey: string): Promise<string> {
            const { data } = await this.#imagingRepository.requestThumbnailUrls([mediaKey], 300, 300);
            return data?.[0]?.url ?? '';
        }
    
        override render() {
            console.log(this.content);
            return html`
                <h5>My Custom View</h5>
                <p>Headline: ${this.content}</p>
                <div class="logo-container">
                    ${this.logos.map((logoItem: UmbMediaPickerPropertyValue) => html`
                        <img src="${this.logoUrls.get(logoItem.mediaKey) || ''}" alt="Logo" />
                    `)}
                </div>
            `;
        }
    
        static override styles = [
            css`
                :host {
                    display: block;
                    height: 100%;
                    box-sizing: border-box;
                    background-color: #dddddd;
                    border-radius: 9px;
                    padding: 12px;
                }
            `,
        ];
    }
    
    export default ExampleBlockCustomView;
    
    declare global {
        interface HTMLElementTagNameMap {
            'example-block-custom-view': ExampleBlockCustomView;
        }
    }
    

    enter image description here

    Hope this helps

  • ivan valadares 6 posts 86 karma points
    Nov 15, 2024 @ 10:42
    ivan valadares
    0

    @afreed Yeh! I needed the UmbImagingRepository, thank you. Umbraco is in need of Web Components Libraries Documentation.

  • Afreed 54 posts 261 karma points
    Nov 15, 2024 @ 10:45
    Afreed
    1

    Umbraco is in need of Web Components Libraries Documentation.

    Yes, this will be added en route to Umbraco v17. Hopefully

Please Sign in or register to post replies

Write your reply to:

Draft