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
| Hook | Arguments | Purpose |
|---|---|---|
PC.syd.pdf_template.arguments | $args | Variables passed to the PDF template |
PC.syd.pdf_download.configuration_html | $html | The rendered configuration inside the PDF |
PC.syd.pdf_download.pdf_content | $content | The complete HTML handed to Dompdf |
PC.syd.pdf_download.pdf_options | $options | The 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 | $icon | Icon on the "Download PDF" button |
PHP filters — sharing
| Hook | Arguments | Purpose |
|---|---|---|
syd_share_social_list | $options | Which share destinations are offered |
mkl_syd_get_social_media_url | $link, $socialMedia | The share URL template for one destination |
syd-email-share-fields | $fields | Fields on the "share by email" form |
mkl_pc_syd_share_field_output | $html, $field, $fieldId | Rendered markup for one share form field |
PC.syd.share_link.svg.icon | $icon | Icon on the share button |
PHP filters — saved designs
| Hook | Arguments | Purpose |
|---|---|---|
mkl_pc_configuration_taxonomies | array() | Taxonomies registered against the configuration post type |
mkl_pc_syd_saved_designs_ppp | 10 | Saved designs listed per page |
mkl_pc_syd_include_preset_price_in_list | false, $productId, $type | Whether 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, $product | Where "edit" sends the customer |
mkl_pc.syd.preset.product_url | $url | Product URL used by an admin preset |
PC.syd.svg.icon | $icon | Icon on the "Save your design" button |
PHP actions
| Hook | Arguments | Purpose |
|---|---|---|
save_your_design__before_register_post_type | (none) | Before the configuration post type is registered |
mkl_pc_syd_send_email | $configuration, $url, $data | A share email is about to be sent |
mkl_pc_syd_share_modal | (none) | Inside the share modal markup |
mkl_pc_syd/admin/configuration/edit | $post | Below a saved configuration in the admin |
mkl_pc_syd/admin/configuration/edit/choice | $post, $layer | Beside 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
| Hook | Type | Arguments | Purpose |
|---|---|---|---|
PC.fe.pdf_data | filter | data | The payload sent to the PDF endpoint |
PC.fe.pdf.max_dimension | filter | 1200 | Largest edge, in pixels, of images in the PDF |
syd_share_modal_side | filter | 'left' | Which side the share modal opens on |
syd_share_modal_insert_target | filter | $target | The element the share modal is inserted into |
pc.fe.syd.setConfig | action | configItems | A saved configuration was applied |
PC.fe.syd.modal.init | action | view | The saved-designs modal was created |
PC.fe.syd.modal.open | action | view | It was opened |
PC.fe.syd.modal.close | action | view | It was closed |
PC.fe.syd.share.modal.init | action | view | The 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.
add_filter( 'PC.syd.pdf_template.arguments', function ( $args ) { $args['company_vat'] = get_option( 'my_company_vat' ); return $args;} );
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().
add_filter( 'PC.syd.pdf_download.paper_size', function () { return 'letter';} );add_filter( 'PC.syd.pdf_download.orientation', function () { return 'landscape';} );
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.
add_filter( 'PC.syd.pdf_download.pdf_content', function ( $content ) { return str_replace( '</body>', '<div class="watermark">DRAFT</div></body>', $content );} );
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:
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.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:
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 );
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.
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;} );
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']).
add_action( 'mkl_pc_syd_send_email', function ( $configuration, $url, $data ) { my_crm_log_share( $url );}, 10, 3 );
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.
add_filter( 'mkl_pc_configuration_taxonomies', function ( $taxonomies ) { $taxonomies[] = 'design_collection'; return $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.
add_filter( 'mkl_syd/my_account/config_thumbnail_size', function () { return 'medium';} );
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.
wp.hooks.addAction( 'PC.fe.syd.modal.open', 'my-plugin/syd', function ( view ) { myAnalytics.track( 'saved_designs_opened' );} );
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.
wp.hooks.addAction( 'pc.fe.syd.setConfig', 'my-plugin/syd', function ( configItems ) { console.log( 'restored', configItems.length, 'items' );} );
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.
wp.hooks.addFilter( 'syd_share_modal_side', 'my-plugin/syd', function () { return 'right';} );
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.
add_action( 'mkl_pc_syd/admin/configuration/edit/choice', function ( $post, $layer ) { echo ' <em>' . esc_html( $layer->get_choice( 'sku' ) ) . '</em>';}, 10, 2 );
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.
add_filter( 'PC.syd.pdf_download.svg.icon', function ( $icon ) { return '<span class="dashicons dashicons-pdf"></span>';} );
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.