Updating Trellis – WordPress LEMP

Updating Trellis can be a challenge initially and there is no one way to do it. Lots of people wrote about it at Roots Discourse and on Github. Most of them require some major git foo. Did write about updating the Trellis server before, but not on how to maintain Trellis itself. Here is my- manual – take on it.

Trellis Repository Update

I first rename the current Trellis folder to trellis-old and git clone the latest Roots Trellis version:

  • mv trellis trellis-old
  • git clone –depth=1 git@github.com:roots/trellis.git && rm -rf trellis/.git

That way I can keep the old copy and have the latest so I can copy over changes I need. I also put trellis-old on the .gitignore list with some other directories and files:


Trellis files to be updated

Then I make all the changes to files in the following directories:

  • group_vars/all
  • group_vars/production
  • group_vars/staging
  • hosts

I skipped group_vars/development as there hardly ever is a need for me there. Don’t do tweaks in development really as Trellis handles this pretty well out of the box with Vagrant.

Common Variables

The group all with common variables alone has:

  • mail.yml,
  • main.yml,
  • vault.yml,
  • users.yml

to updateMail.yml has the mail details so your Trellis server can send out email. Something like:

# Documentation: https://roots.io/trellis/docs/mail/
mail_smtp_server: smtp.sendgrid.net:587
mail_admin: admin@domain.com
mail_hostname: domain.com
mail_user: user
mail_password: "{{ vault_mail_password }}" # Define this variable in group_vars/all/vault.yml

when you are using Sendgrid.

Main has the main vars including some of your own custom ones.I made sure all customizations to PHP settings are added to group_vars/all/main.yml:

php_max_execution_time: 300
php_max_input_vars: 1000
php_memory_limit: 256M
php_post_max_size: 128M

In vault.yml the vault mail password is stored. That is needed for sending out email which is mainly set up in mail.yml. Under users.yml you add the server users and the keys used for which we normally use our own Github ones:


Though users.yml is not hard to set up and admin for admin_user is correct most of the time you do need to make sure all is well and no changes were made.

Staging and Production

Then staging and development have two files each that need updating:

  • vault.yml
  • wordpress_sites.yml

These files do not change much in Trellis, but they contain major details on your WordPress setup so do need to be updated with your customizations properly.

NB Did add php_memory_limit: 512M to production and staging, but I guess that could be moved to group_vars/all as well. Still two files each there. So nine files in total.


Host files for staging and production need their ips updated so they have the ones you added before. This is pretty easy to do and as these files hardly every change you can overwrite them. Example staging hosting file:

# Add each host to the [staging] group and to a "type" group such as [web] or [db].
# List each machine only once per [group], even if it will host multiple sites.

WP CLI Installation of WordPress

To do a WP CLI Installation of WordPress on a server where WordPress Command Line Interface is installed is quite easy. Let me explain here how you can get WordPress installed with it in no time.

WP CLI Installation

To install WP CLI itself do a

curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x wp-cli.phar 
sudo mv wp-cli.phar /usr/local/bin/wp

then do a wp –info to see that it works.

WP Core Installation Parameters

You just need to log into the server via shell using ssh user@domain.com. Then you go to the web root or directory where your site should reside. There you run the command wp core with the following parameters:

wp core install --url=staging.domain.com --title=Staging --admin_user=uberlord --admin_password=toughpassword --admin_email=jasper@staging.domain.com

This will make wp-cli install WordPress for you with:

  • url – domain where the site will be served from
  • title – site’s Title
  • admin_user – admin’s username
  • admin_password – the administrator’s password
  • admin_email – the email address of the administrator

WP CLI Automation

Once you have started the command it will download the latest WordPress version, install it using the parameters you fed it.


I also wrote about installing WordPress from the command line before without any tool. This works just fine too. But these days I prefer Laravel Valet or WP CLI. These tools are just too nice to live without.

Mailchimp Comment Optin – Fixing Outdated Constructor Error

Mailchimp Comment Optin is a plugin we still use for some of our clients. Fixing Outdated Constructor Errors is needed to work with it properly. The error you get will be:

( ! ) Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; MCAPI has a deprecated constructor in /srv/www/domain.com/current/web/app/plugins/mailchimp-comment-optin/lib/classes/MCAPI.class.php on line 3

This refers to an issue with a class name being the same as a function name. This is an old way to add a constructor from back in the days. To deal with that issue on line 39 change:

function MCAPI($apikey, $secure=false) {
 $this->secure = $secure;
 $this->apiUrl = parse_url("http://api.mailchimp.com/" . $this->version . "/?output=php");
 $this->api_key = $apikey; }


function __construct($apikey, $secure=false) {
 $this->secure = $secure;
 $this->apiUrl = parse_url("http://api.mailchimp.com/" . $this->version . "/?output=php");
 $this->api_key = $apikey; }

As you see we added __construct and with that you initiate a constructor properly.

NB We recommend not using composer for updates anymore. This so your fixes won’t be removed by an outdated flawed version. Just add the plugin to your ignore list.

WooCommerce and Gutenberg – Great stuff ahead!

WooCommerce and Gutenberg.. What will happen when Gutenberg Editor gets introduced to your WooCommerce site in WordPress 5.0? Will it be Armageddon and will all product fields below the description and title field break? Do you need to deactivate Gutenberg just to keep your ecommerce business up and running?

What is Gutenberg?

Gutenberg is the new WordPress Editor. We wrote about it before at the beginning of this year actually. It will allow you to create content for posts, pages and custom post types just like WooCommerce Products using blocks. Here is a screenshot of what you see looking for blocks:

Gutenberg Blocks


And here one with some text added:

Text Block

Think of it as some of the Page Builders out there like Visual Composer, Beaver Builder or Divi. What is more, it will also make these options available in the customizer and perhaps frontend in the future as well.

Custom Fields and Gutenberg

As all is still under development it tends to be foggy sometimes and a lot of developers and end users are freaking out about it as it might break the way meta boxes / custom fields are used now. WooCommerce relies heavily on custom fields to add product data. And these fields may not work properly, or be moved to the new sidebar and so on. When you currently run the Gutenberg plugin to check you see it in action on a product page the WooCommerce custom fields are below it.

WooCommerce Custom Fields

But it is going to be way more integrated. Either they will be show below the block in a different way, go to the sidebar or they are going to come up with another solution.

Product Blocks

I am all for it and the sneak preview WooCommerce has shown looks very promising. And WooCommerce is working on product blocks already in their repo using a separate branch (code to be merged once done).

I installed the product blocks branch on my local WooCommerce Gutenberg Laravel Valet site and I can already see we can add a product block with ease inside a post:

Product Search Inside Woo Block

I just cannot search for my existing dummy products yet.  There seems to be a 404 issue


Here the no products found message:

Product Block Search

So I can’t go and add a product yet, but I can see we are closer than I thought and that is nice to see.

It is work in progress and perhaps my setup needs some REST API changes..? But the WooCommerce REST API is turned on though..

WooCommerce REST API


Well, that is something to try another time. Just like add products in x numbers and columns as Woo demoed. That I seem to not be able to do with this test branch yet.

The Future of WooCommerce with Gutenberg

I must say I am really exciting. I always found most page builder lacking a lot. Especially in the WooCommerce field. I want to be able to change the product page layout around. I want to be able to decide where the

  • product gallery,
  • description
  • cart button,
  • price and
  • other tabs with data


will be added. And I am positive that we will. Do see great options for the category or shop page in progress already. Rows and columns can be decided and hopefully thumbnail sizes in the future too. As for product page changes, well I expect to be able to move the mentioned elements around and WooCommerce did mention these as possibilities as well.

I expect to see way more in the upcoming weeks and months! Can’t say I am too worried. Big changes yes, but changes for the better to keep WordPress ahead of the game and compete with the likes of Shopify and Magento. And for WordPress to show others like Wix, Squarespace, Weebly and so on who’s boss. Exciting times!

Bedrock Valet Can’t connect to local MySQL server Error

If you want to set up a Valet Bedrock based WordPress website and you run into this Valet Can’t connect to local MySQL server error. It will block you from generating a Bedrock WordPress website. It is however easy to remedy.

Valet Can’t connect to local MySQL server Error

The error you get will pop up this way on creating a Bedrock WordPress site:

wp valet new woo-guteberg --project=bedrock
Don't go anywhere, this should only take a second...
Error: ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)

MariaDB not running

This Valet Can’t connect to local MySQL server Error happens to us all every now and then. Either because we shut down MariaDB or because it did not start properly when we started our Mac.

You probably need to restart MariaDB:

brew services start mariadb

Afterwards you will be able to set up the site without issues:

wp valet new woo-guteberg --project=bedrock
Don't go anywhere, this should only take a second...
Success: woo-guteberg ready! https://woo-guteberg.dev

It is so easy with Laravel Valet. Love it very much!

Jupiter Page Background Image Position

The Jupiter Page Background Image Position can be a challenge with certain images. Sometimes the background image added behind your page winds up looking horribly cut off. So how can we improve the Jupiter Theme background images?

Background Color & Texture

Jupiter only allows for general background-position directions. This can be done per page using the Background Color & Texture settings’ Background position buttons.
Background Color & Texture
There you can choose for 9 positions:
  • top left,
  • top center,
  • top right,
  • center left,
  • center center,
  • center right,
  • bottom left,
  • bottom center and
  • bottom right.
And this is a nice feature and is enough most of the time. But sometimes you simply need more control. And for that you need to add some nice CSS.

CSS Background Position

With CSS you can position the background image more fine grained with percentages or using a fixed amount of pixels. This allows you to position these images the way you want. Especially useful when you add portrait size images and need to make them fit and display well. You could make all these title background images taller to make things fit. But then at about 700px height they will take up too much space really. Visitors like images, but also need to be able to read text right away.

So what I did is add:

.page-template-default .mk-header {
background-repeat: no-repeat;
background-position: 20% 35%;

to the Visual Composer’s CSS for that page. This piece of CSS with your own choice of percentages for the background-position allows for you to tweak the background image position to your heart’s desire. I do hope we will be able to do this without CSS in the future with Jupiter but for now this seems to be the way to go.

Trellis Server FTP Credentials requested by WordPress

Just today WordPress asked me to enter FTP Credetials to proceed after I adjusted an image using the Jupiter interface for header images. This had never happened before on any Trellis setup of mine.

FTP Credentials Needed

The full error message was on a very basic page with the fields to enter the ftp user and password:

Connection Information

To perform the requested action, WordPress needs to access your web server. Please enter your FTP credentials to proceed. If you do not remember your credentials, you should contact your web host.

 example: www.wordpress.org
 FTP Username
 FTP Password
 This password will not be stored on the server.

And the error came when I tried to update the post or save it. Normally data is just stored in the database so I failed to understand why the FTP credentials were requested in the first place. But apparently the file being run also suffers from this. And so there must be a permission issue.

WordPress Admin Rights

We do allow admins to install plugins on the server and as Ben mentioned at Roots discourse once again that is not recommended. But hey, we needed this working with multiple team members not familiar with tools such as Git, Composer, WP-CLI and the likes. So although I would have preferred to manage the plugins with composer it was simply not possible with this projects.

Error Logs

So decided to check the logs for clues on the need for FTP. The error log showed

PHP message: PHP Warning: Cannot modify header information - headers already sent by (output started at /srv/www/sub.domain.com/releases/20171017052436/web/wp/wp-admin/includes/file.php:1678) in /srv/www/sub.domain.com/releases/20171017052436/web/wp/wp-admin/post.php on line 198
PHP message: PHP Warning: Cannot modify header information - headers already sent by (output started at /srv/www/sub.domain.com/releases/20171017052436/web/wp/wp-admin/includes/file.php:1678) in /srv/www/sub.domain.com/releases/20171017052436/web/wp/wp-includes/pluggable.php on line 1216" while reading upstream, client:, server:sub.domain.com, request: "POST /wp/wp-admin/post.php HTTP/2.0", upstream: "fastcgi://unix:/var/run/php-fpm-wordpress.sock:", host: "sub.domain.com", referrer: "https://sub.domain.com/wp/wp-admin/post.php?post=483&action=edit"

Based in this I checked this WordPress core files for anomalies. I found:

 // Session cookie flag that the post was saved
 if ( isset( $_COOKIE['wp-saving-post'] ) && $_COOKIE['wp-saving-post'] === $post_id . '-check' ) {
 setcookie( 'wp-saving-post', $post_id . '-saved', time() + DAY_IN_SECONDS, ADMIN_COOKIE_PATH, COOKIE_DOMAIN, is_ssl() );

in post.php. In Pluggable line 1216 showed:

if ( !$is_IIS && PHP_SAPI != 'cgi-fcgi' )
 status_header($status); // This causes problems on IIS and some FastCGI setups
header("Location: $location", true, $status);
return true;

Session Issue

And so that seemed to be related to a session issue on saving of the post. Which is correct. Not a whitespace issue that should not be there as is sometimes the case. So I started to wonder. I did do a server update while working so perhaps the session got messy. I logged of and on, tried saving the same post again and things were fine. I also checked rights and permissions for the /srv/www/sub.domain.com/current/web/app/ and did not see something odd really. So perhaps it was just a session issue due to the server update I did doing a 

unattended-upgrades -d

Should have probably not have done these two things at the same time!

Reinstallation Latest WordPress Version

Issue continued however. Once I made a header change the second time and saved the issue returned. So then I decided to reinstall WordPress as it seemed the issue was pointing to WordPress Core files and I could still not find issues with the files it got stuck at. Did not work either

Image Replacement

The image used in the header was an image loaded from the main domain on the same server so thought that may be the issue and uploaded on on the subdomain media manager itself. Did did not seem to be the issue though as the issue remained.


So I decided to upload the theme once again as it was updated recently and that may be the issue. After I overwrote all theme files things seem to be working. But only when I added a line to application.php for direct FS method*.

* Custom Settings
define('DISABLE_WP_CRON', env('DISABLE_WP_CRON') ?: false);
define('DISALLOW_FILE_EDIT', true);
define('FS_METHOD', 'direct');

*(Primary Preference) “direct” forces it to use Direct File I/O requests from within PHP. It is the option chosen by default.

The extra define(‘FS_METHOD’, ‘direct’); in application.php seemed to do the trick.

This makes us think there has been a Jupiter change that requires file manipulation that somehow does not work properly with other methods besides direct file I/O requests. But we have not figured it out yet. Seems unlikely now that this is a file or directory permission issue. Otherwise we would have had other issues and error messages.

PHP Strict standards: Declaration of A should be compatible with B

We bumped into an PHP Strict standards: Declaration of A should be compatible with B issues.We had a theme made by us quite some time stop working recently.  One we we were using as a demo mainly. So we decided to work things out. As many of you might bump into this I decided to jot this down.

Strict Coding Standards Warning

The warning we got was:

Declaration of THeaderContainer::OnEnableEvent($Sender, $Input) should be compatible with TControl::OnEnableEvent($Sender)

This is a strict coding standards warning. See comment searching this PHP.net page for declaration. The first argument does have two arguments, but the second does not. This could be fixed using:

OnCreateEvent($Sender, $input)

with the extra argument $input added. This had to be done across like 35 files so I had to do a search and replace.

Additional Similar Declaration warning

The same had to be done with:


occurrences. This to deal with warnings like:

Warning: Declaration of THeaderContainer::OnEnableEvent($Sender, $Input) should be compatible with TControl::OnEnableEvent($Sender) in /../../../../../THeaderContainer.php on line 32

So just like with the previous warning we added the extra argument $input to make PHP in Strict Mode happy.


The main question remains though why this pops up now though. We had been running PHP 7.0 for quite some time already so been using a post PHP 5.4 version for quite some time to say the least. And we did see some errors from time to time, but now we could no longer login. What had changed is that we moved from a VPS to Dreamhost shared hosting so perhaps lack of memory spoiled the party.

Strict Mode needed?

You do of course not need to work with PHP Strict Mode and you can turn it off. This by changing php.ini, or a user.ini. or removing or adjusting mode declarations in other files. But as we had this project up and running with it since way back I decided to stick to this. And this way you do learn a lot about PHP and how to write it properly.

WP Rocket Algolia Search Conflict

When I ran Algolia Search with WP Rocket I bumped into WP Rocket Algolia Search Conflict. With JavaScript Minification turned on I got several errors

JavaScript Errors

I got this error:

[Error] Failed to load resource: the server responded with a status of 404 (Not Found) (head.js.map, line 0)

as well as these:

Uncaught ReferenceError: algoliasearch is not defined at HTMLDocument.<anonymous> ((index):94) at i (a9b476399a1ace75e81cb940be005dd2.js:2) at Object.fireWith [as resolveWith] (a9b476399a1ace75e81cb940be005dd2.js:2) at Function.ready (a9b476399a1ace75e81cb940be005dd2.js:2) at HTMLDocument.K (a9b476399a1ace75e81cb940be005dd2.js:2) (anonymous) @ (index):94 i @ a9b476399a1ace75e81cb940be005dd2.js:2 fireWith @ a9b476399a1ace75e81cb940be005dd2.js:2 ready @ a9b476399a1ace75e81cb940be005dd2.js:2 K @ a9b476399a1ace75e81cb940be005dd2.js:2

and these:

SyntaxError: expected expression, got '<'
ReferenceError: algoliaAutocomplete is not defined[Learn More] wpvilla.in:131:9

The latter two were the real culprit as a soon as these showed up the site would not load properly anymore. The files causing the issue seemed to be:


WP Rocket JavaScript Exclusion

But I could no longer find a way to exclude these to make the error go away. Only CSS files could be excluded with the latest WP Rocket version it seemed:
WP Rocket Minify files
So we have turned off minification of JS for now until we have found a solution to the problem. Either an exclusion somehow or Algolia JS Fix. We will keep you posted!
This until I was reminded by WP Rocket you have to have JavaScript minification turned on to see this box. Then we added the Algolia general script and autocomplete script we found. This however clearly was not enough as we still had the same issues.


Solution given by WP Rocket for the site not loading with Algolia JS minified in the end was to add this to exclude all Algolia JS:


So that means we probably somehow missed a script besides the ones I mentioned and this one was not excluded. It is now. Happy to have this work though! Again I would prefer to go without the inline script added by Algolia, but to solve that more time would be needed.

Boost Sales with Algolia Search

Let’s face it, WordPress built-in search kind of blows. You can improve search and boost sales with Algolia Search. It will upgrade search to site wide search including products and offers suggestions! And it really easy to get going.

Improving WordPress Search

Visitors as we know can be an impatient bunch. So if we allow them to find what they need faster they are more likely to buy. Also, if search provides suggestions on what is available he or she might also go to a product though he was searching for blog content he saw earlier.

Unfortunately WordPress search out of the box sucks. Even a plugin like Better Search does not quite cut it. Sure it searches not just post, but other post types as well such as pages, but still it does not suggest other possible content, nor is it really fast.

Algolia Search to the rescue

Lighting fast search with search suggestions Google style  can now all be done with the power of Algolia Search. Algolia Search is used heavily in the Laravel community and at Laracasts.com and with good reason.

Algolia Search

It is simply an amazing search integration. This is what is has on offer:

  • site-wide search
  • content suggestions while typing
  • suggests other options when the customer misspells something*

*Here example of misspelling where correct search term is suggested:

Misspelling and suggestions

And while you could integrate Google Search this is way prettier as in really integrates well. Just test it on our site. On typing suggestions popup in a dropdown from where a customer can click on a link. Each suggestion is also displayed with a small thumbnail based on the featured image.

Better Conversion and Lower Bounce Rate

All these features will prove that you can boost sales with Algolia Search. It will suggest possible products to buy and it will show these directly while searching. That is pretty amazing isn’t it. Besides a sales boost it is also just a general retention boost. It will lower your bounce rate as visitors will with ease be able to find follow up content, products and services to look at.


Let me just quote what they mentioned on the plugin description page here:

Algolia offers its Search as a Service provider on a incremental payment program, including a free Community Plan which includes 10,000 records & 100,000 indexing operations per month.
Beyond that, plans start at $35/month.

So you can stay on the free community plan post registration – needed for key – as long as you do not pass 10,000 records & 10,000 indexing operations per month. Indexing wise you should not have issues with that anytime soon on most sites and neither should you record wise.

We have had 2,452 records and 3,311 indexing operations so far with with 150+ post and close to 30 pages. Also during the trial the sky’s the limit really.


First of all you need to install their plugin. That is easy as always.

Search by Algolia – Instant & Relevant results

Next you will need to register to get your

  • application id,
  • search-only api key and
  • admin api key

and get your trial up and running. The plugin will guide you with this.

Algolia Settings


Then you need to choose the content you would like to be part of the searches and allow Algolia to index it under autocomplete and activate this. This will take some time as in will need to index and store it at Algolia for lightning fast future searches and suggestions.

Algolia Auto Complete

Search Page Choice

On Search page you can choose to use WordPress Search Page or the Algolia Search page:

Search Page and Algolia

This really depends on your preference. We are testing with at the moment.


Algolia Dashboard

Once you are setup you can keep track of indexing, searches done and much much more in their Dashboard.

Algolia Dashboard

I like the design and UI in general. It is easy to see what is going on. Do think I won’t be needing to check things here that much, but it is nice to have when search starts getting used a lot.

Rolling your Own

If you want to run it all for free and under your control you can clone the repo and roll your own on your own server. Just to to the repository at Github and get your own copy. Then install in on the same web server or a separate on, and integrate it with your site. Doing this all by yourself will require more technical knowhow and more server power of course, but you do keep all the data under your control