Skip to main content
Skip to main content

Developers Doc

Shortcodes: The Complete Developer Reference

10 mins read 6 Views 3+

Havenlytics shortcodes render property archives, grids, lists, featured listings, agent and agency directories, and the Agent Workspace SPA anywhere WordPress accepts a shortcode — posts, pages, widgets, and template do_shortcode() calls. This reference documents every canonical shortcode that ships in Havenlytics 3.3.1, its exact attributes and defaults, the output it produces, the handler class::method behind it, and the caching and filter hooks you can use to extend it.

Note: Every Havenlytics shortcode tag is prefixed hvnly_. If a tag is not listed on this page it is either a legacy alias (documented below) or it does not exist in the plugin — do not rely on undocumented tags.

How shortcodes boot

Havenlytics does not use a central shortcode registrar at runtime. Each property shortcode is a small service class that is instantiated when the frontend loads, and it registers itself in its own constructor.

The frontend service list in includes/Frontend.php instantiates each shortcode class (PropertySearchPropertyGridPropertyListFeaturedPropertiesPropertyAgentsPropertyAgencies). Every one of those classes extends AbstractShortcode, whose constructor calls add_shortcode():

<?php
// includes/Frontend/Shortcodes/AbstractShortcode.php (simplified)
abstract class AbstractShortcode {

    protected $tag;

    public function __construct() {
        // ...body-class + cache wiring...
        add_shortcode( $this->tag, array( $this, 'render' ) );
    }

    abstract public function render( $atts, $content = null );
}

Note: There is a Frontend\Shortcodes\Registry class in the codebase, but Registry::init() is never called. It is dead/dormant code. Shortcode registration happens entirely through the per-class AbstractShortcode::__construct() mechanism described above. Do not attempt to hook into Registry.

The Agent Workspace shortcode boots on a separate path: WorkspaceShortcode::register() calls add_shortcode( WorkspaceConstants::SHORTCODE, ... ), where WorkspaceConstants::SHORTCODE is hvnly_agent_dashboard.

Legacy alias tags are registered separately on the init action at priority 20 by Frontend\Shortcodes\LegacyCompatibility (covered under Legacy aliases).

Transient caching and body classes

AbstractShortcode gives every property shortcode two shared behaviours:

  • Body classes — the shortcode adds classes to the page <body> so themes can target pages that embed a Havenlytics shortcode.
  • Transient caching — rendered output is cached in a WordPress transient (default TTL 1 hour) under the cache group hvnly_shortcodes. Repeated renders of the same shortcode with the same attributes are served from cache instead of re-running the query.

Performance: Because output is cached under hvnly_shortcodes, changing a property, agent, or agency does not instantly change a cached shortcode render. Clear Havenlytics caches (for example via HVNLY_NAB()->clear_cache()) after bulk data changes, or wait for the 1-hour transient to expire.

Tip: The hvnly_featured_properties shortcode exposes a cache attribute (default yes). Set cache="no" during development so you always see fresh output.

Canonical shortcodes

hvnly_property_search

Renders the full property archive UI — filter sidebar plus results grid — using the content-archive-property template. Internally it swaps the main $wp_query to the plugin’s PropertyQueryExecutor so the archive template renders your filtered result set.

AttributeDefaultDescription
posts_per_page4Number of properties per page in the archive results.
class''Extra CSS class(es) added to the shortcode wrapper.
id''HTML id for the wrapper element.

Handler: PropertySearch::render — includes/Frontend/Shortcodes/PropertySearch.php:35

[hvnly_property_search posts_per_page="6" class="homepage-search"]

hvnly_property_grid

Renders properties as a responsive grid using the shortcodes/property-grid template. Builds a WP_Query with a tax_query and meta_query assembled from the taxonomy and meta attributes below — the most flexible query shortcode in the plugin.

AttributeDefaultDescription
posts_per_page12Properties per page.
columns3Grid columns, accepted range 16.
orderbydateOrdering field passed to WP_Query.
orderDESCSort direction (ASC / DESC).
featured_onlynoWhen yes, limit to featured properties.
show_paginationyesRender pagination controls.
show_results_countyesShow the “N results” count.
results_bar_positionbothWhere the results bar appears (topbottomboth).
idsComma-separated property IDs to include.
excludeComma-separated property IDs to exclude.
department / deptTaxonomy filter: department.
statusTaxonomy filter: property status.
property_type / typeTaxonomy filter: property type.
categoryTaxonomy filter: category.
locationTaxonomy filter: location.
feature / featuresTaxonomy filter: feature(s).
tag / tagsTaxonomy filter: tag(s).
badge / badgesTaxonomy filter: badge(s).
min_price / max_priceMeta filter: price range.
bedrooms / bedsMeta filter: bedrooms.
bathrooms / bathsMeta filter: bathrooms.
reception_rooms / receptionsMeta filter: reception rooms.
sqft / areaMeta filter: floor area.
garageMeta filter: garage.
year_builtMeta filter: year built.

Handler: PropertyGrid::render — includes/Frontend/Shortcodes/PropertyGrid.php:70

[hvnly_property_grid columns="4" posts_per_page="8" property_type="apartment" location="london" min_price="250000" order="ASC"]

hvnly_property_list

Identical query surface to hvnly_property_grid, but renders a single-column list using the shortcodes/property-list template. The columns attribute is forced to 1 regardless of what you pass.

Handler: PropertyList::render — includes/Frontend/Shortcodes/PropertyList.php:70

[hvnly_property_list posts_per_page="10" status="for-sale" orderby="date" order="DESC"]

Note: hvnly_property_list accepts every taxonomy and meta attribute listed for hvnly_property_grid. The only behavioural difference is the forced single-column layout.

hvnly_featured_properties

A subclass of PropertyGrid that forces featured_only=yes, so it always renders the featured-flagged listings. Pagination and the results count default to off, and it exposes an explicit cache toggle.

AttributeDefaultDescription
posts_per_page6Number of featured properties.
columns3Grid columns.
orderbydateOrdering field.
orderDESCSort direction.
categoryTaxonomy filter: category.
locationTaxonomy filter: location.
statusTaxonomy filter: status.
min_price / max_priceMeta filter: price range.
bedroomsMeta filter: bedrooms.
bathroomsMeta filter: bathrooms.
show_paginationnoRender pagination controls.
show_results_countnoShow the results count.
cacheyesToggle transient caching for this render.

Handler: FeaturedProperties::render — includes/Frontend/Shortcodes/FeaturedProperties.php:62

[hvnly_featured_properties posts_per_page="3" columns="3" location="manchester"]

hvnly_property_agents

Renders a searchable directory of agents (the hvnly_agent CPT) via the property-archive/partials/agents-archive template. It reads the ?s= (search) and ?view= (grid/list) query parameters from the request so the front-end search and view toggle work out of the box.

AttributeDefaultDescription
posts_per_page12Agents per page.
columns4Grid columns, range 14.
orderbytitleOrder by title or date.
orderASCSort direction.
show_headeryesRender the directory header.
title''Header title text.
subtitle''Header subtitle text.
show_searchyesRender the search box.
show_view_controlsyesRender the grid/list view toggle.
default_viewgridInitial view: grid or list.
classExtra wrapper CSS class(es).

Handler: PropertyAgents::render — includes/Frontend/Shortcodes/PropertyAgents.php:49

[hvnly_property_agents columns="3" title="Our Team" default_view="grid"]

hvnly_property_agencies

Renders an agency directory using the property-archive/partials/agencies-archive template. Agencies are sourced from AgencyArchiveQuery::query_agencies() (returns an array) rather than a plain CPT query. Same controls as the agents directory, with two differences: orderby accepts name or date, and the default header title is Real Estate Agencies.

AttributeDefaultDescription
posts_per_page12Agencies per page.
columns4Grid columns, range 14.
orderbynameOrder by name or date.
orderASCSort direction.
show_headeryesRender the directory header.
titleReal Estate AgenciesHeader title text.
subtitle''Header subtitle text.
show_searchyesRender the search box.
show_view_controlsyesRender the grid/list view toggle.
default_viewgridInitial view: grid or list.
classExtra wrapper CSS class(es).

Handler: PropertyAgencies::render — includes/Frontend/Shortcodes/PropertyAgencies.php:97

[hvnly_property_agencies columns="4" orderby="name" order="ASC"]

hvnly_agent_dashboard

Mounts the Agent Workspace single-page application. When WorkspaceAvailability::is_available() returns true, it prints the SPA mount element — <div id="{MOUNT_ID}">, where WorkspaceConstants::MOUNT_ID is hvnly-ws-root — using the dashboard template and fires the hvnly_workspace_enqueue_assets action so the Workspace JavaScript and CSS bundles load. When the Workspace is unavailable it renders an “unavailable” page instead. This shortcode takes no attributes.

Handler: WorkspaceShortcode::render — includes/Workspace/WorkspaceShortcode.php:69

[hvnly_agent_dashboard]

Note: hvnly_workspace_enqueue_assets is a real action hook fired by the Workspace shortcode. The Workspace asset service (WorkspaceAssets) subscribes to it to enqueue the SPA bundles. Add your own callback to it if you need to enqueue additional scripts only on the dashboard page.

Legacy aliases

Frontend\Shortcodes\LegacyCompatibility registers a set of older tag names on init (priority 20) that map onto the canonical shortcodes above. They exist so content authored against earlier plugin versions keeps working. Use the canonical tags for new content.

Legacy tagMaps to
hvnly_propertieshvnly_property_grid
hvnly_featuredhvnly_featured_properties
hvnly_property_search_formhvnly_property_search
hvnly_property_listshvnly_property_list
hvnly_property_listingshvnly_property_grid
hvnly_properties_gridhvnly_property_grid
hvnly_properties_listhvnly_property_list
hvnly_prop_gridhvnly_property_grid
hvnly_prop_listhvnly_property_list
hvnly_agentshvnly_property_agents
hvnly_agencieshvnly_property_agencies

Legacy attribute conversion

Legacy aliases also translate older attribute names onto their canonical equivalents before rendering:

Legacy attributeConverted to
per_page / num / limitposts_per_page
typeproperty_type
citylocation
bedbedrooms

Filters for extending shortcodes

Three filters let you change shortcode behaviour without editing plugin files.

FilterFires inPurpose
hvnly_property_grid_default_attsPropertyGrid.php:67Filter the default attribute array for hvnly_property_grid (and its subclasses).
hvnly_property_list_default_attsPropertyList.php:67Filter the default attribute array for hvnly_property_list.
hvnly_legacy_attribute_conversionLegacyCompatibility.php:141Filter the converted attribute array (receives the converted atts and the shortcode name).

Change the default number of columns for every property grid site-wide:

<?php
add_filter( 'hvnly_property_grid_default_atts', function ( $atts ) {
    $atts['columns'] = 4;   // default grid columns
    return $atts;
} );

Add your own legacy attribute conversion:

<?php
// $converted is the already-converted attribute array; $shortcode is the tag name.
add_filter( 'hvnly_legacy_attribute_conversion', function ( $converted, $shortcode ) {
    if ( isset( $converted['rooms'] ) ) {
        $converted['bedrooms'] = $converted['rooms'];
        unset( $converted['rooms'] );
    }
    return $converted;
}, 10, 2 );

Rendering a shortcode from PHP

Use the WordPress do_shortcode() function to embed a Havenlytics shortcode directly in a theme template:

<?php
// In a page template — render a 3-column featured grid.
echo do_shortcode( '[hvnly_featured_properties posts_per_page="3" columns="3"]' );

Best practices

  • Prefer the canonical tags (hvnly_property_gridhvnly_property_list, etc.) over legacy aliases for all new content.
  • Use the ids and exclude attributes on hvnly_property_grid for hand-curated listing rows rather than building custom queries.
  • Filter defaults with hvnly_property_grid_default_atts instead of repeating the same attributes across dozens of shortcodes.
  • Set cache="no" on hvnly_featured_properties only while developing; leave caching on in production.

Common mistakes

  • Hooking into Registry. It is dead code and never initialized — registration is done in AbstractShortcode::__construct().
  • Expecting columns to affect hvnly_property_list. The list shortcode forces a single column.
  • Expecting instant updates. Output is cached in the hvnly_shortcodes transient group for one hour; clear the cache after bulk edits.
  • Assuming hvnly_agent_dashboard takes attributes. It takes none; it mounts the SPA into #hvnly-ws-root.

Need more help?

Can't find what you're looking for? Our team and community are here to help you ship faster.