Add shortcode with WordPress new content editor interface Gutenberg

You might have add difficulties to and errors when trying to add shortcode to new WordPress articles and posts.

To add a short code in the new editor, hover at the top center of an unactive block and click on the circled + icon that appears at its top center .

Adding a block above another one.

You can also click on the circled + icon at the top left corner of the page.

In the search bar type: shortcode

Click on the shortcode option. A new block will be added.

The shortcode block can be found under widgets in the block type selection box.

Type in your shortcode as you would do in the classic view:

[ShortCodeTag]

Note: I did encounter an error that the page couldn’t be saved when trying to save the page with the square brackets in WordPress 5.2.4. It turned out that the page was actually saved. This issue was supposed to be fixed already since 3.9 see github repo for wordpress gutenberg.

Change Product Available Date Format in Virtuemart

You might have noticed that virtuemart date format for the “Product Available Date” notice is in US format (at least for my install). This format (YYYY-MM-DD) is a bit confusing in countries where the standard is different, for instance the standard in Europe is DD-MM-YYYY.

Now we will attempt to display this product available date in our choosen standard.

In com_virtuemart/product/details/default.php, you can see that the part controlling the display of the product availability date is stockhandel.php in sublayouts

By consulting this file you can quickly locate the variable for the product availabity date string followed by the variable for the date string: DATE_FORMAT_LC4

Now that we have this information we can go in Extensions -> Languages->overrides

select your front end language on the drop down menu. Enter the variable and in text enter the date format you want to use.

A user friendly format might be: j F yy

This will yield a date in this format: 28 February 2020

Fluid inline-block VS grid system

Fluid inline-block products browsing page

The advantage of a fluid inline-block strategy to display product thumbnails is that the thumbnails will arrange themselves according to the screen size.

The drawback is that, if the images have various widths, their alignment will be completely jagged on a mobile display. In case the height varies, they will be jagged in large screen too, so it requires to use standard width and height. The length of the product name can also be a problem, pushing the next product card to the line below. For that reason, you want to have media query so that the card takes 80% of the width of the screen on the smallest screen size to have your products display on one column.

Last drawback for which I don’t have a solution yet is centering. The inline-block div will align left and if there is a gap on the right that is even one pixel too small for the next card, the space will be left blank. It’s up to you if you consider this acceptable or not.

Grid system

A grid system allows to keep everything nicely organized. The drawback is, for it to work, you will have to set break points to change your grid organization depending of the screen size. The number of screen size available on the market is already quite large and you want to check how your page will look on various display (first and foremost the most popular ones). But there will be new ratio of screen display coming up in the market that will be in between your existing break point and might break your carefully crafted design.

To avoid this issue, I style the website starting from the smallest screen currently on the market and then I use the “responsive” feature of the dev tool and change the screen size until the design “breaks”. That’s where I set my new break point and implement new rules.

All is perfect in the best possible world you would say, but I actually also like to use bootstrap framework and it has breakpoints on its own.

And if you are using other CSS framework they also comes with their own breakpoints and they might fit so well the latest device on the market, same if you use a theme you have not developped etc.

Another option is to use Flexbox.

Handling pictures display

Let’s summarize what we have seen regarding picture display:

Adapt the size of your picture by using souce set html element.

<picture>
 <source media="(min-width: 376px)" srcset="https://path/to/picture.jpg">
 <source media="(max-width: 375px)" srcset="https://path/to/picture.jpg"> 
 <img class="center" alt="alt text" src="https:// path/to/picture.jpg ">
</picture> 

Normalize the width and height of your picture

Normalize the width on your pictures. If slightly different picture width won’t look bad on a large screen, due to the width of the div being larger than the width of the picture, the picture grid might be completely jagged on a mobile display simply because the width of the div is not large enough to compensate for variation in the width of the pictures. That looks terrible. One reason you might want to have thumbnails of different width is when you have picture representing object of the same height but of different width. If you set the width to be the same on both type of object, the larger one might appear smaller (if you keep its proportion right, reducing its width will also reduce the heighth of the picture). It is not really desirable.

One colum display on small mobile screen

The second option that is used by most webshop is to switch to a one column display when the screen size goes below a certain point. That seems a sensible decision. The draw back is that you have to scroll through more “screens” to view all the products but at least you don’t have to dwarf large products compare to slim one or worse, have a completely jagged display.

Lazyload

Lazyload your picture, there are easy to use framework and the code is not difficult to implement.

Use large, high definition product pictures on product page

If you have an online store, people will want to check the product in detail: they will want to see the texture, the finish on the edges. Is it sharp or bezeled? etc. So give as much freedom as possible to your user to zoom in and look around your products, by having pictures of the product with different angles and zoom in some details.

Use webp

There are excellent solution available to serve webp to supporting browser without bothering with javascript. I recommend the Webp Express plugin for wordpress and webp on demand. For more options you can check my article on serving webp and jpeg2000.

Apache access log structure

Recommended reading:

https://httpd.apache.org/docs/2.4/logs.html

A typical access log structure looks as follow

LogFormat "%h %l %u %t \"%r\" %>s %b" common
CustomLog logs/access_log common

%h: IP of the visitor (it might be a VPN IP for instance).

%l RFC 1413 identity of the client (not check unless IdentityCheck set to On). Highly unreliable.

%u user id. If the document is not password protected, the value will be set to – as above.

%t The time the request was received

\”%r\” Request that the server received, between double quote. It starts with the method, then the requested resource, then the protocol (e.g. HTTP/2.0)

%>s The status code that the server sends back to the client

%b size of the object returned byt the server to the client.

Example:

213.18X.X.XXX – – [11/Oct/2019:11:52:08 +0300] “GET /index.phpXXXXXXX HTTP/2.0” 303 314 “https://example.com/” “Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36” (38FF183F-0.107)

You can see the two dash represented the fact that, for the first dash, the RFC 1413 identity is not used, and for the second, that the resource is public and no identification is requested.

Here you can see there are extra info after the size of the object returned. This indicates the server is using combined log format which goes as follow:

 "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" 

\”%{Referer}i\” being the referer (e.g. a link to your site on another web site or a form with a POST action to your server)

\”%{User-agent}i\” the user agent (e.g. the browser specification used to navigate your site)

In a more readable way, you will often see your access log as follow:

IP – – [DATE and TIME] “METHOD /URLREQUESTED PROTOCOL” SERVER_RESPONSE_CODE OBJECT_SIZE “REFERER_URL” “USER_AGENT”

Open chrome from command line

To start a new chrome window without any userl profile loaded run cmd and type:

start chrome

You can also simply call the run interface and type “chrome” then enter to have the same effect.

Now, more interesting, if you want to open a new chrome windows with an alternative profile, or simply a different user:

C:\Users\user1>runas /user:alternative_profile_name "C:\Program Files (x86)\Google\Chrome\Application\Chrome.exe"

replace “alternative_profile_name” with the user name you want to use. It is usefull if you engage in multilanguage SEO activity to have profile set with different languages as default. Or if you work in a different language that the one you use for your everyday account, you can have a “professional” profile setting with all the appropriate default.

You might also need to open Incognito window to check website without your browser cache. Emptying your cache everytime can be cumbersome, so you can simply open an incognito window:

start chrome /incognito

For that matter I rather use a Firefox developer installation set to not cache anything.

Adding Recaptcha to registration page on Laravel framework

In the app folder, create a Rules folder. Save the following code as GoogleRecaptcha.php:

<?php
namespace App\Rules;
use GuzzleHttp\Client;
use Illuminate\Contracts\Validation\Rule;
class GoogleRecaptcha implements Rule
{

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        $url='https://www.google.com/recaptcha/api/siteverify';
	$data = array(
       		'secret' => env('GOOGLE_RECAPTCHA_SECRET'),
		'response' => @$_POST['g-recaptcha-response']
        );
	$ch = curl_init($url);	
	curl_setopt($ch, CURLOPT_POST, 1);
	curl_setopt($ch , CURLOPT_POSTFIELDS, http_build_query($data));
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	$json = curl_exec($ch);
	curl_close($ch);
	$response = json_decode($json,true);
	var_dump($response);
	if ($response['success'] != false) {
		return 'success';}
	else{return false;}
	#$response= $obj ->{"success"};
	#var_dump($response[0]);
        #$response = $client->post('https://www.google.com/recaptcha/api/siteverify',
         #   [
          #      'form_params' => [
           #         'secret' => env('RECAPTCHA_SECRET_KEY', false),
            #        'remoteip' => request()->getClientIp(),
             #       'response' => $value
              #  ]
            #]
        #);
        #$body = json_decode((string)$response->getBody());
        #return $body->success;
    }
    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return 'Are you a robot?';
    }
}

In app/Http/Controllers/Auth/RegisterController.php

use App\Rules\GoogleRecaptcha;
/**
 * Get a validator for an incoming registration request.
 *
 * @param  array  $data
 * @return \Illuminate\Contracts\Validation\Validator
 */
protected function validator(array $data)
{
    return Validator::make($data, [
        'name' => 'required|string|max:255',
        'email' => 'required|string|email|max:255|unique:users',
        'password' => 'required|string|min:6|confirmed',
        'g-recaptcha-response' => ['required', new GoogleRecaptcha]
    ]);
}

Original code was with guzzle but it leads to the following issue:

Issue: “cURL error 60: SSL certificate problem: unable to get local issuer certificate (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)”

https://stackoverflow.com/questions/42094842/curl-error-60-ssl-certificate-in-laravel-5-4

in resources/views/auth/register.blade.php

Add in the registration form:

                      @if(env('GOOGLE_RECAPTCHA_KEY'))
                        <div class="form-group row">
                             <div class="g-recaptcha offset-md-4 col-md-6"
                                  data-sitekey="{{env('GOOGLE_RECAPTCHA_KEY')}}">
                             </div>
                         </div>
                       @endif

in the views/layouts/app.blade.php or in the register.blade.php files add the following line:

<script src="https://www.google.com/recaptcha/api.js" async defer></script>

In .env

GOOGLE_RECAPTCHA_KEY=site_key
GOOGLE_RECAPTCHA_SECRET=site_secret

to avoid issue with guzzle, let’s consider making the curl REST API call manually: https://weichie.com/blog/curl-api-calls-with-php/

$jsonurl =""
$curl_handle=curl_init();

The CURL manual call worked perfectly

Upload webp images to wordpress

wordpress and webp: “Sorry, this file type is not permitted for security reasons.”

Error message when uploading a webp image in wordpress media library

Certain image type like svg, jpeg2000 or webp raises an error when you try to upload them in wordpress as shown in the picture above.

We have already covered how to implement webp in wordpress but there might be some cases where you might want to upload this image manually and serve them to supporting browser via your own script if necessary (that’s not the case for svg though).

Add the following snippet of code to the functions.php file of your template. Comment out or delete the line for the mime type you are not interested in.

function add_mime_types( $mimes ) {
$mimes['webp'] = 'image/webp'; 
$mimes['svg'] = 'image/svg+xml';
$mimes['jpeg2000'] = 'image/jp2'; 
return $mimes; }
add_filter( 'upload_mimes', 'add_mime_types'  );

Troubleshoot BOM issue

BOM: Byte Order Mark

What does it look like:

On the page an invisible element push the html element out of there normal place, messing up alignment.

In the developper code, in firefox it looks like a red dot that display /ufeff on mouse hover.

In a php file it the BOM might cause the header to be sent prematurely, leading to a “header already sent” error.

What is the BOM and why does it causes issue:

BOM is usually invisible in browser but can cause issue by displacing html elements on the page.

W3 consortium write in their dedicated resource on BOM:

At the time this article was written, if you include some external file in a page using PHP and that file starts with a BOM, it may create blank lines.

This is because the BOM is not stripped before inclusion into the page, and acts like a character occupying a line of text. See an example. In the example, a blank line containing the BOM appears above the first item of included text.

https://www.w3.org/International/questions/qa-byte-order-mark#problems

The byte order mark is not present in UTF-8 but some text editor such as Microsoft notepad add it systematically (at the time of writing).

Solution to identify the file starting with BOM:

To find out the php file that included the BOM I SSH into the shared hosting, and found the file using this code: 

find -type f|while read file;do [ "`head -c3 -- "$file"`" == $'\xef\xbb\xbf' ] && echo "found BOM in: $file";done


I downloaded the file through FTP and encoded it in UTF-8 with notepad++ and uploaded back to the server.

Notepad++ offers to format the file in UTF-8 with or without the BOM in the encoding tab.