A calm place to write long-form, and publish it to the open social web. skypress.blog/
0

Configure Feed

Select the types of activity you want to include in your feed.

Render: core/embed renders resolved card or link fallback

+53 -2
+36
src/lib/blocks/render.test.ts
··· 111 111 expect( blocksToText( blocks ) ).toBe( 'Before\n\nAfter' ); 112 112 } ); 113 113 } ); 114 + 115 + describe( 'core/embed', () => { 116 + it( 'renders the resolved card when a payload is attached', () => { 117 + const html = renderBlocks( [ 118 + { 119 + name: 'core/embed', 120 + attributes: { 121 + url: 'https://bsky.app/profile/a/post/b', 122 + _skypressEmbed: { 123 + kind: 'atproto', 124 + authorName: 'A', 125 + handle: 'a.bsky.social', 126 + text: 'hi', 127 + images: [], 128 + viewUrl: 'https://mu.social/profile/did:plc:a/post/b', 129 + }, 130 + }, 131 + }, 132 + ] ); 133 + expect( html ).toContain( 'skypress-embed--atproto' ); 134 + expect( html ).toContain( 'hi' ); 135 + } ); 136 + 137 + it( 'falls back to a plain link when there is no payload', () => { 138 + const html = renderBlocks( [ 139 + { name: 'core/embed', attributes: { url: 'https://example.com/x' } }, 140 + ] ); 141 + expect( html ).toContain( '<a' ); 142 + expect( html ).toContain( 'https://example.com/x' ); 143 + expect( html ).not.toContain( 'skypress-embed' ); 144 + } ); 145 + 146 + it( 'renders nothing for an embed with no url and no payload', () => { 147 + expect( renderBlocks( [ { name: 'core/embed', attributes: {} } ] ) ).toBe( '' ); 148 + } ); 149 + } );
+17 -2
src/lib/blocks/render.ts
··· 7 7 * is locked to `@wordpress/blocks.serialize()` by `render.test.ts`, which uses the 8 8 * real packages as the oracle. 9 9 * 10 - * Covers the curated allowlist (Decision 0002). Image/gallery/pullquote/embed 11 - * rendering is stubbed pending SP3 (blobs) / SP4 (oEmbed + sanitisation). 10 + * Covers the curated allowlist (Decision 0002). `core/embed` renders a resolved 11 + * card (atproto post / video facade) when `resolveEmbeds` has attached a payload, 12 + * else a plain link. Card markup intentionally diverges from `serialize()` — a 13 + * read-time enhancement, like blob-image URL resolution (rule 4). 12 14 */ 15 + 16 + import { renderEmbedCard, type EmbedData } from '../embeds/card'; 13 17 14 18 export interface BlockNode { 15 19 name: string; ··· 69 73 const caption = attr( node, 'caption' ); 70 74 const fig = caption ? `<figcaption>${ caption }</figcaption>` : ''; 71 75 return `<figure class="wp-block-image"><img src="${ url }" alt="${ alt }"/>${ fig }</figure>`; 76 + } 77 + 78 + case 'core/embed': { 79 + const data = node.attributes?._skypressEmbed as EmbedData | undefined; 80 + if ( data ) { 81 + return renderEmbedCard( data ); 82 + } 83 + const url = attr( node, 'url' ); 84 + return url 85 + ? `<figure class="wp-block-embed"><a href="${ url }">${ url }</a></figure>` 86 + : ''; 72 87 } 73 88 74 89 default: