Skip to content

v1.17.0

Choose a tag to compare

@github-actions github-actions released this 19 Aug 14:48
· 198 commits to main since this release

Highlights

  • A tag's source can now follow more than one step. Start at the current context, the site or a relationship, then follow further relationships or drop into a post's taxonomy terms to read the field you need. (Added)

    • 25 retired tag names for fixed two-step source paths are now convertible via the Migration Tool.
  • A tag you saved with a result limit of 0 or -1 now correctly returns every result; change it to 1 to keep the previous output. (Changed)

  • A source the tag cannot use renders nothing, instead of falling through to the current context. If a spot on your site goes blank after this update, check the tag's source(s). (Fixed)

  • The first-available tags read the author on an author archive now. An existing tag that output nothing or a later attempt instead may now show the author's name or bio. (Fixed)

  • Multi-slot tags now have buttons to add and remove slots, instead of automatically showing the next slot's controls. (Changed)

Added

  • A tag's source path can now follow more than one step. On the base tags, the Source control builds a path: start at the current context, the site or a relationship, then add steps that follow a relationship field or drop into a taxonomy term. Before this a source could follow one relationship and one taxonomy and no further, so something two relationships away was out of reach.
    • Each step that can return several results now has its own Limit Results control. Limit a taxonomy step to one and you get one term per referenced post, not one term overall. Leave it blank for all. Once an earlier step returns several results, a subsequent step's limit applies to each of them in turn. Existing tags render as before, apart from the three source items under Fixed.
    • A relationship field stored on an options page can now be followed. A path that starts at the site can take a relationship step, where before that step returned nothing. A globally configured "featured partner" now reads the way a per-post one does.
  • A slot's source can follow a path too, the same one a plain tag can. Each field in {{join}} and each attempt in the first-available tags builds its source with the same control a base tag uses, and it now resolves the same way: start at the current context, the site or a relationship, then follow a relationship field or drop into a taxonomy term, as many steps as you need, each with its own Limit results. A slot used to be held to one relationship step and one taxonomy step, and a source that went further rendered nothing at all; the editor did not offer those steps for that reason, and now it does. "Same as Previous Source" carries the whole path, so an attempt that inherits a two-step source inherits both steps rather than landing back on the current context. Setting a step of your own on the same kind still replaces the inherited one, as it always has.
  • 25 retired tag names are now convertible. The second_related_post_* and post_term_related_post_* families were retired in 1.6, and the Migration Tool has had no conversion for them since, because nothing could follow two relationships. A source path can. This is the one change here you may see on a page: these tags have rendered nothing since 1.14, so a blank spot can start showing content again after you run the migrator. A tag whose second relationship field was never filled in is left alone rather than half-converted.
  • Another plugin can add its own starting point to the Source control. A plugin that resolves its own context from the page being viewed can offer it as a place a source path starts. It then appears in the Source list on every base tag and in every slot of {{join}} and the first-available tags, named by that plugin, next to Current and Site. Steps, per-step limits, field pickers and previews all work from there as usual. Nothing appears until a plugin you have installed opts in.
  • For plugin developers: two routes to offering a source as a source-path start. A source class returns true from is_selectable_root(), or a plugin declares one from the bws_dynamic_tags_chain_roots filter with a label, a context type and a function that finds the entity, no class needed. Offering is separate from resolving: a tag naming your source resolves whether or not you currently offer it, so removing the offer alone never blanks saved content. Upgrade note: is_selectable_root() is declared on SourceInterface, so a source class implementing the interface directly must add it; extending AbstractSource inherits the default. See docs/plugin-integration.md §1a.
  • The editor now tells you what a relationship field does and does not enforce. Pick an ACF relationship or post object field for a source step and a short note appears above Limit results. It says whether the field has a configured limit, whether edits made elsewhere can add to it, and whether it is set to hold a single entry. ACF applies a configured limit only when the field is edited directly in ACF, so a bidirectional write, an import or WP-CLI can push a field past it; and a post object field set to a single entry can be holding entries it never shows, all of which appear at once if you later allow it several. Field group settings are where you would otherwise have to check this, and they are out of reach in Patterns, Elements and templates, which is where the note is most useful. It reads field settings only, never stored values, so it says the same thing wherever you are. A field with nothing to report gets no note, and the note never blocks a save or changes what a tag renders.
  • For plugin developers: one call migrates a prefixed tag family onto the base tags. bws_register_modifier_root_migrations( 'yourprefix', 'yoursource' ) registers one migration entry per registered tag template, so there is no list of tag names to keep in step. The Migration Tool then rewrites saved content: a tag that followed a relationship or dropped into a taxonomy term keeps doing exactly that, as steps of a source path. Your tags stay registered and go on rendering, so retiring the prefix stays your decision. One shape renders differently after conversion: a prefixed tag set to read the site that also carried a relationship or taxonomy setting has rendered nothing at all, and converting it drops both and gives you the site value. The migrator reaches every post, page and template part, but not block widgets. See docs/plugin-integration.md §9.
  • For plugin developers: the plugin now announces when it writes post content without firing a save. The Migration Tool writes migrated content straight to the database on purpose, so that a maintenance run does not create a second revision, bump modified dates, or set off every save listener on the site. The cost is that nothing downstream hears about it, which is how the pattern cache under Fixed went stale. bws_dynamic_tags_content_written now fires with the post ID and the new content, so a cache of your own over post content can refresh itself. Use the content you are handed: no post object is passed, because the one in scope at that point still holds the pre-migration content. It states a fact rather than promising to drive anyone's cache. See docs/plugin-integration.md §10.

Changed

  • Multi-slot tags now configure one slot at a time, with buttons to add and remove them. {{join}} and the nine try_ tags used to reveal their slots one at a time: slot 3's controls appeared only once slot 2 held a value, and clearing an early slot could hide the later ones. Each slot is now a block of controls you add and remove directly, and removing a middle slot closes the gap without re-pointing the slots after it. Each slot saves under one option key instead of six, and its key is a letter (A, B, C), which is also its panel label; {{join}} adds a field (Field B), a try_ tag an attempt (Attempt C). Existing tags are converted for you, both on opening one in the editor and on running the Migration Tool. Output is unchanged apart from the source fixes under Fixed.
    • {{join}}'s format tokens are letters now, matching those labels. In template mode you write %A, %B, and so on, where 1.15.0 used %1, %2. The numbered tokens still work and will keep working, so a format string you already wrote requires no change. One thing to know if you used a literal percent sign: a % directly before a capital letter now reads as a slot token, so text like 10%APR would change meaning. The Migration Tool rewrites those to %%APR, which renders as typed; type %% when you mean a literal percent before a capital letter.
  • Every field in a field selector now shows its type. A row reads Partner Staff (Relationship, 'partner_staff'), where before it read the label and key alone and the type was reachable only by narrowing the type filter. Typing a type name searches on it, so "post object" finds the post object fields without touching that filter. The type is read from the field itself, so it is spelled the same way on every field, including types this plugin has no name for and any a third-party plugin adds. Order is unchanged: still alphabetical by field name, not grouped by type. A field with no type, such as a plain registered meta key, shows no type.
  • A tag whose source is a path no longer shows the two old source fields as well. "Relationship Field Key" and "Get from taxonomy term?" are steps in the path now, so the separate controls are gone from the base tags. A tag saved the old way opens with its relationship and taxonomy showing as steps, and saves and renders as before unless it is one of the shapes under Fixed. The term_ family and {{call}} keep both controls.
  • Tag option controls are grouped in the editor. Control groups such as the source path, the field selection, and how the value is rendered are now shown in bordered panels for readability. Nothing about the saved tag or the output changes.
  • A limit of 0 now means no limit. The per-slot limits on {{join}} and the try_ tags, and any tag-wide Result Limit saved from before this release, all accepted 0, but rendered one result anyway. Entering 0 now returns every result the source has, there and on the new per-step limits. A hand-typed -1 reads the same way; 0 is what the plugin writes. A tag saved with a limit of 0 or -1 starts listing every result after this update. Set it to 1 to keep the previous output. On {{text}}, {{title}} and the date/time tags one link wraps the whole result, so a tag that starts listing stops being a link; the email and phone tags are unaffected, since each address or number is its own link. Leaving a limit blank, or typing something that is not a number, means no limit stated: an older tag still bounds its list at one result, a source written as a path returns all of them.
  • Result Separator stays visible once a source follows a path. It used to disappear the moment a source was written as a path, because it was shown by matching the two source values that were once the only ones returning several results. It now shows whenever the source can return several results, however that source is written.
  • The Migration Tool rewrites saved sources into paths. A tag's Source, Relationship Field Key and taxonomy setting become a single source path. The old spelling returned one result unless you said otherwise, while a path returns all of them, so each step's limit is set to 1 and left there for you to see and clear. A Result Limit you set yourself moves onto the last step instead. Opening a tag in the editor does the same, and the two cover different content: the migrator reaches drafts and posts nobody has opened, while opening a tag reaches block widgets and templates the migrator does not scan. A tag you never touch keeps working as it is.
  • A converted tag now writes its settings in the same order the editor does. Converted tags used to come out in whatever order the conversion happened to build them, so opening one and changing anything reshuffled the whole tag, which looked like the edit had changed more than it did. Conversion now uses the editor's own ordering. Nothing about what a tag does or displays changes, and settings the ordering does not recognise, including any an add-on adds, keep their values and their place.
  • On the try_ tags, Result Limit belongs to each attempt now. The tag-wide Result Limit on {{try_text}} and its siblings never bounded the tag as a whole: each attempt used it for its own list, so a tag with three attempts applied it three times. Once an attempt's source is a path there is nothing to say which step such a number applies to. Converting a tag moves your number onto each attempt that lists something. Output is unchanged, including for an attempt set to inherit the previous one's source: inheriting a source now inherits its limit as well. An attempt that returns a single value gets no limit. {{join}} is unaffected, since its Result Limit has always belonged to the individual field.
  • For plugin developers: bws_strip_default_select_values() is now bws_prepare_registration_options(). There is no alias, so an add-on calling the old name needs updating. As well as stripping default select values it now stamps each option's visual group and drops the flat source controls a source path has taken over. What it takes and returns is unchanged. See docs/plugin-integration.md. No effect on tags or output.
  • The image and date/time return-type controls all read "Return As" now. One control doing one job had three labels: "Return type:" on {{image}}, "Return image as:" on {{term_image}} and {{try_image}}, and "Show:" on the date/time tags. Labels only, and the size dropdown under an image's Return As is no longer pressed up against it.
  • A per-step limit on a slot now bounds that step. A field or attempt whose source followed a relationship and a taxonomy could only carry one limit between them, so every step ran unbounded and the finished results were cut at the end: with a limit of 2 you got the first 2 results drawn from every related post. Each step bounds itself now, as it already did on the plain tags, so you get 2 from the first related post. This only ever reaches a slot whose source follows two steps that can each return several results, and the two readings agree wherever the first step supplies enough. A slot with one such step, which is every shape the old controls could produce, is unchanged.
  • A tag whose source cannot work anywhere now says so in the editor. A misspelled source name, a step this plugin has no such thing as, or a source retired in an earlier release all render nothing, and until now the preview described the tag as if it were fine: a typo in the source name previewed exactly like a tag with no source at all. The preview reads ⚠ Unknown source 'currnet' instead, or names the step, or, for a retired source, tells you to run the Migration Tool, which rewrites it. This reaches the plain tags as well as the fields and attempts inside {{join}} and the try_ tags. It only fires where the answer is certain from the tag itself: a source that reads whatever page it is on is never flagged, nor is one an add-on has stopped offering but still resolves.
  • Editor previews name a slot by its letter, and say less when slots disagree. A warning in a tag's editor preview read slot 2 no key while the slot itself is labelled Field B and saves under B. It reads B no key now. Slots with the same problem are listed together (A, C no key); slots with different problems are named without the detail (A, B, C misconfigured), since opening each one is the fix either way. A tag-wide warning, such as a missing {{join}} format, still reads in full beside them.
  • Relationship traversal now has one setting, not two spellings. Four built-in sources kept resolving relationships themselves, reading the field name from an option called rel (or, further back, key) that nothing else has read since 1.14.0. Everything current reads Relationship Field Key (ref), and those four no longer resolve anything. A saved tag naming related_post as its source is rewritten to use ref when you run the Migration Tool, which keeps it reading what it read before. Only hand-written tags and content old enough to predate the conversion were ever affected.

Removed

  • The tag-wide Result Limit control is gone, replaced by per-step limits (see Added). However, a limit already saved in a tag is still read and still bounds the results, converted or not, so tag output doesn't change unexpectedly. Opening a tag with an existing set limit moves the limit onto the step it applies to.

Fixed

  • A first-available attempt now resolves its source the same way the plain tag does. {{try_text}} and its siblings worked out each attempt's source by looking at how it was spelled, where every other tag had already moved to asking what the source resolves to. Two shapes came out differently as a result. An attempt following a relationship stopped at the first result, so {{try_text}} returned one related post's title where {{text}} returned all of them; this is visible only on an attempt with no limit or with a limit above one, since an attempt that states no limit still bounds an older tag's list at one result. And an attempt set to read the site while also carrying a leftover taxonomy setting rendered nothing at all, where the plain tag read the site and ignored the leftover. Both now match. Nothing else about what an attempt returns changes, including the attempt order, the separator and which result gets the link.

  • {{content}} reading a related post now shows that post's own values. Pointing the content tag at a relationship pulled in the related post's layout, but any tag inside that layout read the page you were viewing instead of the post it belonged to. The right structure came out carrying the wrong values, which looks like working output rather than a fault. Excerpts had it too, including the "read more" link, which pointed back at the page you were on. Both now resolve against the post the content came from. This affects the tag only when its source is a relationship or a path that leads elsewhere; reading the current context is unchanged.

  • A source the tag cannot use now renders nothing, instead of quietly reading the current context. Four shapes all did the same wrong thing: showed a real, plausible value from the wrong place, so nothing looked broken, and any Fallback Text you had set never fired because the read never reported finding nothing. All four now render nothing (your fallback shows, a first-available tag moves on to its next attempt, a {{join}} drops that field), matching what the editor already warned about. If a spot on your site goes blank after this update, open that tag — it was reading something it was never pointed at, or scoped somewhere it never applied.

    • A step names a relationship but no field, or has no field or taxonomy chosen yet — the editor has been telling you all along: an unfinished step displays "will be skipped unless a field is set". On {{join}} and the first-available tags the unfinished slot is skipped, so a later attempt gets its turn. A step that inherits its field from an earlier slot is unaffected.
    • A source name this plugin does not recognise — a typo, or a token from a plugin that is no longer active — was treated as though no source had been set at all.
    • A step in a source path names something this plugin has no such thing as — dropped, so the tag read the part of the path before it.
    • A source scoped to part of a site answered correctly on its own pages and, everywhere else, fell through to the current context. Elements are where this bites: a tag in a site header or footer evaluates on every page, so one such tag could show the wrong data site-wide. It reads empty off its scope now.

    Deliberately unchanged: leaving a source unset still means the current context, which is what a blank Source control has always meant; a source belonging to a plugin that has stopped offering it in the Source list still resolves for tags already using it, so withdrawing an offer never blanks saved content; and if this plugin's own source list fails to load, tags still read the current context, because that is a fault in the plugin rather than in your tag and refusing would blank every tag on the site at once.

  • An image tag saves its return type again. Since 1.16.0, a newly inserted image tag wrote no return type into the tag string, so {{image use:featured}} did not say it returned a URL at full size. It rendered correctly, since that is what a missing return type has always meant, but writing it out is how you read a tag and see what it does. New image tags write it again. Tags saved under 1.16.0 keep rendering as they always did; open one and set the return type if you want it written out.

  • A slot set to "Same as Previous Source" inherits the whole of that source, and inherits nothing when there is nothing to reuse. Two faults, both ending in a silent read of the current context.

    • A taxonomy term step was not inherited. On {{join}} a field you expected from the term came back blank, or worse, came back with the page's own value and looked right. On the first-available tags the same attempt could succeed against the current context and stop the ones after it from being tried. A slot that states its own source or its own taxonomy still wins. If a multi-slot tag of yours starts at a taxonomy term, check the slots after the first: they may have been reading the current context and will now read the term.
    • With every earlier slot skipped, there was no previous source at all. If none had a field chosen yet, the slot fell back to the current context rather than to nothing, so a {{join}} whose only visible source said the site read the page instead. Slot one is unchanged: a first slot with no source set still means the current context.
  • The first-available and term-based tags order their controls like every other tag now. On the nine try_ tags, the formatting options rendered above the attempts, Fallback Text sat above the link options, and Result Limit and Result Separator were pushed to the very bottom of the panel even though they describe the source at the top. On the term_ tags, Fallback Text likewise sat above the link options. All of them now run source, then field, then formatting, then link, then fallback: the order 1.16.0 described. Nothing about the saved tag or the output changes.

  • The Migration Tool no longer loses a tag's on/off settings. Four settings are written into a tag as a plain switch with no value: "Do not link" on the email and phone tags, "Open in new tab" on any linked tag, and the two date/time options for showing the current year and midnight. Two separate faults could leave a converted tag with one of them turned off. Both are fixed. In both cases the setting cannot be recovered from the tag itself, though the migrator saves a copy of each post before it changes anything.

    • Any such switch was deleted outright by every conversion, and had been since the migrator shipped in 1.6. Until now the only one it reached was the pre-1.6 spelling of "Open in new tab" on a retired tag name, which it quietly turned off; this release converts far more tags, so all four were about to be exposed. All four now survive conversion. If you converted a retired tag name on an earlier release, check whether it was meant to open in a new tab.
    • On a pre-1.6 date tag, the year and midnight settings were inverted on top of that. 1.6 renamed both, and the migrator went on reading the old ones as though an untouched box meant the opposite of what it did. A pre-1.6 date or date-and-time tag whose author never ticked either box showed the current year and showed a time stored as midnight; converting it turned both off, so a date could quietly lose its year and a midnight time could vanish. Conversion now preserves what the tag showed, and stops writing a midnight setting onto a date-only tag, or a year setting onto a time-only one, where neither does anything. Only tags predating the 1.6 rename are affected, and only those the migrator has not already rewritten. If you converted a pre-1.6 date or date-and-time tag on an earlier release, check how it displays the year and midnight times.
  • The Migration Tool's repair of the pre-1.6 relationship key is fixed on three counts. That repair rewrites the old spelling (rel:) to the current one (ref:); only content old enough to predate the 1.6 rename is affected.

    • It covers the term_ and try_ families now. They were never included, so a tag left half-converted by an old run stayed broken. Each try_ attempt is repaired on its own rather than all of them together.
    • It no longer re-points a working tag. Since 1.6, a tag carrying both spellings had the old one win: the repair overwrote the live ref: value with the rel: value beside it, and the tag silently started reading a different post. The tag's source now decides which spelling was actually in use, and the other is dropped. Only tags holding both keys at once were affected, which the editor cannot produce; a hand-edited tag or one left by a partial migrator run can.
    • A key written as key: is no longer read as two different things. On a tag using the older related_post source, a relationship named through key was used both to find the related post and, separately, as the field to read on it. Conversion keeps both readings rather than dropping one, so such a tag renders the same after it as before.
  • Block patterns no longer hand out pre-migration tags after a conversion. GenerateBlocks Pro keeps its own copy of each block pattern's content, written once when the pattern is saved. The Migration Tool rewrote post content without touching that copy, so the pattern inserter went on inserting the old tag strings indefinitely, seeding retired wire back into fresh pages. Nothing rendered wrong and a second scan reported nothing left to do, because the scan reads post content only. Measured on two sites, a completed conversion left 30 of 31 rewritten tag strings alive in that copy. Scanning, migrating, and upgrading the plugin now each reconcile it, whether or not anything migrated in that run, so a site converted on an earlier release is repaired too. Only the stored content is rewritten: previews, and the scripts and styles that go with them, are left exactly as found, so a migration cannot degrade the pattern library. The Migration Tool reports how many patterns it checked and how many it updated, including when it updates none. A pattern already consistent is not written at all. Patterns are the only cache reached, and the Migration Tool now says so: tag strings held in custom field values or in another plugin's data are still out of reach.

  • The first-available tags read the author on an author archive now. {{try_text}}, {{try_title}} and {{try_content}} rendered nothing there, while {{text}}, {{title}}, {{content}} and {{join}} all read the author. An attempt is meant to resolve exactly as the plain tag does, and these three now do: the display name, the biography from the author's profile, and any field stored on the user. A spot that has been blank on your author archives can start showing the author's name or bio after this update. Watch for the other half of that on a tag with several attempts: where a first attempt reads a field on the user and that field has a value, the attempt wins, so a later attempt that used to supply the value stops being reached. The other six first-available tags are unchanged, since the plain tags have no author reading for them either. This is the one intentional change to what a tag renders in this release; everything else under Fixed corrects a tag that was reading the wrong thing.

  • For plugin developers: a rename chain now completes in one migrator run. Where one deprecated tag name renames to another deprecated name, the migrator took the first step and stopped. The tag landed on a still-registered name that still rendered, and a second conversion run finished the journey. No tag this plugin ships chains that way; it applies to a plugin that has retired a tag prefix more than once. Nothing was lost or misread, and the scan reported the tag accurately at every stage.