Display javascript as text in html (for tutorials and so on…)

To prevent your script to be interpreted, you will need to replace the opening and closing brakets with html code. They will be displayed correctly but the script within won’t get executed!

<script>//Inspect this element console.log(‘this code won’t get executed<br>nothing to see in the console! <br> Also did you notice the line did not break after the <br> elements? What is this sorcery? ‘)</script>

To check which code to use to replace a specific character, have a look at the following resource:

https://www.strictly-software.com/htmlencode

How to remove jquery.migrate.js in wordpress

Jquery.migrate is used to ensure compatibility with older jquery code using deprecated function.

In case your jquery is all shiny and new and you don’t use deprecated functions, then you can get the reed of jquery migrate and have one less file to load. As usual, we will do that by adding a function in the functions.php file of your theme:

function remove_jquery_migrate($scripts)
{
    if (!is_admin() && isset($scripts->registered['jquery'])) {
        $script = $scripts->registered['jquery'];
        if ($script->deps) { 
            // Check whether the script has any dependencies     
            $script->deps = array_diff($script->deps, array('jquery-migrate')); 
            }
      }
 } 
 add_action('wp_default_scripts', 'remove_jquery_migrate'); 

How to debug your wordpress function to the browser console

At time, it might be useful to debug some plugin or theme function directly in your browser console. It comes handy specially if you are sending some data live with jquery to a php function when you input something here and click some button there.

Add the following function to your theme functions.php:

//Send message to the web console

function debug_to_console( $data ) {
    $consoleLog = $data;
    if ( is_array( $consoleLog ) )
          $consoleLog = implode( ',', $consoleLog);
    echo '<script>console.log( "Debug Objects: ' . $consoleLog . '" );</script>';
 } 

Now you can add debug_to_console($data ) in your theme and plugins to check what value your variable take. Replace $data with whatever value you need to monitor.

Display wp plugins script and style handle

If you are serious about your site optimization, there will be a point where you want to control all these additional scripts and stylesheets your plugins are loading on your site.

To do so you will need to know the handle that is used to identified the said stylesheets and and scripts.

One easy way is to have it displayed front end in your test environment.

Add the following code to your theme function.php:

function get_enqueued_scripts () {

    $scripts = wp_scripts();

    echo 'Enqueued scripts:
';

    foreach( $scripts->queue as $handle ) :

        echo $handle.' | ';

    endforeach;

    echo '
';

}
 add_action( 'wp_head', 'get_enqueued_scripts', 9999 ); 

And to get the handles of the enqueued style sheets:

function get_enqueued_styles () {

    $styles = wp_styles();

    echo 'Enqueued styles:
';

    foreach( $styles->queue as $handle ) :

        echo $handle.' | ';

    endforeach;

}
 add_action( 'wp_head', 'get_enqueued_styles', 9999); 

In case you don’t have a test environment (really?) you can display this info in the console, don’t forget to disable that after you are done optimizing your site.

Defer the execution of javascript and load js files in the footer

In a previous article we have seen how to manually concatenate scripts in your main theme to avoid loading multiple files.

In case you can’t concatenate some scripts here are two options to defer the exectution of the script until after the page has fully loaded or simply load a php script in the footer rather than in the header of your page.

Defer the execution of a script:

For your inline scripts:

<script defer> your script</script>

And it is exactly the same when the scripts are in an external file:

<script src="/path/to/your/script" defer></script>

Execute a function in the footer instead of the header.

In one of my plugn I had the case where I needed to fetch all the categories and product variation in jquery plugin that allow live display and filtering for a given search string. As such, the jquery is prepared in a php file that I then included in my theme header with and include function. Until I realize I can as easily load the script in the footer and avoid to overload my header.

In the index.php file of the plugin:

add_action('wp_header', 'PluginName::functionName);

simply becomes:

add_action('wp_footer', 'PluginName::functionName);

functionName is your plugin function that contains the include statement that should be loaded in the footer.

Control what javascript and css files your wordpress plugins load.

Javascript and css can heavily impact your page load time and the ability of google bots to render your page. The consequence on your ranking might be heavy in case the page to be marked as not mobile friendly due to this rendering issue.

A solution is to reduce the number of css and js files your wordpress site loading.

As you have noticed, many plugins load their own css and js in order to perform their function and nicely display the output, which is perfectly legitimate, although it might not be desirable for a web designer concern with performance, as you ought to be ;)

I am pretty sure I don’t need to make the matter clear, as you are reading this article but just in case, let’s recall here that on top of impacting your SEO as stated above, there is a 5% drop in sales for each 0.1 sec of load time (I am not sure I state that correctly but you got the idea).

So, what the solution you may ask, rightfully, so let’s dig into that without any further delay.

The strategy we will explore here is to dequeue the plugin css and js and concatenate it to your theme js and cs

Dequeue a plugins javascript file or css stylesheet:

To dequeue the script you want to concatenate add the following code
in your theme functions.php :


add_action('wp_print_styles', 'deregister_styles', 100);

function deregister_styles() {
  wp_deregister_style('name-of-style');
}

Merge Javascript and styling with your existing files

Locate the style or js you have deregistered and copy and paste it’s content in your theme css or js.

Test your site thoroughly to make sure there is no conflict. Paste the code in your stylesheet in the order they are loaded on your page. Once you are sure everything is displaying properly, you might merge the style rules and remove the duplicated one in case there are.

There are more advance technique to load css such as css preprocessing. which we will cover in further articles.

More info on this excellent article:
https://davidwalsh.name/remove-stylesheets

Tips:

In order to make sure you are removing the right css files from the queue, use the developper tool of your browser and inspect the element related to your plugin, you will which css rules affect them and from what file they come from. Once you have noted the name of the css file you know which one you need to copy to your own css rules and remove from the queue.

Custom blade directive @isAdmin in Laravel 5.3+

  1. Create a is_admin column in your user database, only admin can register a user. Allow admin to register user as admin or not.
  2. Open user.php in the app folder and add use Illuminate\Support\Facades\Auth;
  3. Add the following function to the user class:
public function isAdmin()
{
    if (Auth::user() &&  Auth::user()->is_admin == 1) {
        return true;
    }
}

From there we can already check if user is admin in our view like this:

@if(Auth::user()->isAdmin())
    Something that should only be visible to admin
@endif

4. We would like to keep our code elegant so let’s add a custom directive to blade. Open AppServiceProviders.php and add the following code in the boot function:

namespace App\Providers;
 use Illuminate\Support\ServiceProvider;
 use Illuminate\Support\Facades\Schema;
 use Illuminate\Support\Facades\Blade;
 use Illuminate\Support\Facades\Auth;
 class AppServiceProvider extends ServiceProvider
 {
     /**
      * Register any application services.
      *
      * @return void
      */
     public function register()
     {
         Blade::if('isAdmin', function(){
             if(Auth::check())
                 return Auth::user()->is_admin===1?true:false;
             else return false;
         });
     }
 /**  * Bootstrap any application services.  *  
* @return void  */ 
public function boot() {
     Schema::defaultStringLength(191);
    // Blade custom directives for isAdmin
     Blade::directive('isAdmin', function() {
         return "<?php if(Auth::user()->isAdmin()): ?>";
     });
     Blade::directive('endisAdmin', function() {
             return "<?php endif; ?>";
     }); }
 }

From there you should be all set to use @isAdmin @endisAdmin in your blade view files.

In case it doesn’t work, make sure to test that @if(Auth::user()->isAdmin()) is working properly and revert back to your custom directive.

Content wider than screen in Google Search Console and Woocommerce site

I noticed some of my pages were marked as not mobile friendly with indication that some pages shows the following errors:

  • Content is wider than screen
  • Clickable elements too close together
  • Text too small to read

For a start, I’d like to deal with the Content wider than screen message as I think I have identified the cause of the issue. Woocommerce magnifier keep a full size picture of the product on the page with the following styling:

class="zoomImg" style="position: absolute; top: 0px; left: 0px; opacity: 0; width: 1000px; height: 1000px; border: none; max-width: none; max-height: none;"

We can see that the opacity is set to 0, so the picture is transparent and that the width and height are the picture full size in pixel.

So there is no mystery any longer on what element on the page generate the content wider than screen message.

Now that (at least one of) the culprit has been identified, we need to elaborate a fix. The first strategy that come to mind would be to resize the pic when it is transparent and only switch it to full size when the picture is magnified. This could be done by doing some overwriting of woocommerce files.

Remove component/virtuemart from search results’ URLs

To remove component/virtuemart from URL’s, all you need to do is to create a menu with all your category hierarchy.

It might occur that you want to keep your navigation menu simple and that choose to not put the sub categories (of the nth degrees) in your main menu. In that case URLs of the items in these subcategories will appear with the component/virtuemart part in their URL, which might lead to duplicate content issue and is not very tidy.

There are two solutions:

Solution 1: Hide sub-categories with css in your navigation menu.

Solution 2: create a hidden menu that reproduce the hierarchy of the main menu and add your sub-categories as child of their respective parent category there.

Note that you can’t two URL with the same alias, that means that in order to add the top levels categories that are already in your main menu you can’t use “Virtuemart > Category layout” as menu item type. Instead use “system links > URL” for all your category that are in your main menu. For the sub-categories you can use
“Virtuemart > Category layout” as usual. Remember to attribute the correct parent for each sub-categories to keep a clean navigation structure and avoid potential duplicat content.

It’s quite trivial but it took me a while to figure out so I thought I might as well share it with you.

Virtuemart Check default Radio Custom field.

The javascript for this is really simple:

radiobtn = document.getElementById("theid"); 
radiobtn.checked = true;

The difficulty will lie in the fact that the id of the element is changing depending on the product. Indeed the product id is used in the radio id.

A convenient option is to use CSS selectors in javascript:


radiobtn =document.querySelector(CSS selectors) .

We want to select the first radio input where the parent is div.controls

radiobtn =document.querySelector(" div.controls> label  > input");  
radiobtn.checked = true;

For good measure we should check that div.controls exists on the page and that we are on a product page.

if(document.querySelector(" div.controls > label  > input")){
radiobtn = document.querySelector(" div.controls > label > input");
radiobtn.checked = true;
}

This query only catch the first radio button custom field. In case we have a second custom field options for our product we need to catch that too. We will use jquery for that purpose to catch the radio button id whatever product page it is set on (remember that the product id is part of the radio button id and that’s the only changing part).

jQuery.noConflict();
jQuery(document).ready(function(){
if (jQuery(“[id$=_885843]”)){
jQuery(“[id$=_885843]”).prop(“checked”,true);
}
});

Repeat the operation for any additional custom fields needed a default check.