Things I never knew existed: Gitk

Gitk is a built-in GUI repository browser for Git.

There are options, but to begin with, just launch it by typing gitk

It’s fast and handy if you just want to quickly browse commits or staged/unstaged files and don’t have an alternative GUI app.

Also a useful companion if you’re doing interactive staging.

You can instantly search full commit messages (matching commits will be shown in bold, remember to set IgnCase otherwise the search is case sensitive).

You can also use the touching paths option to look for files affected by a commit, and you can search by strings added or removed or changing lines matching.

There’s a second search box for finding things in the diffs.

You can modify colours, fonts and so on.

NB: Sourcetree has command line tools as well (so you can type stree, though I couldn’t get them to install properly when I tried).

Utility first CSS – observations / lessons learnt

I’ve been trying Tailwind CSS recently.  I’ll likely to continue using it.

People talk about Component First vs Utility First CSS frameworks – in my opinion the important word here is “first” – you should use your own best  judgement to combine the two techniques.

  • Start prototyping the design using atomic styles.
  • Observe where you’re reusing the same styles a lot and/or it’ll be a pain (e.g. paragraphs of body text)
  • Build components for these using @apply in your CSS file (between @tailwind components; and @tailwind utilities;)
  • Don’t bother build components for things you are unlikely to reuse.

Does the HTML source code look a horrible with all those styles? 

A bit when you very first see it.  But:

  • most code you didn’t write yourself looks confusing initially
  • maybe your CSS file looks confusing close up too

There are several ways Utility First can save time:

  • You’ll be switching back and forth between HTML and CSS rather less
  • There won’t be as much friction in the early stages of building the site (you’ll be plugging in atomic classes and seeing the results straight away, you won’t be worrying about how to name things or constructing BEM selectors) – however you should keep an eye out for when you need to build a component.
  • Obviously for a while you’ll be referring to the framework’s documentation a lot to learn the class names, but in the case of Tailwind CSS there’s an autocomplete search field on the site.  The abbreviations for margin, padding, flexbox etc., once learnt, are logical and easy to remember.
  • I find specifying code for screen breakpoints a lot simpler (typically I end up with lots of nesting in conventional CSS/SASS).
  • No maths needed when building grids etc.

Can you still customise everything?

Yes. Your tailwind.js config defines everything – colours, breakpoints, font  sizes, font families, leading, the grid etc. etc.

Who’s it good for:

  • Developers who aren’t working in CSS every single day and can’t remember the intricacies of flexbox or grids.
  • Anyone who doesn’t want their site to look like every other Bootstrap site (or any other framework that comes with pre-built components)

Can you still use it with SASS?

Yes (my typical build process for static sites uses Gulp and PostCSS)

Performance issues

There are two aspects to this, the CSS file size/download speed, and the speed the browser can process the quantity of selectors in it.

By default Tailwind will generate a very large CSS file with several thousand selectors.  But with a little optimisation (turning off unused colours and screen sizes) you can dramatically reduce this.   Also, the size is modest if served minified and gzipped.

Further reading:

Memcached and PHP 7.3

Just a note that the PECL memcached extension doesn’t work with PHP 7.3 yet, you need to stay on PHP 7.2.

This is the error I got when trying to running sudo perl install memcached (along with several sasl deprecation warnings):

/private/tmp/pear/install/memcached/php_memcached.c:1284:20: error: expression is not assignable

NB: Also, don’t get memcache and memcached mixed up when searching extensions.

WordPress – WPML – fix an incorrect language

I had a site using WPML (WordPress Multilingual) where the site’s language picker was set to English but a Chinese translation was consistently showing up for one particular item.

This turned out to be a simple case of the wrong language being set for the post in the database, but to the best of my knowledge you’d never be able to find that out from the UI.

Fortunately it’s easy to detect and fix with some simple PHP and SQL – the examples below use WP-CLI commands.

Firstly, you can use wp shell to verify the language the post is set to.

wpml_get_language_information('',123456);

The language is stored in the wp_icl_translations table, where element_id = the post ID.  So, using wp db query:

update wp_icl_translations set language_code = 'zh-hans' where element_id = 123456;

The above sets the post language to Chinese, which means it won’t be visible when the English version is requested.

Remember to clear any caches you are using.

 

How to install a drupal.org sandbox module using composer

Sandbox modules don’t have a drupal.org/project/foo URL like full contrib modules, and therefore you can’t use composer require drupal/foo to add them.

If you have a Drupal 8 site using drupal-composer/drupal-project, here’s what to edit in composer.json – using a sandbox module of mine as an example.

  1. Within the repositories section
"drupal-wturrell/ckeditor_remove_elementspath": {
    "type": "package",
    "package": {
        "name": "drupal-wturrell/ckeditor_remove_elementspath",
        "version": "0.0.1",
        "type": "drupal-module",
        "source": {
            "url": "https://git.drupal.org/sandbox/wturrell/3018599.git",
            "type": "git",
            "reference": "8.x-1.x"
        }
    }
},

2.  In require (or run composer require with the name you’ve specified)

"drupal-wturrell/ckeditor_remove_elementspath": "^0.0.1",

You can choose any name you like, but drupal-username/module makes sense to me.

Your sandbox module doesn’t need a composer.json file of it’s own.

Blocking ‘Next up’ notification on Amazon Prime (for people who have respect for movie end credits)

Regardless of your ‘auto play’ setting, Amazon Prime Video displays a “Next Up” box bottom right, with movie artwork, on reaching the credit offset point; because, after spending perhaps more than two hours watching a film, who doesn’t want immediately want to start another?

Here’s the adblock rule you need:

www.amazon.co.uk##DIV[class="nextUpWrapper"]

(i.e. you’re blocking div.nextUpWrapper)

Acquia Dev Desktop 32-bit MySQL

It’s worth noting the version of MySQL that comes installed with Acquia Dev Desktop 2 (5.6.41-84.1) is still 32-bit (unlike PHP which is now 64-bit).   Recently I was testing with a particularly large database and found it kept crashing with things like:

‘MySQL server has gone away’

Lost connection to MySQL server at ‘reading authorization packet’

Intensive operations such as Drupal-to-Drupal migration tended to trigger this.

I used MySQLTuner but the changes made little difference so then it occurred to me the 32-bit version simply wasn’t up to it, so I installed the latest 64-bit mariadb from homebrew instead and moved the relevant databases over to that (I have mariadb running on port 3306 and Dev Desktop’s MySQL on it’s default 33067).

So far it’s been stable.

Troubleshooting Drush with Acquia Dev Desktop

Updated Tue 8 Jan 2019

Symptom: drush updb hangs

If drush updb is hanging, first, run it with the --verbose script to see exactly what’s going on – that will show you the MySQL connections. (It turned out in my case Drush was connecting to the wrong database).

Symptom: drush connects to wrong database

Checklist:

  • Try starting the terminal connection via DevDesktop (the icon top right) and see if that makes a difference
  • Double the database connection details in the appropriate loc_ file in ~/.acquia/DevDesktop/DrupalSettings/
  • Check your drush status output
  • Check what happens if you run drush sqlc
  • Try installing the latest Drush (composer require drush/drush) rather than relying on the version that comes with DevDesktop (at time of writing that’s 8.1.7, whereas Drush is now up to 9.5.2)

My situation: I have two MySQL installations running, the 32-bit DevDesktop supplied version, and a 64-bit mariadb (for a very large site where I was experiencing connection timeouts).  They are on different ports. I had a site where ordinary drush commands and drush sqlc connection went to the correct MySQL server but drush updb used the wrong one (confirmed using the --verbose option – in fact it was connecting to a database with a different name entirely.

I couldn’t figure out what was going on, so I upgraded from Drush 8 to 9 and that fixed it immediately.

Symptom: large Drupal 7 site where cache is extremely slow or fails to clear…

drush cc all

…and eventually PHP runs out of memory (“cannot allocate”).

Check Drush is using the correct version of PHP, it may not be – use drush status or, more simply: drush php

To fix:

$ which drush
/Applications/DevDesktop/tools/drush

$ vim /Applications/DevDesktop/tools/drush

# edit the PHP version: [ -z "$PHP_ID" ] && PHP_ID=php7_1

 

Drupal debugging: Invalid argument supplied for foreach() EntityFieldManager.php:490

You might see this error occasionally when installing/uninstall modules, running db updates etc.

The code in EntityFieldManager.php loops through an array of entities – each of which is a bundle, for example the user entity contains all the user fields you may have created.

The trick for debugging is to dump the contents of $bundle_field_map and look for something wrong – e.g. my issue was an empty (NULL) font entity, which had been left behind after attempting to remove the fontyourface module.

Backup the DB (obviously) then look in the key_value table for records where collection = entity.definitions.bundle_field_map – for me it was a case of deleting name = font, value = N; and the problem went away.

(So an alternative to writing code is to look at the DB table first.)