Skip to main content

v1.0.0-rc.3

  • Added — Settings: a Privacy category opens private data to expressions: users' email, username, roles, registration date and chosen meta keys, the admin email, the roles loops may list, and the post types hidden from the public.
  • Improved — Pages, the admin and the REST API load faster: Unblock loads less code and runs fewer queries on each request.
  • Changed — Privacy: users' email, username, roles, registration date and meta, the admin email, and the posts of post types hidden from the public show nothing until opened in Settings > Privacy; a user still sees their own, and user fields made with ACF, Meta Box, Pods or JetEngine stay public.
  • Changed — Custom fields: images, files, posts, terms and users now come as the field plugin returns them, as in Timber; add {transform_value: true} to get objects you can chain, dates included, whatever the field's format: post.meta('hero', {transform_value: true}).src('medium'). The unblock/data/meta_transform_value filter turns it on for the whole site.
  • Fixed — Security: expressions could show private data: users' password hashes and emails, other users' editor preferences, password fields of ACF and Meta Box, options pages included, commenters' emails and IP addresses, or a file's server path.

Privacy​

  • Added — Settings: a Privacy category opens private data to expressions: users' email, username, roles, registration date and chosen meta keys, the admin email, the roles loops may list, and the post types hidden from the public.
  • Changed — Privacy: users' email, username, roles, registration date and meta, the admin email, and the posts of post types hidden from the public show nothing until opened in Settings > Privacy; a user still sees their own, and user fields made with ACF, Meta Box, Pods or JetEngine stay public.
  • Changed — Loop block: user loops and get_users() list authors with a published post, sorted by name; to list a role's members, open it in Settings > Privacy and filter the loop on it.
  • Changed — Loop block and get_posts(): sorting or filtering on a private meta key (starting with _) returns nothing, even for admins; WooCommerce's public product keys, such as _price, stay open, and the unblock/data/allowed_meta_keys filter opens others.
  • Fixed — Drafts, private posts and unapproved comments could show to visitors through loops, custom fields, post.children and post.comments.

Dynamic Data​

  • Added — Dynamic data: arguments can be given by name, as in Twig, to skip the ones before: post.timestamp|date(timezone: 'Europe/Paris').
  • Added — Dynamic data: in map, filter, find and reduce, an arrow function also gets the item's key: prices|map((price, name) => name ~ ': ' ~ price).
  • Added — Dynamic data: the date filter keeps the date's own timezone with false as second argument, as in Twig.
  • Improved — Dynamic data: get_posts(), post.terms() in a loop, post.variations and custom fields holding several posts are faster.
  • Changed — Dynamic data: operators follow Twig 4's precedence, so an expression mixing tests, ~, ?? or a minus can give another result, such as 'Total: ' ~ price + 1, which now adds first; add parentheses to keep the old one.
  • Changed — Dynamic data: false prints nothing instead of 0, and 0 is no longer empty for is empty and default, while a query without results now is, as in Twig.
  • Changed — Dynamic data: + adds numeric text, so '5' + 1 gives 6, and sort and filter keep each item's key, as in Twig; add |values to number the items from 0 again.
  • Changed — Dynamic data: date() gives a date instead of a timestamp, as in Twig, so it compares with a date field; write date(post.timestamp) > date() instead of post.timestamp > date().
  • Changed — Dynamic data: the date filter shows today's date for an empty value, as in Twig; test a custom field with is empty before formatting it.
  • Changed — Dynamic data: term.posts gives 10 posts unless asked otherwise, as get_posts() does: term.posts(20), or -1 for all.
  • Changed — Dynamic data: truncate counts words instead of characters, as in Timber, keeps links and formatting, and drops its third argument; use excerpt_chars to count characters.
  • Changed — Dynamic data: list adds a space after each separator, so write list(';', ' or') for a; b or c, and excerpt keeps 55 words instead of 50, as in Timber.
  • Changed — Dynamic data: the Intl filters take Twig's arguments in Twig's order; write the locale, and the style of format_number, by name: format_currency('EUR', locale: 'de_DE').
  • Changed — Dynamic data: column, wp_list_filter and json_encode read posts, terms and users as Timber does: post.categories|column('name') gives the names.
  • Changed — Dynamic data: on a product page, post.categories, post.tags and post.children read the product's.
  • Changed — Conditions: post.parent, post.next and post.prev are posts, no longer their titles: === 'Title' is now false, == 'Title' still matches.
  • Fixed — Dynamic data: list filters, such as first, join or map, gave nothing on get_posts(), term.posts, post.comments or a named loop.
  • Fixed — Dynamic data: a field after a filter was ignored, so post.categories|first.name == 'News' was true for any category.
  • Fixed — Dynamic data: a ? b without : swallowed what followed, and loop.length-1 did not subtract; both now read as in Twig, and - negates any value.
  • Fixed — Dynamic data: the date filter showed month names in English with a timezone, a date in 1970 for an ACF date such as 20260301, and broke the expression on an unknown timezone.
  • Fixed — Dynamic data: currency_name showed the code, such as EUR, in a regional locale like fr_CA.
  • Fixed — Condition block: the Code view dropped needed parentheses, such as in not (a ?? b), so leaving the field could change what the condition tests.
  • Fixed — Data picker: choosing a filter or a field with arguments wrote them empty, such as date('', ''), which printed an empty date.

Custom Fields​

  • Changed — Custom fields: images, files, posts, terms and users now come as the field plugin returns them, as in Timber; add {transform_value: true} to get objects you can chain, dates included, whatever the field's format: post.meta('hero', {transform_value: true}).src('medium'). The unblock/data/meta_transform_value filter turns it on for the whole site.
  • Fixed — JetEngine: fields of custom post types, users and terms were not recognized, and checkboxes saved as arrays came empty.
  • Fixed — Meta Box: with Meta Box AIO, fields came as stored in the database instead of as Meta Box returns them.
  • Fixed — Pods: a single file field came as a list.
  • Fixed — Custom fields: an empty field of ACF, Meta Box, Pods or JetEngine gave false instead of an empty text, as in Timber.

Loop​

  • Changed — Loop block and get_posts(): post_type: 'any' and a search without post_type cover the post types included in search, as in WordPress; name a post type excluded from search to list it.
  • Fixed — WooCommerce: upsells, cross_sells and children counted unpublished products and gave empty items in a loop.
  • Fixed — Loop block: a loop over get_posts({…}), term.posts or post.comments, or a Variable holding one, gave nothing, the latest posts or a single item.
  • Fixed — Loop block and get_posts(): without post_type, a query filtered by a custom taxonomy, such as product categories, found nothing; get_post() also missed post types excluded from search.
  • Fixed — Loop block: the term field suggested nothing for WooCommerce product attributes or shipping classes unless the user could manage products.

Editor Preview​

  • Improved — Editor preview: loops, and expressions on a page with many {% set %} variables, preview faster.
  • Fixed — Editor preview: in a page or custom post type template, or a synced pattern opened on its own, post previewed empty or wrong; it now shows sample data of its post type, parent, children and images included.
  • Fixed — Editor preview: loops over a {% set %} variable, a parent loop's alias or repeater rows, and over post.categories, post.tags or post.children in a template, showed nothing or the wrong items; inside a loop, post now reads the edited page.

Performance​

  • Improved — Pages, the admin and the REST API load faster: Unblock loads less code and runs fewer queries on each request.
  • Improved — The home page, archives, search results and 404 page no longer generate their CSS on each visit, and pages with the same styles or scripts share one cached file.

CSS & JS​

  • Changed — Unblock's element scripts load at the end of the page on every theme, still deferred.
  • Changed — Developer: the styles Unblock prints carry the id unbk-css (a link) or unbk-css-inline-css (inline), instead of unbk-initial-inline-css and unbk-deferred-inline-css.
  • Fixed — Classic themes printed the page CSS twice and ran each element script twice, so a toggle opened then closed at once.
  • Fixed — Content shown to some visitors only, such as a Condition true for them, could stay unstyled: a page kept the styles of its first visitor.
  • Fixed — A block printed late in the page, such as in the footer by another plugin, got its styles at the end of the page.
  • Fixed — On WordPress VIP, saving styles or purging the CSS left pages with their old CSS, and uninstalling Unblock or deleting a library left files behind.

Plugin​

  • Changed — Unblock requires WordPress 6.9 or later.
  • Fixed — Editing a page without the right to post unfiltered HTML no longer removes the JavaScript, styles and markup of the blocks you did not change.
  • Fixed — Forms: on a site installed in a subfolder, a form sent without JavaScript could lead to a page not found.
  • Fixed — Fonts: on a classic theme without saved global styles, each visit could add a global styles entry to the database.

Security​

  • Fixed — Security: expressions could show private data: users' password hashes and emails, other users' editor preferences, password fields of ACF and Meta Box, options pages included, commenters' emails and IP addresses, or a file's server path.
  • Fixed — Security: a contributor could display live HTML on a page through a text filter on the post content or excerpt, such as post.content|replace(…).
  • Fixed — Security: a loop or get_posts() could test a private meta value through a key left blank, 0 or starting with a space.
  • Fixed — Security: an editor request could overload the server by nesting batches of requests.
  • Fixed — Security: a pattern preview shared from the library could carry the output of the site's shortcodes, run with the rights of the user who captured it.