Skip to content

links as blocks - #28

Merged
pfefferle merged 23 commits into
mainfrom
feat/link-blocks
Sep 22, 2026
Merged

pfefferle merged 23 commits into
mainfrom
feat/link-blocks

Conversation

@pfefferle

Copy link
Copy Markdown
Owner

Every link of a blogroll is a block of its own now, blockroll/link, inside the blogroll block. Adding, moving, duplicating and copying a link to another page works the way it does with any block, and everything is edited where it shows: name and description in place, the address behind the name in core's link overlay, feed and relationship in small overlays on the line below, the icon with a click on it (core's media menu). "Add link" opens an overlay with the address, looks the site up and fills in what it finds, like the old form's "Fetch details" did. Import is unchanged and puts the links in as blocks. The idea comes from the Jetpack blogroll block.

The frontend, the OPML, the discovery links and the source registry do not change: the blogroll still renders the whole list on the server, the link block has no output of its own. Sources::links() reads the link blocks and falls back to the old links attribute.

Migration in two layers: a post nobody opens again keeps rendering from the attribute, and a post that is opened gets its links turned into link blocks by a block deprecation (src/blogroll/deprecated.js). Core does not mark the post changed for that, so the new shape is written with the next edit.

Two things I ran into, both with a comment in the code: the container useInnerBlocksProps returns has to be rendered even for an empty list, since it is what registers the block list settings a link block needs to be inserted. And a MediaReplaceFlow whose toggle sits in the canvas iframe closes on the media library, because its focus check only knows the iframe's document; that unmounts the media control and leaves an empty modal, so the check is done against the parent document instead.

Not in here yet: a hint in the inspector that the canvas shows the list order while "Sort by" is name or date, and the empty placeholders for description, feed and relationship only when the link block is selected.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Unresolved portal focus bugs and import, child-filtering, and hook-ordering issues require fixes before approval.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 High severity · 2 Medium severity

Open (3)
What changed in this PR

Refactors blogroll links from a legacy attribute array into nested blockroll/link blocks while preserving server rendering, OPML export, source integration, and migration.

Changes:

  • Adds editable link blocks with overlays, media controls, discovery, import, and duplication.
  • Updates rendering, OPML extraction, migration, tests, and documentation.
  • Rebuilds assets and updates dependencies and CI configuration.
File Description
tests/​test-render.php Tests nested link rendering and legacy fallback.
tests/​test-opml.php Tests OPML extraction from link blocks.
src/​link/​overlay-button.js Adds metadata overlays; portal focus handling needs correction.
src/​link/​index.js Registers the link block.
src/​link/​editor.scss Styles link block editing.
src/​link/​edit.js Implements link editing and overlays; link overlay focus handling needs correction.
src/​link/​block.json Defines link block metadata and attributes.
src/​blogroll/​utils.js Adds URL, migration, and duplicate utilities.
src/​blogroll/​render.php Passes nested blocks to server rendering.
src/​blogroll/​link-block.js Creates link block instances.
src/​blogroll/​index.js Enables inner blocks and deprecations.
src/​blogroll/​editor.scss Styles blogroll editing controls.
src/​blogroll/​edit.js Manages nested links, imports, and insertion; child filtering and hook ordering need fixes.
src/​blogroll/​discover.js Adds cancellable discovery requests.
src/​blogroll/​deprecated.js Migrates legacy link attributes.
src/​blogroll/​components/​link-form.js Removes the superseded link form.
src/​blogroll/​components/​import-modal.js Adds cancellable import enrichment; pending requests need abort handling.
src/​blogroll/​components/​address-form.js Adds the reusable address form.
src/​blogroll/​components/​add-link.js Adds address lookup; popover portal focus handling needs correction.
src/​blogroll/​block.json Provides avatar context.
src/​blogroll/​__tests__/​utils.test.js Updates utility tests.
src/​blogroll/​__tests__/​to-url.test.js Tests URL normalization.
src/​blogroll/​__tests__/​site-key.test.js Tests duplicate detection keys.
src/​blogroll/​__tests__/​migrate.test.js Tests legacy migration helpers.
readme.md Documents block-based link editing.
package.json Adds the Compose dependency; dependency placement needs adjustment.
package-lock.json Updates dependency resolution.
includes/​class-sources.php Resolves links from nested blocks.
includes/​class-opml.php Exports nested link blocks.
eslint.config.cjs Configures the experimental focus hook.
docs/​developers.md Documents the new data model.
build/​link/​index.js Built link block script.
build/​link/​index.css Built link block styles.
build/​link/​index.asset.php Link script dependencies.
build/​link/​index-rtl.css RTL link styles.
build/​link/​block.json Built link metadata.
build/​blogroll/​render.php Built render template.
build/​blogroll/​index.js Built blogroll script.
build/​blogroll/​index.css Built blogroll editor styles.
build/​blogroll/​index.asset.php Blogroll script dependencies.
build/​blogroll/​index-rtl.css RTL blogroll styles.
build/​blogroll/​block.json Built blogroll metadata.
blockroll.php Registers both blocks and skips child rendering.
.github/​workflows/​phpunit.yml Updates the supported WordPress test configuration.
Files not reviewed (6)
  • build/blogroll/index-rtl.css: Generated file
  • build/blogroll/index.css: Generated file
  • build/blogroll/index.js: Generated file
  • build/link/index-rtl.css: Generated file
  • build/link/index.css: Generated file
  • build/link/index.js: Generated file

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/blogroll/components/add-link.js
Comment thread src/link/edit.js
Comment thread src/link/overlay-button.js

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

The editor can misrepresent empty blogrolls when non-link inner blocks are present.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 Low severity

Open (1)
Resolved since last review (3)
Files not reviewed (6)
  • build/blogroll/index-rtl.css: Generated file
  • build/blogroll/index.css: Generated file
  • build/blogroll/index.js: Generated file
  • build/link/index-rtl.css: Generated file
  • build/link/index.css: Generated file
  • build/link/index.js: Generated file

Comment thread package.json

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Five moderate findings remain regarding version configuration, empty submissions, import cancellation, source fallback, and block-props initialization.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 Medium severity

Open (1)
Resolved since last review (1)
Files not reviewed (6)
  • build/blogroll/index-rtl.css: Generated file
  • build/blogroll/index.css: Generated file
  • build/blogroll/index.js: Generated file
  • build/link/index-rtl.css: Generated file
  • build/link/index.css: Generated file
  • build/link/index.js: Generated file

Comment thread src/blogroll/edit.js

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Unresolved moderate findings remain in validation, child-block handling, hook ordering, URL normalization, and accessibility.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 2 Medium severity

Open (2)
Resolved since last review (1)
Files not reviewed (6)
  • build/blogroll/index-rtl.css: Generated file
  • build/blogroll/index.css: Generated file
  • build/blogroll/index.js: Generated file
  • build/link/index-rtl.css: Generated file
  • build/link/index.css: Generated file
  • build/link/index.js: Generated file

Comment thread src/blogroll/components/address-form.js
Comment thread src/blogroll/edit.js Outdated
@pfefferle
pfefferle requested a lite review from Copilot September 22, 2026 14:51

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Four moderate findings and one scope/documentation nit remain unresolved.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 3 Medium severity

Open (3)
Resolved since last review (2)
Files not reviewed (6)
  • build/blogroll/index-rtl.css: Generated file
  • build/blogroll/index.css: Generated file
  • build/blogroll/index.js: Generated file
  • build/link/index-rtl.css: Generated file
  • build/link/index.css: Generated file
  • build/link/index.js: Generated file

Comment thread src/blogroll/components/import-modal.js
Comment thread src/blogroll/utils.js Outdated
Comment thread src/link/edit.js Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Legacy migration can leave editor and server views inconsistent, and the deprecation wiring needs focused end-to-end coverage.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 Medium severity

Open (1)
Resolved since last review (3)
Files not reviewed (6)
  • build/blogroll/index-rtl.css: Generated file
  • build/blogroll/index.css: Generated file
  • build/blogroll/index.js: Generated file
  • build/link/index-rtl.css: Generated file
  • build/link/index.css: Generated file
  • build/link/index.js: Generated file

Comment thread src/blogroll/deprecated.js Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

A critical URL-scheme validation issue can allow javascript: links to execute in the editor.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 High severity

Open (1)
Resolved since last review (1)
Files not reviewed (6)
  • build/blogroll/index-rtl.css: Generated file
  • build/blogroll/index.css: Generated file
  • build/blogroll/index.js: Generated file
  • build/link/index-rtl.css: Generated file
  • build/link/index.css: Generated file
  • build/link/index.js: Generated file

Comment thread src/link/edit.js Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

One or more issues must be addressed before approval.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 2 High severity · 1 Medium severity

Open (3)
Resolved since last review (1)
Files not reviewed (6)
  • build/blogroll/index-rtl.css: Generated file
  • build/blogroll/index.css: Generated file
  • build/blogroll/index.js: Generated file
  • build/link/index-rtl.css: Generated file
  • build/link/index.css: Generated file
  • build/link/index.js: Generated file

Comment thread src/blogroll/edit.js Outdated
Comment thread src/blogroll/link-block.js
Comment thread src/blogroll/utils.js

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

The asynchronous lookup callback can overwrite a newer user-edited Added date.

Review effort: Lite
Findings: None

Resolved since last review (3)
Files not reviewed (6)
  • build/blogroll/index-rtl.css: Generated file
  • build/blogroll/index.css: Generated file
  • build/blogroll/index.js: Generated file
  • build/link/index-rtl.css: Generated file
  • build/link/index.css: Generated file
  • build/link/index.js: Generated file

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

Correct the block-props hook order and add direct deprecation migration coverage.

Review effort: Lite
Findings: None

Files not reviewed (6)
  • build/blogroll/index-rtl.css: Generated file
  • build/blogroll/index.css: Generated file
  • build/blogroll/index.js: Generated file
  • build/link/index-rtl.css: Generated file
  • build/link/index.css: Generated file
  • build/link/index.js: Generated file

@pfefferle
pfefferle merged commit 10092b6 into main Sep 22, 2026
4 checks passed
@pfefferle
pfefferle deleted the feat/link-blocks branch September 22, 2026 20:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants