Shortcodes and filters

Reference for developers: shortcodes, hooks, template overrides, the rendering pipelines and where the data lives.

Shortcodes

[ptstudio_tabs]
Renders the whole WooCommerce tabs template for the current product. Use it when a page builder or block template has dropped the default tabs output. Optional attribute product_id.
[ptstudio_tab]
Renders one panel inline, heading and content. Identify it with key="size-guide" or id="12" (the global tab's post id); optional product_id. Returns nothing when the tab does not apply to that product, so it is safe to place in a shared template.
[ptstudio_youtube]
Embeds a video from video_id, with optional width and height. Falls back to a privacy-enhanced iframe when the oEmbed lookup returns nothing.

When data from WB Custom Product Tabs is present and that plugin is inactive, [wb_cpt_product_tabs] and [wb_cpt_youtube_embed_shortcode] are registered as aliases of the first and third.

Storage

  • A product's own tabs are one post meta value, _ptstudio_tabs, holding a JSON string. Version history is _ptstudio_tabs_history.
  • Global tabs are posts of the ptstudio_tab type, with their key, priority, heading, admin label, rules and origin in _ptstudio_-prefixed meta.
  • Settings are the single option ptstudio_settings. A compiled index of published global tabs and their rules is kept in an option so a product page never has to query for them.
  • Every value the plugin writes is a JSON string or a scalar. The only unserialize() call in the code base is the guarded decoder used to read other plugins' legacy data.

Resolving one product's tabs reads its post meta, that one option and the product's terms. There are no LIKE scans and no extra tables.

Rendering pipelines

Tab content passes through one of three pipelines, chosen per site under Tab Settings → Rendering and overridable per tab:

Standard
apply_filters( 'the_content', … ), with a re-entrancy guard that falls back to the isolated pipeline if the filter is already running.
Isolated
The content filters applied by hand, without the theme's own additions: blocks, wptexturize, convert_smilies, wpautop, shortcode_unautop, prepend_attachment, wp_filter_content_tags, one do_shortcode pass, then auto-embeds. This is what you want when a page builder rewrites the_content.
Raw
do_shortcode only.

Panel rendering is wrapped in a try/catch. If a pipeline throws, or returns nothing for non-empty input, the failure is logged once per tab per day and the content is re-rendered with the isolated pipeline, then raw. Turning on safe mode forces the isolated pipeline everywhere.

Filters

FilterArgumentsUse
ptstudio_resolved_tabstabs, productThe resolved tab models for a product, before they become WooCommerce tab entries.
ptstudio_product_tabstabs, product, resolvedThe WooCommerce woocommerce_product_tabs array after this plugin has added to it.
ptstudio_tab_contenthtml, tab, productThe rendered panel content.
ptstudio_tab_headinghtml, tab, productThe heading markup printed above the content.
ptstudio_content_pipelinesteps, mode, tabThe list of steps in the isolated pipeline.
ptstudio_rule_typestypesThe rule type registry. This is the extension point the paid tier uses.
ptstudio_brand_taxonomiestaxonomiesWhich taxonomies count as brands for rules. Defaults to product_brand, pwb-brand and yith_product_brand.
ptstudio_tabs_filter_prioritypriorityThe priority this plugin uses on woocommerce_product_tabs. Default 10.
ptstudio_locate_templatepath, nameWhere a template file is loaded from.
ptstudio_allowed_htmlallowed, contextThe allowed HTML map used when sanitising tab content.
ptstudio_iframe_hostshostsThe hosts an iframe in tab content may point at.
ptstudio_admin_capabilitycapabilityThe capability required for settings, tools and migration. Default manage_woocommerce.

When legacy hook mode is on, the equivalent filters of Custom Product Tabs for WooCommerce are fired as well, so theme snippets written against that plugin keep working.

Actions

ActionArgumentsFires
ptstudio_after_product_tabs_savedproduct id, tab setAfter a product's tabs are written.
ptstudio_product_tabs_save_abortedreason, product id, contextWhen a save was refused by a guard, for example a truncated form.
ptstudio_after_tab_savedpost id, submitted dataAfter a global tab is saved.
ptstudio_migration_finishedplugin, stateAfter a migration run completes.
ptstudio_panel_row_fieldstab, index, rowInside a row of the product panel, for adding fields.
ptstudio_tab_settings_fieldspostInside the global tab settings box.

Template overrides

Two templates control the panel output: tab-heading.php and tab-panel.php. Copy either into yourtheme/product-tabs-studio/ to override it. The heading template can also be sidestepped entirely by setting the heading to hidden.

No wrapper element is added around the heading and the content. WooCommerce's own panel markup already carries a class ending in the tab key, which is what CSS should hook onto.

Endpoints and capabilities

The free plugin registers no REST routes, and its custom post type is not exposed in REST. Admin operations go through admin-ajax, and every handler checks a nonce and then a capability before it does anything: manage_woocommerce for settings, tools, migration, import and export; edit_products for the search and lookup endpoints used by the editors; and edit_product on the specific product for anything that reads or writes one product's tabs. There are no endpoints available to logged-out visitors.

The ptstudio_tab post type uses WooCommerce product capabilities, so shop managers and administrators can edit tabs and other roles cannot.

The plugin source is published on GitHub in the repository product-tabs-studio.