Guide

Save Your Design hooks

Save Your Design stores a configuration as a post, lets the customer come back to it, share it by link or email, and download it as a PDF. Its hooks split cleanly along those lines: the saved configuration post type, the share modal and its emails, and PDF generation.

See the hook reference index for how to register PHP and JavaScript callbacks.

PHP filters — PDF export

HookArgumentsPurpose
PC.syd.pdf_template.arguments$argsVariables passed to the PDF template
PC.syd.pdf_download.configuration_html$htmlThe rendered configuration inside the PDF
PC.syd.pdf_download.pdf_content$contentThe complete HTML handed to Dompdf
PC.syd.pdf_download.pdf_options$optionsThe Dompdf\Options instance
PC.syd.pdf_download.paper_size'A4'Paper size
PC.syd.pdf_download.orientation'portrait'Page orientation
PC.syd.pdf_download.svg.icon$iconIcon on the "Download PDF" button

PHP filters — sharing

HookArgumentsPurpose
syd_share_social_list$optionsWhich share destinations are offered
mkl_syd_get_social_media_url$link, $socialMediaThe share URL template for one destination
syd-email-share-fields$fieldsFields on the "share by email" form
mkl_pc_syd_share_field_output$html, $field, $fieldIdRendered markup for one share form field
PC.syd.share_link.svg.icon$iconIcon on the share button

PHP filters — saved designs

HookArgumentsPurpose
mkl_pc_configuration_taxonomiesarray()Taxonomies registered against the configuration post type
mkl_pc_syd_saved_designs_ppp10Saved designs listed per page
mkl_pc_syd_include_preset_price_in_listfalse, $productId, $typeWhether preset prices are included in the list
mkl_syd/my_account/config_thumbnail_size'thumbnail'Image size in the My Account list
mkl_syd/my_account/edit_config/product_url$url, $productWhere "edit" sends the customer
mkl_pc.syd.preset.product_url$urlProduct URL used by an admin preset
PC.syd.svg.icon$iconIcon on the "Save your design" button

PHP actions

HookArgumentsPurpose
save_your_design__before_register_post_type(none)Before the configuration post type is registered
mkl_pc_syd_send_email$configuration, $url, $dataA share email is about to be sent
mkl_pc_syd_share_modal(none)Inside the share modal markup
mkl_pc_syd/admin/configuration/edit$postBelow a saved configuration in the admin
mkl_pc_syd/admin/configuration/edit/choice$post, $layerBeside each choice in the admin
mkl_pc_syd_updated_plugin(none)The add-on finished its update routine
tmpl-pc-configurator-admin-bar--after(none)Template hook, after the preset admin bar

JavaScript

HookTypeArgumentsPurpose
PC.fe.pdf_datafilterdataThe payload sent to the PDF endpoint
PC.fe.pdf.max_dimensionfilter1200Largest edge, in pixels, of images in the PDF
syd_share_modal_sidefilter'left'Which side the share modal opens on
syd_share_modal_insert_targetfilter$targetThe element the share modal is inserted into
pc.fe.syd.setConfigactionconfigItemsA saved configuration was applied
PC.fe.syd.modal.initactionviewThe saved-designs modal was created
PC.fe.syd.modal.openactionviewIt was opened
PC.fe.syd.modal.closeactionviewIt was closed
PC.fe.syd.share.modal.initactionviewThe share modal was created

PC.syd.pdf_template.arguments

The variables handed to the pc-pdf-export/pdf.php template. This is the hook to use when you want extra data in the PDF — the template itself can be overridden in your theme the usual WooCommerce way, but it can only print what it is given.

php functions.php
add_filter( 'PC.syd.pdf_template.arguments', function ( $args ) {	$args['company_vat'] = get_option( 'my_company_vat' );	return $args;} );
PC.syd.pdf_template.arguments.

The array already carries _product, product_id, variation_id and the configuration data.

PC.syd.pdf_download.paper_size and …orientation

The two you will reach for most. Both are passed straight to Dompdf's setPaper().

php functions.php
add_filter( 'PC.syd.pdf_download.paper_size', function () {	return 'letter';} );add_filter( 'PC.syd.pdf_download.orientation', function () {	return 'landscape';} );
PC.syd.pdf_download.paper_size and …orientation.

Neither filter receives any context, so they apply to every PDF the site generates.

PC.syd.pdf_download.pdf_content and …pdf_options

pdf_content is the finished HTML, immediately before loadHtml() — the last chance to inject a header, a watermark or extra CSS. pdf_options is the Dompdf\Options object; remote images are already enabled and PHP execution is already disabled.

php functions.php
add_filter( 'PC.syd.pdf_download.pdf_content', function ( $content ) {	return str_replace( '</body>', '<div class="watermark">DRAFT</div></body>', $content );} );
PC.syd.pdf_download.pdf_content and …pdf_options.

Leave isPhpEnabled off. The PDF is built from customer-supplied configuration data, and turning it on would let that data execute.

PC.fe.pdf_data and PC.fe.pdf.max_dimension

The browser side of PDF export. PC.fe.pdf_data filters the whole payload — which already carries the configuration and, if Extra Price is active, the subtotal:

javascript custom.js
wp.hooks.addFilter( 'PC.fe.pdf_data', 'my-plugin/syd', function ( data ) {	data.customer_reference = document.querySelector( '#my-ref' ).value;	return data;} );
PC.fe.pdf_data and PC.fe.pdf.max_dimension.

PC.fe.pdf.max_dimension caps the longest edge of the images captured for the PDF, at 1200px by default. Raise it for print-quality output, at the cost of a much larger file and a slower request.

syd_share_social_list and mkl_syd_get_social_media_url

The first decides which destinations appear in the share modal — an array keyed by slug, with the label as the value. Remove entries to hide them, add one to introduce your own:

php functions.php
add_filter( 'syd_share_social_list', function ( $options ) {	unset( $options['reddit'] );	$options['pinterest'] = 'Pinterest';	return $options;} );add_filter( 'mkl_syd_get_social_media_url', function ( $link, $social_media ) {	if ( 'pinterest' === $social_media ) {		return 'https://pinterest.com/pin/create/button/?url={url}&description={share_text}';	}	return $link;}, 10, 2 );
syd_share_social_list and mkl_syd_get_social_media_url.

The URL is a template: {url} and {share_text} are replaced before use.

syd-email-share-fields

The fields on the "share by email" form. Each entry declares a label, type, order and — this is the important part — its own sanitize, escape and validate callbacks.

php functions.php
add_filter( 'syd-email-share-fields', function ( $fields ) {	$fields['syd-company'] = array(		'label'    => __( 'Company', 'my-plugin' ),		'type'     => 'text',		'order'    => 25,		'sanitize' => 'sanitize_text_field',		'escape'   => 'esc_html',		'required' => false,	);	return $fields;} );
syd-email-share-fields.

Always supply sanitize and escape. These fields are filled in by anonymous visitors and go straight into an email.

mkl_pc_syd_send_email

Fires just before the share email goes out, with the configuration object, the share URL and the assembled data (including a base64 QR code at $data['qrcode']).

php functions.php
add_action( 'mkl_pc_syd_send_email', function ( $configuration, $url, $data ) {	my_crm_log_share( $url );}, 10, 3 );
mkl_pc_syd_send_email.

mkl_pc_configuration_taxonomies

Taxonomies attached to the configuration post type at registration. Because it runs during register_post_type(), your taxonomy must already exist — register it on init at an earlier priority.

php functions.php
add_filter( 'mkl_pc_configuration_taxonomies', function ( $taxonomies ) {	$taxonomies[] = 'design_collection';	return $taxonomies;} );
mkl_pc_configuration_taxonomies.

Use save_your_design__before_register_post_type if you need to register the taxonomy at exactly the right moment.

mkl_syd/my_account/edit_config/product_url and …/config_thumbnail_size

Control the saved-designs list under My Account: where the edit link points, and which registered image size the thumbnails use.

php functions.php
add_filter( 'mkl_syd/my_account/config_thumbnail_size', function () {	return 'medium';} );
mkl_syd/my_account/edit_config/product_url and …/config_thumbnail_size.

PC.fe.syd.modal.init, .open and .close

The saved-designs modal lifecycle. init fires once when the view is created, open and close on every toggle. All three receive the Backbone view.

javascript custom.js
wp.hooks.addAction( 'PC.fe.syd.modal.open', 'my-plugin/syd', function ( view ) {	myAnalytics.track( 'saved_designs_opened' );} );
PC.fe.syd.modal.init, .open and .close.

Focus is restored to the triggering element on close, so avoid moving focus yourself in a close handler.

pc.fe.syd.setConfig

Fires after a saved configuration has been applied to the configurator, with the list of configuration items. Note the lower-case prefix — it is pc.fe.…, not PC.fe.…, unlike its neighbours.

javascript custom.js
wp.hooks.addAction( 'pc.fe.syd.setConfig', 'my-plugin/syd', function ( configItems ) {	console.log( 'restored', configItems.length, 'items' );} );
pc.fe.syd.setConfig.

syd_share_modal_insert_target and syd_share_modal_side

Positioning hooks for the share modal. insert_target is a jQuery object — return a different element to move the modal elsewhere in the DOM; the add-on logs a warning and gives up if it is empty. side is 'left' or 'right' and drives the CSS custom properties used for placement.

javascript custom.js
wp.hooks.addFilter( 'syd_share_modal_side', 'my-plugin/syd', function () {	return 'right';} );
syd_share_modal_insert_target and syd_share_modal_side.

mkl_pc_syd/admin/configuration/edit and …/edit/choice

Print extra information into the admin screen for a saved configuration — once per choice, and once after the list. $layer is an MKL\PC\Choice.

php functions.php
add_action( 'mkl_pc_syd/admin/configuration/edit/choice', function ( $post, $layer ) {	echo ' <em>' . esc_html( $layer->get_choice( 'sku' ) ) . '</em>';}, 10, 2 );
mkl_pc_syd/admin/configuration/edit and …/edit/choice.

Icon filters

PC.syd.svg.icon, PC.syd.share_link.svg.icon and PC.syd.pdf_download.svg.icon each supply the markup inside their respective button. All take the current icon and return markup, unescaped.

php functions.php
add_filter( 'PC.syd.pdf_download.svg.icon', function ( $icon ) {	return '<span class="dashicons dashicons-pdf"></span>';} );
Icon filters.

mkl_pc_syd_updated_plugin

Internal. Fires after the add-on's own update routine has run.

Other plugins' hooks it fires

The share emails extend WC_Email, so WooCommerce's woocommerce_email_header, woocommerce_email_footer, woocommerce_email_footer_text, woocommerce_is_email_preview and the dynamic woocommerce_email_main_content_{$id} all apply. Cloudflare Turnstile's cfturnstile_enqueue_scripts and cfturnstile_widget_disable are used when that plugin is active, and PC.fe.validate_configuration comes from the core plugin.