Hooks & Filters

The supported API for installed WordPress plugins that extend Lay Theme without changing theme files.

This is a developer reference. Only the functions and hooks listed here are part of Lay Theme's supported plugin API. Other hooks found inside the theme are implementation details and may change in an update.

This does not make your website publicly writable. These functions are not web endpoints and cannot be called by website visitors. They are available to server-side PHP code, normally inside a WordPress plugin installed by an administrator. The Browser Bridge does not gain additional permissions from this reference: its write operations remain restricted to authenticated administrators and continue to use the validate → confirm → apply workflow.

Before adding custom code, check whether AI Mode already supports the task. Project-specific PHP, scheduled jobs, exports, admin screens, custom URLs and new data models belong in a separate plugin. Learn how to expose that plugin safely to an AI assistant under Plugin Extensions.

Plugin Functions

FunctionPurpose
lay_ai_register_extension_provider( string $id, array $definition )Expose focused plugin resources and reversible actions to AI Mode.
lay_get_gridder_document( int $post_id, string $layout = 'desktop' )Read a normalized Desktop or Phone Gridder document.
lay_update_gridder_document( int $post_id, array $document, string $layout = 'desktop', string $source = 'plugin' )Save through Lay Theme normalization, preview generation and cache invalidation.
lay_get_content_context( int $post_id )Read the structured post context used by Liquid-compatible Custom Elements and Views.
lay_get_custom_field_group_values( int $post_id, string $group_id, bool $include_defaults = true )Read one native Custom Field group without accessing private meta.
lay_update_custom_field_group_values( int $post_id, string $group_id, array $values, bool $partial = true )Validate and save one native Custom Field group.
lay_prepare_gridder_rows( array $document, bool $cover_active = false )Prepare the canonical row objects for a Gridder document.
lay_get_gridder_rows_margin_css( array $document, array $rows, string $selector, bool $is_phone = false )Generate native row-gutter CSS for prepared rows.
lay_get_site_chrome_visibility( int $post_id )Read per-post site title, menu and footer visibility.
lay_update_site_chrome_visibility( int $post_id, array $visibility )Update per-post site title, menu and footer visibility.

AI Mode, Content Types, Gridder and Content

HookType and signaturePurpose
lay_ai_register_extensionsAction
do_action( $hook )
Register AI Mode extension providers.
lay_add_gridder_meta_boxes_toFilter
string[] $post_types
Add a registered WordPress post type to the native Gridder editor.
lay_gridder_post_typesFilter
string[] $post_types
Add a registered WordPress post type to every canonical Gridder consumer, including editor and frontend.
lay_ai_gridder_post_typesFilter
string[] $post_types
Advertise additional Gridder-capable post types to AI Mode.
lay_ai_writable_content_typesFilter
array<string,string> $aliases
Advertise an alias-to-post-type map as writable Lay content.
lay_custom_elements_liquid_post_typesFilter
string[] $post_types
Expose post types to Liquid collections and structured content context.
lay_gridder_documentFilter
array $document, int $post_id, string $layout
Filter a normalized Gridder document returned through the supported plugin helper.
lay_gridder_document_before_saveFilter
array $document, int $post_id, string $layout, string $source
Filter a plugin-supplied Gridder document before normalization and save.
lay_gridder_document_savedAction
int $post_id, array $before, array $after, string $source
React after a save from the editor, AI Mode or the supported plugin helper.
lay_gridder_prepared_rowsFilter
array $rows, array $document, bool $cover_active
Filter canonical prepared rows returned to a plugin.
lay_gridder_rows_margin_cssFilter
string $css, array $document, array $rows, string $selector, bool $is_phone
Filter native row-gutter CSS generated for a plugin layout.
lay_custom_field_group_valuesFilter
array $values, int $post_id, string $group_id, bool $include_defaults
Filter a Custom Field group returned through the supported plugin helper.
lay_custom_field_group_values_before_saveFilter
array $values, int $post_id, string $group_id, bool $partial
Filter validated Custom Field values before the supported plugin helper saves them.
lay_custom_fields_savedAction
int $post_id, string $group_id, array $before, array $after
React after native Lay Custom Field values were saved.
lay_content_updatedAction
int $post_id, string[] $areas, string $source
Receive a general notification after supported Lay content areas change.
lay_content_duplicatedAction
int $source_post_id, int $new_post_id
React after AI Mode duplicated a content item.
lay_content_contextFilter
array $context, int $post_id
Extend the structured content context returned to plugins.

Frontend, Styles, Elements and Navigation

HookType and signaturePurpose
lay_frontend_layout_responseFilter
array $layout, int $id, string $type, object $object
Filter the final structured frontend layout response.
lay_site_chrome_visibilityFilter
array $visibility, int $post_id, string $type
Control the site title, menus and footer for one frontend layout.
lay_site_chrome_visibility_savedAction
int $post_id, array $visibility
React after the supported plugin helper changes site chrome visibility.
laytheme_after_bodytagAction
do_action( $hook )
Output markup immediately after the opening body tag.
lay_after_navbar_markupFilter
string $markup
Append markup after Lay Theme navbar markup.
lay_mobile_menu_markup_before_ulFilter
string $markup
Insert markup before the mobile menu list.
lay_mobile_menu_markup_after_ulFilter
string $markup
Insert markup after the mobile menu list.
lay_shared_stylesFilter
string $css
Append CSS shared by Desktop, Tablet and Phone.
lay_desktop_and_tablet_stylesFilter
string $css
Append Desktop and Tablet CSS to the generated stylesheet.
lay_mobile_stylesFilter
string $css
Append Phone CSS to the generated stylesheet.
lay_phone_menu_styles_above_breakpointFilter
string $css
Append Phone Menu CSS above the configured breakpoint.
lay_phone_menu_styles_under_breakpointFilter
string $css
Append Phone Menu CSS below the configured breakpoint.
laytheme_video_element_markupFilter
string $markup, array $args
Filter native Gridder video element markup.
lay_thumbnail_tag_markupFilter
string $markup, int $post_id
Filter the opening tag markup of a project thumbnail.
lay_navigation_requires_full_page_loadFilter
bool $blocked, int $id, string $type
Require a full page load for a resolved navigation target.
lay_navigation_full_reload_page_idsFilter
int[] $post_ids
Provide post IDs that must use full-page navigation.

SEO and Media

HookType and signaturePurpose
lay_meta_enabledFilter
bool $enabled, int $post_id
Disable Lay Theme description and social meta output when a plugin owns those tags.
lay_meta_titleFilter
string $title, int $post_id
Filter the final HTML document title.
lay_meta_descriptionFilter
string $description, int $post_id
Filter the HTML meta description.
lay_og_tagsFilter
array $tags, int $post_id
Filter or replace the Open Graph property-to-content map.
lay_twitter_tagsFilter
array $tags, int $post_id
Filter or replace the Twitter name-to-content map.
lay_image_altFilter
string $alt, int $attachment_id, int $post_id
Filter image alternative text when Lay renders an attachment.

Common Examples

React once Lay content has been saved, regardless of whether the change came from the Gridder editor, AI Mode or a plugin:

add_action( 'lay_gridder_document_saved', function ( $post_id, $before, $after, $source ) {
	studio_sync_project_data( $post_id );
}, 10, 4 );

Replace selected SEO values without rewriting the final HTML:

add_filter( 'lay_meta_description', function ( $description, $post_id ) {
	return get_post_meta( $post_id, '_studio_description', true ) ?: $description;
}, 10, 2 );

add_filter( 'lay_image_alt', function ( $alt, $attachment_id, $post_id ) {
	return get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) ?: $alt;
}, 10, 3 );

Hide the standard Lay Theme chrome on one custom presentation:

lay_update_site_chrome_visibility( $presentation_id, array(
	'site_title' => false,
	'menu'       => false,
	'footer'     => false,
) );

Search and Cache

HookType and signaturePurpose
lay_search_placeholder_textFilter
string $placeholder
Change the frontend search input placeholder.
lay_search_post_typesFilter
string[] $post_types
Choose post types included in Lay Theme search.
lay_search_enable_hidden_projectsFilter
bool $enabled
Include projects hidden from the project overview in search.
lay_search_exclude_taxonomiesFilter
string[] $taxonomies
Exclude taxonomies from search metadata.
lay_search_custom_taxonomiesFilter
array $taxonomies, WP_Post $post
Filter custom taxonomy values collected for one search item.
lay_search_full_content_post_idsFilter
int[] $post_ids, string $query, string $language
Filter IDs used for full-content search matching.
lay_search_post_arrayFilter
array $items
Filter the complete normalized frontend search index.
lay_search_result_configFilter
array $config, int[] $thumbnail_ids
Filter search result rendering configuration.
lay_layout_cache_entry_allowedFilter
bool $allowed, int $layout_id, array $layout
Reject a stale or incompatible layout cache entry at read time.
lay_element_markup_cache_taxonomiesFilter
string[] $taxonomies
Add taxonomies whose changes invalidate cached element markup.

For AI Assistants

The Browser Bridge exposes the same reference as JSON through its authenticated AI Mode route. This is not a freely accessible website API. An authorized assistant can focus the reference by category, type, query or exact hook.

GET /wp-json/laytheme/v1/ai/hooks
GET /wp-json/laytheme/v1/ai/hooks?category=gridder
GET /wp-json/laytheme/v1/ai/hooks?hook=lay_content_updated

If the required event or input is missing, name the exact integration point and ask for a new supported plugin hook. Do not read private meta keys or modify Lay Theme files as a workaround.

Compatibility

if ( function_exists( 'lay_get_gridder_document' ) ) {
	$document = lay_get_gridder_document( $post_id, 'desktop' );
}

Guard Lay Theme helpers with function_exists() or class_exists(), fail gracefully on older versions, preserve unknown document properties, and use WordPress capability checks for every plugin write.