Responsive Images with Width Based on Actual Image Width

WordPress has responsive images built in these days. Since 4.4 as a matter of fact. But what if we want to have WordPress Responsive images with width based on actual image width?

Current State and Needs

Can we generate something like WordPress responsive image (comments added to html):

<img width="1024" height="445" 
src="" // old browser support using src
class="d-block w-100" alt="" 
srcset=" 1024w, // 1024 width image 300w, // 300px width image 768w" / /768px width image
sizes="(max-width: 1024px) 100vw, 1024px">

where the 1024px can be based on the actual width of the image? That was the question we had and so we started looking around.

Additional Width

Somehow we had quite a few images that were smaller than 1024px on our site and these now got stretched as they are not 1024px wide.
As WordPress sees that the full image is 1024px by 445px that is what is uses to generate the images and though this works well it does not work for all. Looking for solution as suggested by Mark Root-Wiley like:

 srcset="example.gif 200w"
 sizes="(min-width: 400px) 400px, 100vw"
 width="200" /* <=== TA-DA! */

This would be a possible solution if the width was not static and the $attr variable would not overwrite the image attributes. Still we looked further.

Custom Sizes

Well, WordPress did suggest a solution for custom sizes:

$img_src = wp_get_attachment_image_url( $attachment_id, 'medium' );
$img_srcset = wp_get_attachment_image_srcset( $attachment_id, 'medium' );
<img src="<?php echo esc_url( $img_src ); ?>"
     srcset="<?php echo esc_attr( $img_srcset ); ?>"
     sizes="(max-width: 50em) 87vw, 680px" alt="A rad wolf">

But that still did not load a width based on actual image width. And that set the srcset image to a another image size which we didn’t really need. Full width was fine for us.

WordPress Image Width

We could use

$image_data = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), "thumbnail" ); ?>

to grab the image meta data and then the width using:

$image_width = $image_data[1];

NB Great Explanation by Jonathan here

Custom Responsive Image with Actual Width

So something like:

$alt_text = get_post_meta($post->ID, '_wp_attachment_image_alt', true);
$image_data = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), "thumbnail" );
$image_width = $image_data[1];
$img_src = wp_get_attachment_image_url( $attachment_id, 'full' ); 
$img_srcset = wp_get_attachment_image_srcset( $attachment_id, 'full' ); ?> 
<img src="<?php echo esc_url( $img_src ); ?>" srcset="<?php echo esc_attr( $img_srcset ); ?>" sizes="(max-width:<?php $echo image_width;?>) 100vw,<?php$ echo image_width;?>" alt="<?php echo $alt_text;?>">

NB Not tested yet!

should do the trick. This would allow a fully customized loading of the image with the actual width loaded instead of the full image width as set in the theme.

To be continued…

Quick Local WordPress Setup with Valet

Often you just want to do a quick WordPress setup locally on your Mac for trying something out. I always do a quick local WordPress setup with Valet. Laravel Valet is an application that is created by the developers behind Laravel. It can be used to run all sorts of apps and WordPress is one of them. Thanks to the Evan Mattson’s CLI Valet Command package you can use Valet to create WordPress sites with a single command.


So what do you need? You need to setup Laravel Valet and for that you need Homebrew (MacOs package manager) including PHP and MariaDB. You also need Composer to install the Laravel Valet package itself.. Let’s go through settings all these up.


So what do you need? You need to setup Laravel Valet and for that you need Homebrew (MacOs package manager). So install Homebrew using:

/usr/bin/ruby -e "$(curl -fsSL"

Homebrew Packages

Then you need to install PHP 7.2 (currently).

brew install homebrew/php/php72

And you also need to install MariaDB

brew install mariadb

Composer & Laravel Valet

Then you can install Laravel Valet with composer. Most of you using Laravel should have it already, but just in case. To install Composer do the following in a directory of your choice

php -r "copy('', 'composer-setup.php');"
php -r "if (hash_file('SHA384', 'composer-setup.php') === '544e09ee996cdf60ece3804abc52599c22b1f40f4323403c44d44fdfdd586475ca9813a858088ffbc1f233e9b180f061') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"

Next step is to install the composer package for Laravel Valet

composer global require laravel/valet


You should have WordPress Command Line Interface installed too. You can read about it here. But on top of that you need to install the WP Valet package. This package does all the magic of using the coolness of Laravel Valet and WP CLI. You can do the installation using this wp command:

wp package install

That will get you going.

WordPress Website Installation

Once that is done you can install WordPress using Valet and Bedrock as a setup using:

wp valet new my-project --project=bedrock

Bonus: Local Site Copy

So what if you quickly want to set up an existing website? This so you can make changes for your client? There are many options. You could do a general WordPress Valet setup, replace the database and add the wp-content directory. That would do the trick. You could also do a general Valet WordPress setup and than do a BackupBuddy restore.

To start a new project as a base you simply run:

wp valet new my-project --project=wp

Then inside the newly created directory my-project run

valet link new-project

Using valet links you can check if it was created, but of course also by surfing to https:/my-project.test. You can then login at https://my-project.test/wp-login.php with username admin and password admin.

Local Restore

Now let’s say I want to go the BackupBuddy restore way. How do I proceed? I install the BackupBuddy plugin and import the backup using the backup file and the import file. Issue is that BackupBuddy refuses to run backups or restores due to errors with wp-cron and others.

Error: Error #9038: Loopback test error: cURL error 6: Could not resolve: site.test (Domain name not found). URL: https://site.test/wp-admin/admin-ajax.php?action=itbub_http_loop_back_test&serial=96ytxigaj612suq. If you need to contact your web host, tell them that when PHP tries to connect back to the site at the URL https://site.test/wp-admin/admin-ajax.php?action=itbub_http_loop_back_test&serial=96ytxigaj612suq via curl (or other fallback connection method built into WordPress) that it gets the error cURL error 6: Could not resolve: site.test (Domain name not found). This means that WordPress' built-in simulated cron system cannot function properly, breaking some WordPress features & subsequently some plugins. There may be a problem with the server configuration (eg local DNS problems, mod_security, etc) preventing connections from working properly.

We do have 1024MB as a memory limit already at /usr/local/etc/php/7.3/conf.d/php-memory-limits.ini and we also made execution time 120 instead of 30 at /usr/local/etc/php/7.3/php.ini

But with or without SSL we still got stuck updating via BackupBuddy’s interface. So what you can better do is replace wp-content and import the database as a whole. We imported with WP Database Backup.

WP Database Backup

We did however had to re-create the database and using utf8mb4. Basic WP Valet database setup caused the import to fail and even using different import settings than Greek Windows did not help. Still got stuck at

[ERROR in query 1] You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'PK   ' at line 1 [ERROR in query 2] You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '??4?A?? ??G?ж??O ?????? ? fW??n?,?m??e?x? ? ?

With new database under the same name we could import. Warning shots were fired and a database update was needed by WordPress but things did work in the end. That and with home url and site url changed to work with .test . Of course image would still load remote site images, but for local code tweaks that did not matter.

NextGen Gallery Custom Field Rotating Images

NextGen Gallery Custom Field Rotating Images was created by us about 5 years ago for Ultimate Fiji Vacations. Since then the NextGen gallery has gone through some major changes. It has been taken over by Imagely and it has had some major upgrades.

Shortcode Changes

Some of these NextGen Gallery plugin changes were also shortcode changes. And these caused a not loading or not loading of some galleries (old post on setup) of a client of ours. We had to dig deep into the code changes to figure out what to do. We realized templates were loaded differently and that also the shortcode to load a gallery had changed. It now calles source and container_ids to load a gallery with images properly. The code

$gal = apply_filters('the_content', '[nggallery id='.$gal.' ' . $nggtemplate. ']' );
is therefore no longer applicable.

Full Code

Here is the full code to now load the gallery based on custom post type ID:
/* NG Gallery Custom Field Rotating Images */ 
$gallery = get_post_meta($post-&gt;ID, 'Gallery ID Number', true); 
$gal = $gallery; 
if( !empty($gal) ) { 
$gal = apply_filters('the_content', '[ngg_images source="galleries" container_ids=' .$gal.' display_type="photocrati-nextgen_basic_imagebrowser"]');
echo $gal;

As you can see the source=”” has been added and we removed the old fashioned way loading of the template as it no longer worked.

Template Loading

As the template is no longer loaded the old fashioned way and as this code allowed it to be loaded right away we decided do ditch loading a template by absolute path like so:


Instead we added the necessary JavaScript for the styling in the code where the slider was generated. This saved us the loading of another file and worked just as well!

Update Trellis like a Pro


Here a quick blog post how to update Trellis like a pro.


Here are some requirements or basically tips before you get started

  • Trellis should be in its own repo not together with Bedrock/Site
  • Always make sure you’re working in a Git repo
  • Make sure all your work is committed
  • Use a great IDE like Visual Code to deal with merge conlficts

Trellis As Upstream Remote

Add Trellis as a remote

git remote add upstream

The pull the upstream changes using

 git fetch upstream

You will then see something like

git fetch upstream
remote: Counting objects: 40, done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 40 (delta 24), reused 29 (delta 24), pack-reused 9
Unpacking objects: 100% (40/40), done.
   c8515b3..14cce04  master                -> upstream/master
 * [new branch]      memcached-disable-udp -> upstream/memcached-disable-udp

Once that is done rebase upstream changes into your master repository using

 git rebase upstream/master

Git Merge Conflicts

Manually fix all conflicts. I recommend Visual Code as it visually helps you to deal with it all as you see in the image below. Also read: and

Visual Code Git Merge Conflicts

In Visual Studio Code you simply need to accept current change (added by upstream) or keep incoming change. And the latter you have to do for most if not all group_vars files.

Rebase Continued

Once you have fixed all conflicts you can do a

git add .
git rebase --continue

Merge Conflicts Leftovers

When I continued the rebasing I got a few more merge conflicts:

Falling back to patching base and 3-way merge...
Auto-merging group_vars/development/vault.yml
CONFLICT (content): Merge conflict in group_vars/development/vault.yml
Auto-merging Vagrantfile
CONFLICT (content): Merge conflict in
error: Failed to merge in the changes.
Patch failed at 0002 first commit
The copy of the patch that failed is found in: .git/rebase-apply/patch

When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".

So I fixed the files and overwrote changelog, README and Vagrantfile with the latest from the repo at Github. Then I rebased again and… all good!

NB This blog post is based on Swalkinshaw’s post at Roots Discourse on updating Sage