How to reinstall WordPress via WP-CLI

You can easily reinstall WordPress on an existing site using WP-CLI with this command:

wp core download --skip-content --force

It’s important to note the two parameters:

[–skip-content]: Download WP without the default themes and plugins.
[–force]: Overwrites existing files, if present. We want this in order to overwrite any corrupted or infected files.

Read more: wp core download – WP-CLI

How to extract attributes from an HTML string in PHP (without using RegEx)

Say you have an <a>, <link> or other HTML element and you need to extract its href (or other) attribute. You can extract those values using DOMDocument quite easily:

$custom_font = '<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;700&display=swap" rel="stylesheet">';

$link = $custom_font;
libxml_use_internal_errors(true);
$dom = new DOMDocument();
$dom->loadHTML($link);
foreach ($dom->getElementsByTagName("link") as $a) {
    echo $a->getAttribute("href");
}

HTML’s forgotten native accordion: styling the details/summary element

As frontend developers or designers, many times we’re requierd to design or implement accordion-style components. While there are plenty of libraries out there, the easiest way to accomplish the same results without adding bloat is to use the <details> HTML element.

The HTML Details Element (<details>) creates a disclosure widget in which information is visible only when the widget is toggled into an “open” state. A summary or label can be provided using the <summary> element.

<details> on MDN

Out of the box, the details element looks pretty decent, but not really appealing:

12319

Styled details

12319

Further styling

Here’s another version, very similar to what I had to implement for a client:

See the Pen details styled by Nacho Toledo (@iign) on CodePen.12319

Notice how you can also change the default disclosure widget (the little arrow/triangle), by using the list-style property or the ::-webkit-details-marker pseudo-element selector for Chrome based browsers.

In this case, I’m removing the disclosure widget altogether and using a pseudo-element to display a chevron. I also added a subtle animation to flip it on expand/collapse.

A note on Firefox vs Webkit

On Webkit-based browsers you can declare summary::-webkit-details-marker { display: none; } to hide the marker. However, on Firefox you need this declaration summary { list-style-type: none; }

LocalWP styled FAQs

I came across this beautiful and subtle implementation on the pricing page of the Flywheel site. Interestingly, they’re actually using <dl> and <dt> tags instead of a <detail>, which would seem semantically more correct. Also, looking at their HTML I see they refer to it as an accordion item (<dl class="accordion">).

See the Pen details reveal widgets — Flywheel style by Nacho Toledo (@iign) on CodePen.12319

Other stuff and behaviour

Of course, you could add some JavaScript on top of this to collapse other elements on click, to make it behave more like a traditional accordion. However, I think that’s often not necessary or even expected from the user’s point of view.

Useful links

How to maintain the aspect ratio of an element with CSS

As Una Kravets announced on Twitter, we can now set an aspect ratio to any HTML element via CSS, without any padding hacks. This is still an experimental feature so support is still not great.

To test this feature, go to chrome://flags in Chrome Canary and enable Experimental Web Platform Features.

Here’s a quick Pen on how to implement this:

See the Pen Aspect ratio in CSS by Nacho Toledo (@iign) on CodePen.12319

On supported browsers, you should see something like this:

With this feature comes also a set of media queries, such as min-aspect-ratio, max-aspect-ratio and aspect-ratio:

/* Force an aspect ratio of 1:1 */
.square {
  aspect-ratio: 1/1;
}

/* Force an aspect ratio of 3:2 */
.photo {
  aspect-ratio: 3/2;
}

/* aspect-ratio media query */
@media (aspect-ratio: 1/1) {
  .element {
    background: gold;
  }
}

Further reading

How to convert JPGs to WebP automatically

The easiest way to convert a ton of JPGs to WebP is to use the cwebp command line utility written by the WebP team. Here’s how I do it using a very simple Bash script:

for f in `find ./source/uploads -name *.jpg` ; do
	dir=$(dirname "$f")
    filename=$(basename -- "$f")
    extension="${filename##*.}"
    filename="${filename%.*}"
    cwebp -q 90 $f -o $dir/$filename.webp;
done

This goes through all JPG files in ./source/uploads folder, converts them with a 90% quality rate and writes the output to the same origin.

How to convert SVG files to PNG automatically

A few weeks after the designer handed off about 500 tidy little icons, some customer requested PNG versions for all those.

Of course one option would be to export all again in PNG format. While possible, I wanted to simplify the designer’s job after creating new icons: hand off the SVGs and we’ll take care of the rest. After researching some alternatives, I ended up implementing this in Bash, using rsvg-convert from librsvg.

Install librsvg in macOS

brew install librsvg

The following script goes through all .svg files in a particular /files folder and converts them to a 400 width PNG file, if a PNG file does not already exist:

#!/bin/bash
# File: convert_to_png.sh

for f in ./files/*.svg; do
  
  filename=$(basename -- "$f")
  extension="${filename##*.}"
  filename="${filename%.*}"

  if test -f "./files/$filename.png"; then
    echo "$filename already exists. Skipping."
  else 
    echo "Converting" `basename $f`
    rsvg-convert $f -o ./files/$filename.png -w 400
  fi

done

Make sure you have permissions to execute the file:

chmod +x convert_to_png.sh

And run it:

./convert_to_png.sh

Useful links

Enable Custom Post Order via code in WordPress

Recently I enabled the great Simple Custom Post Order (SCPO) plugin in a bunch of sites. After you activate it you can go into its settings and enable sorting for all posts, custom post types, taxonomies, etc.

We had a particular case though. At my current job, we manage a network of nearly 200 WordPress sites. It makes no sense logging to 200 sites’ admin to update their values. In every site, we needed to

  1. Upload and activate SCPO.
  2. Enable sorting for categories only.

First one can be handled by ManageWP or other remote-access tools. The second seemed a bit more tricky. There’s not much documentation, since the plugin works great out of the box.

I asked this question in the forum and after that and a bit of digging into the code and database, I found a solution:

SCPO options are stored in wp_options table, under scporder_options name. In other words, you can manipulate it using the update_option filter. Or, as @mplusb mentioned:

The option’s name where they are stored is: scporder_options
which is an array and in ‘objects’ will keep all the custom posts and in ‘tags’ the taxonomies.

Answer from @mplusb

That means a simple solution is:

update_option('scporder_options', array('objects' => '', 'tags' => array('category')));

I also added a check to ensure the plugin is active and a second one to make sure we are not overwriting options if scporder_options is set, so the final code is:

if (is_plugin_active('simple-custom-post-order/simple-custom-post-order.php')) {
    if (!get_option('scporder_options')) {
        update_option('scporder_options', array('objects' => '', 'tags' => array('category')));
    }
}

How to remove captions from Instagram embeds in WordPress

This is a simple code snippet to achieve just that in Instagram embeds, via shortcode or using Gutenberg.

function custom_instagram_settings($code){
    if(strpos($code, 'instagr.am') !== false || strpos($code, 'instagram.com') !== false){ // if instagram embed
	    $return = preg_replace("@data-instgrm-captioned@", "", $code); // remove caption class
	    return $return;
    }
    return $code;
}

add_filter('embed_handler_html', 'custom_instagram_settings');
add_filter('embed_oembed_html', 'custom_instagram_settings');

[instagram url=https://www.instagram.com/p/B1WjYcxCmHp/ hidecaption=true]

You can achieve the same effect in single embeds by using the following shortcode

[[instagram url=https://www.instagram.com/p/B1WjYcxCmHp/ hidecaption=true]]

Here’s the result

[instagram url=https://www.instagram.com/p/B1WjYcxCmHp/ hidecaption=true]

YouTube

Use this snippet if you want to achieve a similar result wit YouTube embeds:

/* Youtube Videos remove show info related etc */
function custom_youtube_settings($code){
    if(strpos($code, 'youtu.be') !== false || strpos($code, 'youtube.com') !== false){
	    $return = preg_replace("@src=(['\"])?([^'\">\s]*)@", "src=$1$2&cc_lang_pref=en&hl=en&showinfo=0&rel=0&autohide=1&modestbranding=1&iv_load_policy=3", $code);
	    return $return;
    }
    return $code;
}

add_filter('embed_handler_html', 'custom_youtube_settings');
add_filter('embed_oembed_html', 'custom_youtube_settings');

Has this worked for you?

Found: on Reddit

How to iterate a list in batches using Twig (or plain PHP)

Recently I had to loop through a series of elements in a WordPress template (thanks Timber), which happened to be using Bootstrap.

If you ever used Bootstrap, you are familiar with the following markup:

<div class="row">
  <div class="element col-xs-4">
    Stuff
  </div>
  <div class="element col-xs-4">
    Stuff
  </div>
  <div class="element col-xs-4">
    Stuff
  </div>
</div>
<div class="row">
  ...
</div>

The problem here is very common. You have to:

  • Loop every 3/4/n items.
  • Insert a separator or whatever every 3/4/n items.
Continue reading →