Have you ever run vagrant destroy on your box before you realized you wanted to keep the MySQL databases? Well I have, last night actually. Thankfully I use the wonderful and free Veeam Endpoint Backup to backup daily and was able to restore the old VMDK, connect it to a VirtualBox VM, use Ubuntu recovery mode to gain access, and then backup the databases to a shared folder. So that was an exciting learning experience.

Problem

And so it got me thinking – how can I make the databases persist between vagrant destroy and vagrant up so that I don’t lose them just because my memory was lacking. Separate VM? No, that’s more resources and adds complexity. Map MySQL data directory to host? No, been there done that, DB access is noticeably slower. Forget Vagrant and use Docker? No, I’ve tried it and though many love Docker it’s not for me; perhaps when Docker for Windows is as good as Docker for Mac/Linux.

Solution

Use the vagrant-triggers plugin and a couple bash scripts to obtain developer happiness.

Getting Started

Create a new folder where you would like to store the content and config for your new Vagrant box. In my case I have a Vagrant folder on a secondary hard drive that I use for Vagrant boxes. The directory name you choose isn’t important as long as you remember what box is in it. The Vagrant box’s actual name will be taken from PuPHPet’s config.yaml regardless.

Alright, if everything went smoothly you should have a working vagrant box at http://developer.test that displays the PHP info page.

At this point we have no MySQL data but we do have an empty database, db1, so let’s install WordPress to generate some data.

After extracting the WordPress install zip file to D:\Vagrant\Developer\www\developer.test\public_html we can start the install at http://developer.test/wordpress.

Okay, done!

Destroy! Destroy!

Now let’s perform a destroy and see what happens.

Important: The vagrant box must be running when you issue the destroy command because the database backup script needs to run inside box. Otherwise you’ll get a “not yet ready for SSH” error and return to the command prompt.

It grabs a list of SQL files created by the backup and imports each one into the MySQL server.

Important: If you are copying code from this page and creating your own script files make sure the line endings are set to UNIX (LF only). Otherwise Vagrant will fail to execute them.

Conclusion

Not only does this preserve your MySQL databases but with this method also opens up the possibility of distributing a development environment with applications and databases already installed and working from the first startup of your Vagrant box.

Hope this article has been useful to you, drop a comment if you feel so inclined.

I’ll start this by saying that Exim is slightly more difficult to configure for Gmail SMTP relay than Postfix, and if you’re using Webmin there is a standard module for Postfix that makes it even easier. Finding the correct way to configure Exim on CentOS was difficult in itself and the reason for this article.

Now, if you prefer to use Exim for sending mail through Gmail this is how you accomplish it.

Replace the credentials with your actual credentials on the client_send line.

That’s it for the configuration. If you started with a default exim.conf then your updated configuration file will look like this gist.

Restart Exim to make these changes live:

service exim restart

Testing & Troubleshooting

Test by sending an email with echo "Just testing." | mail -s "Test Subject" user@example.org or a simple PHP script. Use a destination address separate from the one you’re using to relay email.

Shortly thereafter you should receive the email at the destination mailbox (check the spam folder too). If you don’t receive it then check the log at /var/log/maillog or /var/log/exim/main.log for errors.

If you get an error from Gmail, they usually reference a URL in the error that you can visit for more info. You can also do a Google search for the error to see what others have done to resolve it.

Of course, the hope is that you didn’t have any errors and you’re all set to send emails from your Linux box. Enjoy!

Recently I was searching for an easy way for developers to add custom fonts to the Beaver Builder child theme customizer. Failing to find that, I have come up with a solution that does not modify the core Beaver Builder theme files and only requires a minimal amount code.

Step 1: Load Your Font

You have a few options and the method will depend on your font source. Perhaps it is a kit from Typekit or Edge Web Fonts loaded via JavaScript. In that case you can add the code through Customize … Code > Head Code.

Alternatively, you could enqueue the embed code through the child theme’s functions.php file, it’s entirely up to you.

Some other methods include uploading your custom CSS font files to your child theme’s directory or using a remote @import URL. Either way you’ll need to edit your child theme’s style.css file and load the font from there.

Important Note: Currently, the Beaver Builder theme code doesn’t quote the font name in the generated CSS so for sure font names with commas will fail and you’re mileage may vary with fonts that include spaces or special characters. I have found that at least fonts with single spaces should work in all modern browsers without quotes.

Once you have your font loaded and can verify that in your site’s source code you can move on.

Step 2: Add Your Font to the Theme Customizer Font List

Edit your child theme’s functions.php file and add the following, making sure to replace acumin-pro-extra-condensed with your custom font name and adjusting the fallback string and weights array as needed. You can add multiple custom fonts to the $custom_fonts array, just follow the same format as the first.

After working with WordPress dashboard widgets in a recent project I wanted to present a complete example with arguments and usage of the control callback for saving widget options. Using the code in the Gist below you will be able to configure custom content for this widget with the native WYSIWYG editor. When you hover over the widget’s title bar the “Configure” link will be revealed – you must be an Administrator to configure the widget.

Widget Display

Widget Configuration

There are couple of special things to note. The first is the workaround to enable the autoembed functions for content output (lines 12-16). The dashboard has no post ID and without a post ID that evaluates to true autoembed will fail to do its job. The second thing to note is code to set the widget priority (lines 81-85). However, once a user manually positions a dashboard widget this code is no longer effective.

You may find this code useful for developing a “getting started” widget to help users use custom WordPress admin features you’ve developed.