Some time ago I needed to create an online store on WordPress. There are many good solutions in the official repository. Among them, the leader - Woocommerce has long stood out. I think he does not need an introduction. A multimillion army of users, hundreds of paid and free extensions and incredible flexibility. This is why Woocommerce has over 5 million active installations and covers a large share of online stores worldwide.
Still, I decided to invent my bike. Partly, to upgrade skills, partly to try to make a non-resource-intensive and fast enough ecommerce plugin. I recently posted it
in the official repository , therefore, I invite everyone to test it. In this article I will not do an overview of the possibilities, but I will only talk about some interesting technical solutions.
Permalinks Problem
In general, permalinks in WordPress are one of the most difficult sites, as they require solving a number of problems of connections and dependencies. WpStore has the ability to manage permalinks. For example, you can remove the
product
slug from the
product
url, change to your own or add the category slug or even category nesting to it. Links to products may look like this:
./-/---/---/-/
. Not bad.
I had to sweat a lot to get categories nesting. Using the
wp_get_object_terms,
function
wp_get_object_terms,
we obtain the categories of the specified product, and then in the cycle we collect the weaknesses and form the url hierarchy from parent to child. To display the necessary links we use the post_link filter. Here is just part of the code (you can see the full code in the source):
add_filter( 'post_link', 'wpsl_post_type_permalink', 20, 3 ); add_filter( 'post_type_link', 'wpsl_post_type_permalink', 20, 3 ); function wpsl_post_type_permalink( $permalink, $post_id, $leavename ) { .... if ( is_admin() ) {
But at this point, a performance problem arose. The site began to work more slowly, especially on the output page of several products. For example, on the category page with the output of only 16 products, almost 90 queries were made to the database and the server response time increased dramatically by about 25-30%.
It turned out that when calling
the_permalink function
, WordPress performs many operations: it gets the type of CNC and collects the
post data depending on this type. To display 1 link WordPress produces several non-cached requests to the database. Moreover, the process of obtaining taxonomies and hierarchies of goods is not the fastest.
Since the constant generation of the link does not suit us, it is logical to store it somewhere and then just pull it from there. It was decided to use the special
guid
field of the
guid
table. Although WP developers do not recommend changing it, we can still ignore this warning for several reasons:
- guid is used to generate RSS, and few people use it.
- only entries are displayed in RSS, and our post type is product.
In order to keep the links in the database correctly, we
save_post
function on the
save_post
event that updates the guid field:
add_action( 'save_post', 'wpsl_guid_rewrite', 100 ); function wpsl_guid_rewrite( $id ) { if( !is_admin() ) return; if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return false; if ( strpos( get_option( 'product_permalink' ), '%category%' ) !== false || strpos( get_option( 'product_permalink' ), '%categories%' ) !== false ) { if( $id && get_post_type( (int)$id ) == 'product' ){ global $wpdb; $wpdb->update( $wpdb->posts, [ 'guid' => ( get_permalink( $id ) ) ], [ 'ID' => intval( $id ) ] ); } clean_post_cache( $id ); } }
We
post_type_link
have to intercept the output of the link on the
post_type_link
hook and output the generated link:
add_filter( 'post_type_link', 'wpsl_get_permalink_change', 10, 4 ); function wpsl_get_permalink_change( $post_link, $post, $leavename, $sample ){ if ( isset( $post->guid ) && $post->guid && $post->post_type == 'product' && ( strpos( get_option( 'product_permalink' ), '%category%' ) !== false || strpos( get_option( 'product_permalink' ), '%categories%' ) !== false ) ) { return $post->guid; } return $post_link; }
Here we check the completeness of the guid field, post type and CNC type. If the values โโof the three parameters suit us, display the previously saved link.
Now, the best part is: look at the results. The number of queries to the database decreased by almost 2 times - from almost 90 to 44! And the server response time on the test hosting dropped to an acceptable 0.24 seconds.
Updating the guid field occurs not only during the creation and editing of goods. The plugin has a built-in system for importing goods through csv, so the update also occurs when the import is complete.
Update:
plugin documentation