Adding a custom field in a product page

1- Add a custom field in the backend

/**
*Add a custom field in the product data section of Woocommerce product.
*/
function cf_create_custom_field(){
 $args= array(
  'id'=>'custom_text_field_title',
  'label'=>__('Custom Text Field Title','cf'),
  'class'=>'cf-custom-field',
  'desc_tip'=>true,
  'description'=>__('Enter the description of your custom text field','cf'),
 );
woocommerce_wp_text_input($args);

}
add_action('woocommerce_product_options_general_product_date','cf_create_cutom_field');

You can find the list of accepted parameters here: https://github.com/woocommerce/woocommerce/blob/master/includes/admin/wc-meta-box-functions.php

Source: https://pluginrepublic.com/add-custom-fields-woocommerce-product/

/**
*Save the custom field
*/
function cf_save_custom_field($post_id){
  $product=wc_get_product($post_id);
  $title=isset($_POST['custom_text_field_title'])?$_POST['custom_text_field_title']:'';
  $product->update_meta_data('custom_text_field_title',sanitize_text_field($title));
  $product->save();
}
add_action('woocommerce_process_product_meta','cf_save_custom_field');
/*
*Display custom field on  the front end
*/
function cf_display_custom_field(){
  global $post;
  //Check for the custom field value
  $product=wc_get_product($post->ID);
  $title=$product->get_meta('custom_text_field_title');
  if ($title){
   //Only display our field if we've got a value for the field title
   printf(
   '<div class="cf-custom-field-wrapper"><label for ="cf-title-field">%s</label><input type="text" id="cf-title-field" name="cf-title-field" value=""></div>',
   esc_html($title)
   );
  }
}
add_action('woocommerce_before_add_to_cart_button','cf_display_custom_field');

Writing content

In case you have no idea about the content a page should have but you have to write it anyway, because you client absolutly want it or because there is an obvious use for such a landing page but you have no inspiration on the content, I present you with a methodology to write a text about a given topic whithout prior knowledge:

Take the few first search result pages and use it as inspiration for the page structure and content. Once you have an overview of the different elements that needs to feature on the page. You will have a better idea on how to layout the page.

With the example gathered from to pages you can now write a text that presents your topic/product/category correctly, using appropriate keyword and satisfying customer expectation and ansewering customer intent.

Even if the pages you use for inspiration or as source were ranking well they might be overooking important keyword or not be fully satisfying for the customer. So don’t hesitate to take further step in order to write better text using a more engaging layout.

Consult your analytic to find for user query using the target keyword(s) to check if customer have recurring question or associate your keyword with specific adjectives or query.

What is a “Final Class” in php?

“PHP 5 introduces the final keyword, which prevents child classes from overriding a method by prefixing the definition withΒ final. If the class itself is being defined final then it cannot be extended”

https://www.php.net/manual/en/language.oop5.final.php#:~:text=PHP%205%20introduces%20the%20final,then%20it%20cannot%20be%20extended.&text=Note%3A%20Properties%20and%20constants%20cannot,may%20be%20declared%20as%20final.

Add pagination to WordPress archives or search results.

There are several options to do so.

Here are two exemples, on being taken from the twentyfifteen template.

The class is to apply woocommerce styling in case you are using it.

      <div>
         <nav class="woocommerce-pagination bt_search_pagination"> <?php
          // Previous/next page navigation.

          the_posts_pagination(

              array(

                  'prev_text'          => __( 'Previous page', 'twentyfifteen' ),

                  'next_text'          => __( 'Next page', 'twentyfifteen' ),

                  'before_page_number' => '<span class="meta-nav screen-reader-text">' . __( 'Page', 'twentyfifteen' ) . ' </span>',

              )

          );?> 
      </nav></div>
 

A second example more compact:

     <div class="row">
          <div class="col-md-12 text-center">
              <nav class="woocommerce-pagination bt_search_pagination"><?php echo paginate_links(); ?></nav>
          </div>
      </div>

You can add this code in search.php or catregory.php

Remove base for category permalink in woocommerce

TLDNR: Not advisable

I have this idea that longer URI path, or deeper “file hierarchy” would have a negative SEO impact. But recently John Mueller made a statement that URI length did not have any negative SEO impact. The most important thing is that your important page are easily accessible to the search engine, and probably to your customer too.

In this article, Search Engine Journal speaks about length and recommend to keep it short but it’s an extrapolation on what J. Mueller said regarding URI longer than 1000 characters may not be a good practice (which is different from: “the shorter, the better”).

https://www.searchenginejournal.com/googles-john-mueller-recommends-keeping-urls-under-1000-characters/318739/#:~:text=Google’s%20John%20Mueller%20recently%20stated,under%201%2C000%20characters%20in%20length.&text=With%20that%20said%2C%20it’s%20generally,than%20they%20need%20to%20be.

In a more recent tweet, John was clear about that point:

https://www.seroundtable.com/google-url-length-seo-28952.html

Given that woocommerce does not recommend to remove the product-category base from the permalinks and that there is no clear SEO SEO advantage to it, then there is no reason to implement this feature.

If anything you can implement the option to have the product category included in your product permalink for SEO purpose. Having the product category in your URL might help google identify which category your product belong to and helped it rank for those keywords.

How a wordpress page is generated

https://codex.wordpress.org/Query_Overview

https://web.archive.org/web/20170524181634/http://humanshell.net/2011/08/wordpress-initialization

All http query to the webserver are send to index.php (this is not a redirect as the rule don’t use the redirect flag [R]) in the root folder. The redirect occurs in .htaccess with mod_rewrite

mod_rewrite operate by using a PCRE* regular expression

*PCRE: Perl Compatible Regular Expression

This operation retains the original URI that can be requested with $_server[‘REQUEST_URI’]

Below is the cascade of file that are succesfully called from index.php (up the 5th level but it needs to be expanded)

index.php

set the constant ‘WP_USE_THEMES’ to true and require wp-blog-header.php

wp-blog-header.php

execute wp(). This function is defined in functions.php

requires wp-load.php and template-loader.php

wp-load.php AND template-loader.php

wp-load.php requires wp-config.php

wp-load.php set the constant ‘ABSPATH’

wp-config.php requires wp-settings.php

wp-settings.php

requires:

  • version.php
  • load.php
  • class-wp-paused-extensions-storage.php
  • class-wp-fatal-error-handler.php
  • class-wp-reccovery-mode-cookie-service.php
  • class-wp-recovery-mode-key-service.php
  • class-wp-recovery-mode-link-service.php
  • class-wp-recovery-mode-email-service.php
  • class-wp-recovery-mode.php
  • error-protection.php
  • default-constant.php
  • plugin.php

and also:

  • compat.php
  • class-wp-list-util.php
  • formatting.php
  • meta.php
  • functions.php
  • class-wp-meta-query.php
  • class-wp-matchesmapregex.php
  • class-wp.php
  • class-wp-error.php
  • pomo/mo.php

and most of wordpress as well:

  • class-wp-walker.php
  • class-wp-ajax-response.php
  • capabilities.php
  • class-wp-roles.php
  • class-wp-role.php
  • class-wp-user.php
  • class-wp-query.php
  • query.php
  • class-wp-date-query.php
  • theme.php
  • class-wp-theme.php
  • template.php
  • class-wp-user-query.php
  • class-wp-session-tokens.php
  • class-wp-user-meta-sessions-tokens.php
  • class-wp-metadata-session-tokens.php
  • class-wp-metadata-lazyloader.php
  • general-template.php
  • link-template.php
  • author-template.php
  • post.php
  • class-walker-page.php
  • class-walker-page-dropdown.php
  • class-wp-post-type.php
  • class-wp-post.php
  • post-template.php
  • revision.php
  • post-formats.php
  • post-thumbnail-template.php
  • category.php
  • class-walker-category.php
  • class-walker-category-dropdown.php
  • category-template.php
  • comment.php
  • class-wp-comment.php
  • class-wp-comment-query.php
  • class-walker-comment.php
  • comment-template.php
  • rewrite.php
  • class-wp-rewrite.php
  • feed.php
  • bookmark.php
  • bookmark-template.php
  • kses.php
  • cron.php
  • deprecated.php
  • script-loader.php
  • taxonomy.php
  • class-wp-taxonomy.php
  • class-wp-term.php
  • class-wp-term-query.php
  • class-wp-tax-query.php
  • update.php
  • canonical.php
  • shortcodes.php
  • embed.php
  • class-wp-embed.php
  • class-wp-oembed.php
  • class-wp-oembed-controller.php
  • media.php
  • http.php
  • class-http.php
  • class-wp-http-streams.php
  • class-wp-http-curl.php
  • class-wp-http-proxy.php
  • class-wp-http-cookie.php
  • class-wp-http-encoding.php
  • class-wp-http-response.php
  • class-wp-http-requests-response.php
  • class-wp-http-requests-hooks.php
  • widgets.php
  • class-wp-widget.php
  • class-wp-widget-factory.php
  • nav-menu.php
  • nav-menu-template.php
  • admin-bar.php
  • rest-api.php
  • rest-api/class-wp-rest-server.php
  • rest-api/class-wp-rest-response.php
  • rest-api/class-wp-rest-request.php
  • rest-api/endpoints/class-wp-rest-controller.php
  • rest-api/endpoints/class-wp-rest-posts-controller.php
  • rest-api/endpoints/class-wp-rest-attachments-controller.php
  • rest-api/endpoints/class-wp-rest-post-types-controller.php
  • rest-api/endpoints/class-wp-rest-post-statuses-controller.php
  • rest-api/endpoints/class-wp-rest-revisions-controller.php
  • rest-api/endpoints/class-wp-rest-autosaves-controller.php
  • rest-api/endpoints/class-wp-rest-taxonomies-controller.php
  • rest-api/endpoints/class-wp-rest-terms-controller.php
  • rest-api/endpoints/class-wp-rest-users-controller.php
  • rest-api/endpoints/class-wp-rest-comments-controller.php
  • rest-api/endpoints/class-wp-rest-search-controller.php
  • rest-api/endpoints/class-wp-rest-blocks-controller.php
  • rest-api/endpoints/class-wp-rest-block-renderer-controller.php
  • rest-api/endpoints/class-wp-rest-settings-controller.php
  • rest-api/endpoints/class-wp-rest-themes-controller.php
  • rest-api/fields/class-wp-rest-meta-fields.php
  • rest-api/fields/class-wp-rest-comment-meta-fields.php
  • rest-api/fields/class-wp-rest-post-meta-fields.php
  • rest-api/fields/class-wp-rest-term-meta-fields.php
  • rest-api/fields/class-wp-rest-user-meta-fields.php
  • rest-api/search/class-wp-rest-search-handler.php
  • rest-api/search/class-wp-rest-post-search-handler.php
  • class-wp-block-type.php
  • class-wp-block-styles-registry.php
  • class-wp-block-type-registry.php
  • class-wp-block-parser.php
  • blocks.php
  • blocks/archives.php
  • blocks/block.php
  • blocks/calendar.php
  • blocks/categories.php
  • blocks/latest-comments.php
  • blocks/latest-posts.php
  • blocks/rss.php
  • blocks/search.php
  • blocks/shortcode.php
  • blocks/social-link.php
  • blocks/tag-cloud.php

Formatting results from Google Search Console API

Issue: using python, google search console API csv lines starts all with the following string

 b'\xef\xbb\xbf2019-04-20'

Solution:

The \xef\xbb\xbf is the BOM. It came here because I was actually encoding the result in utf-8-sig instead of utf-8. Just make sure to properly encode the returned strings in utf-8 and this won’t bother you.

So after this correction we are left with the following:

 b'2019-04-20'

This indicates that the date (which is the key) is actually of type bytes and not of type string.

To solve this just make sure to decode the bytes to string with the following code:

key.decode('utf-8')

Sources of keywords

Google Search Console

It gives you queries for which Google Search returned your site as a result

Google Ad Keyword ideas

Primarily meant to find ideas for your Google Ad campaigns, it is a good source of keyword ideas for your SEO. In addition you can evaluate the value of the keyword thanks to volume forecast, recommended minimum biding and competition evaluation.

Latent Semantic Analysis

If the two sources of keyword above are based on user query (the most important) we can also extract valuable keywords from the site already online. Latent semantic analysis allow to find the most statistically significant keyword in a group of pages compared to a larger set of document which is suppose to be representative of the frequence of the words in the language.

Quality of the results yielded by this method depends greatly on the dataset and on the quality of the content for the specific topic you want to analyse. Topic with poor description and little written content (and no SEO effort ) are likely to yield poor results.

Evaluating the quality of the result of the LSA and optimizing the process to extract the maximum information will require some adjustement: is lemmatization a good idea for n-grams? Doesn’t it make results more difficult to analyze? Lemmatization was suppose to strengthen the presence of a given word by aggregating all its different forms in its unic lemma.

A possibility to evaluate the quality of the subset for the topic is to check how much words from the two first lists (after lemmmatization if necessary) are present in the documents. If little are found, it tends to indicate that this field is not optimized toward user query and possibly that little attention is given to the content, or that the content and the user queries for this topic are “disconnected” and that we have a good opportunity to fill the gap.

Override locotranslate translation strings

If you want to override some loco translate strings, you might have noticed a warning stating that changes to the file might be lost after wordpress/plugin/template update.

Let’s see how to avoid losing all your customization during the next update.

In Loco Translate select the plugins/theme/etc that you want to customize.

Hover over the the language you want to make changes to and click on copy.

Loco Translate let you create a copy of a translation file.

Note that system, on the right end of the picture above indicates that this is a system file and prone to be overwritten during the next update.

Once you have clicked on copy you are brought to a screen to set a new language. Well, good news, it doesn’t have to be a new language at all and you can create a copy of a file for an existing language. Let’s have a look at the settings.

Loco translate “New language” screen.

1- Choose the target language, in our case this is the one of the file we copied.

2- For the location, the most sensible is the custom location. System and Author might be subject to changes from update.

3- For the templates option use the “Just copy English source strings” option and changes just what you need, the rest will fallback safely on the string in the original file. If you have already make your change directly in the original then you can choose the first option.

Once you are all set, click on start translating.

If you need to edit your custom copy. Click on “Languages” in the Loco Translate menu. Choose the languagefor which you have created the copy you want to modify. You will see all templates available under WordPress Core , Plugins and Themes for this language. Look for the name of the plugin or theme you have modified. The original file will be listed as system and your copy will be listed as custom. Click on edit.