🎉 Black Friday Sale is Live: Flat 30% Off on all Products

How to Add Custom Fields as a Schema in Typesense for WooCommerce

The Typesense for WooCommerce plugin covers most of the basic requirements for a WooCommerce shop. Facet / Filters are an integral part for your customer shop experience.

The Typesense for WooCommerce covers most of the basics :

  • Categories
  • Product Attributes

But what if you have a shop that requires more. Lets say I have a vehicle listing part and would like to add the VIN number as product meta, or I want to add my own custom taxonomy. In this blog i’ll be covering how to

  1. Add New Fields to the Product Schema
  2. Add data to the documents ( in typesense )
  3. Showcase the new Filter on the frontend.

For our use case lets say we want to add a new Facet to the schema, lets call it “my_custom_facet”
First Step is to use the filter cm_tsfwc_product_fields to add this to the product schema.

function tsfwc_modify_schema( $fields ) {
		$fields[] = [ 
                             'name' => 'my_custom_facet', 
                             'type' => 'string[]', 
                             'facet' => true, 
                             'optional' => true 
                             ];

		return $fields;
}
add_filter( 'cm_tsfwc_product_fields', 'tsfwc_modify_schema' ] );

The filter provides the fields that are being used to create the Product Schema.
You can get all the info of Schema from the Typesense Documentation.
https://typesense.org/docs/0.25.2/api/collections.html#schema-parameters
https://typesense.org/docs/0.25.2/api/collections.html#field-types

The important thing to note here is the field types and what the Typesense server will accept.
In this case I am sending an array of strings.

After defining the Schema, the second part is to send the data to Typesense via cm_tsfwc_data_before_entry filter which allows you to either modify or in our case send additional data.

function format_data( $formatted_data, $product, $product_id ) {
  //according to the schema value must be a array of strings
  //you can use the $product_id to get post meta fields taxonomoy fields etc.
  $data = get_post_meta( $product_id, 'my_custom_facet', true);
  //e.g of accepted data = ['banana', 'apple', 'orange']
 if(!empty($data){
   $formatted_data['my_custom_facet'] = [ 'banana', 'apple', 'orange' ];    //use $data instead / i'm using a static array to showcase how the data should be.
 } 
 

  return $formatted_data;
}

When sending data to Typesense you have to be wary of what was defined in the schema or else the indexing process may return an error.

Now that you’ve modified the schema and we are now able to send the data to Typesense, for this modification to be implemented.

We’re almost there, the last step is to show this new Facet on the frontend. The Instant Search does not automatically pull in all available facets, this is to allow you to modify the facets and allow flexibility on how you display them ( perhaps you have want to show a range filter, or a range input ).

To do so, we need to specify how to show this on the frontend, and we can do this by using the cm_tsfwc_custom_attributes hook.

function tsfwc_your_custom_filter() { ?>
        <div
                data-facet_name="my_custom_facet"
                data-title="<?php echo __( "Filter by My Custom Facet", 'storefront' ); ?>"
                data-attr_label="<?php echo __( "Custom Facet", 'storefront' ); ?>"
                class="cm-tsfwc-shortcode-tags-attribute-filters"
                data-filter_type="refinementList"
                data-settings="<?php echo _wp_specialchars( json_encode( [ "searchable" => false ] ), ENT_QUOTES, "UTF-8", true ) ?>"
        ></div><?php //leaving a space here auto renders a p ( damn you autop )
	}
add_action( 'cm_tsfwc_custom_attributes', 'tsfwc_your_custom_filter' ] );

And there you have it, in 3 steps we’ve now added our own custom facet.
The finished code can be found here https://github.com/codemanas/tsfwc-addon which we’ll keep up to date and add more fun and useful changes in the future.

Leave a Reply

Your email address will not be published. Required fields are marked *