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.

Admin only register page in Laravel 5.2

All credits go to : https://stackoverflow.com/questions/36250746/how-to-protect-register-with-auth-midleware-in-laravel-5-2

Solution #1 (any authenticated user)

On file /app/Http/Controllers/Auth/RegisterController.php

simply change from

public function __construct()
{
    $this->middleware('guest');
}

to

public function __construct()
{
    $this->middleware('auth');
}

Solution #2 (only authenticated admin user) a) run

php artisan make:middleware IsAdmin

b) Add to the routeMiddleware array in your kernel file by opening app/Http/Kernel.php:

'admin' => \App\Http\Middleware\IsAdmin::class,

c) edit isAdmin file

public function handle($request, Closure $next)
{
     if (Auth::user() &&  Auth::user()->is_admin == 1) {
            return $next($request);
     }

    return redirect('/');
}

d) On file /app/Http/Controllers/Auth/RegisterController.php, change the constructor from

public function __construct()
{
    $this->middleware('guest');
}

to

public function __construct()
{
    $this->middleware('admin');
}

e) Update user migration to include a boolean field

Schema::create('users', function (Blueprint $table) {
    $table->mediumIncrements('id');
    $table->string('name');
    $table->string('email')->unique();
    $table->string('password');
    $table->boolean('is_admin')->default(false);
    $table->rememberToken();
    $table->timestamps();
});

f) Update User model to allow ‘is_admin’ field

protected $fillable = [
    'name', 'email', 'password', 'is_admin'
];

EU VAT ID for Woocommerce

Do you want to write your own VAT ID plugin for woocommerce?

Here are some useful link that will help you in this task and helped me succesfully add a custom VAT ID field in woocommerce checkout page. It checks if the VAT ID is valid and remove the VAT accordingly from the price:

1- Add a VAT ID field to the checkout page

https://www.wpdesk.net/blog/vat-eu-woocommerce/

Check the DIY part! You will need to edit the hook action with a proper hook so that the field display. https://businessbloomer.com/woocommerce-visual-hook-guide-checkout-page/

2- Perform the VAT ID validation

https://www.ptmr.io/blog/php-vies-vat-number-validation-european-vat-id/

3- Exempt customer from TAX if the EU VAT check out.

https://businessbloomer.com/woocommerce-remove-tax-checkout-field-value-exists/

4- refresh the total on change

Materialized: Select value not passed in post body

If you are using the materialize framework, you might have trouble to pass a value when using the select element in a form. Indeed the value is not taken into account. To solve this give an id to the select element and and add an hidden input field with the relevant field name and id as so:

<div class="row">             
<div class="input-field col s12">
<select id="data_select">
<option value="" disabled selected>Data</option> <option value="1">data 1</option>
<option value="2">data 2</option>
<option value="3">data 3</option> <option value="4">data 4</option> </select>
<input type="hidden" name="data_name" id="data_hidden" /> </div>
</div>

and with the associated script:

// Post Materialize select value$(document).ready(function() {
$('#data_select').on('change', function() {
var data_select=document.getElementById("data_select").value;
document.getElementById("data_hidden").value=data_select;

});

[Edit: everything worked fine simply using the following code:

<div class="row">             
<div  class="input-field col s12">                 
<select name="data_name"  id="data_select">                   
<option  value="" disabled selected>Data</option>                   <option  value="1">data 1</option>                   
<option  value="2">data 2</option>                   
<option  value="3">data 3</option>                  
<option  value="4">data 4</option>                 
</select>                 
</div>                       
</div>

]

WAMP Syntax error in INSERT INTO statement

Error : Syntax error in INSERT INTO statement

You might be using some reserved words as the table name.

Based on that article: https://support.microsoft.com/en-gb/help/892608/you-may-receive-a-syntax-error-in-insert-into-statement-error-message.

I tested by changing the name of the table from “orders” to orders_table and it solved the issue. I conclude that orders might be a reserved word.

Solution: change the table name to something else as illustrated above.

WP Plugins or Themes Update error: “Destination directory for file streaming does not exist or is not writable “

Check in wp-config.php which folder is assigned as the temporary directory. the line will start with

  
define('WP_TEMP_DIR', ABSPATH . '/path/to/temp');

Through ftp check the permission on the folder. It should be 755.

Even if all seems alright the update might still failed. In my case my wp-config.php is placed outside the public directory altogether. I decided to go with a temp folder also place outside of the public directoy, those I had to modify my wp-config.php (which is placed in its dedicated directory) as follow:

. I decided to go with a temp folder also place outside of the public directoy, those I had to modify my wp-config.php (which is placed in its dedicated directory) as follow:

define('WP_TEMP_DIR', ABSPATH . '/../temp/');

The path that was causing the error was as follow:

define('WP_TEMP_DIR',dirname(FILE).'/wp-content/uploads');

Placing the wp-config.php outside the public directory allow for an extra layer of security in case the php settings of the apache server get messed up and the php files are exposed instead of being executed. Even though this situation SHOULD NOT happen, there is a possibility that it does and that’s what security is about afterall: being prepared for the unlikely events.