Applying style attributes to table rows, columns and cells in HTML can be done by adding style attributes to <tr> (row) and <td> (column) tags.
A WordPress table however does not allow direct editing of these tags without converting a “table” block to an “html” block.
If you do this, the WordPress editor no longer allows entering text directly and easily into table cells.
Templates that have the “CUSTOMIZE / ADDITIONAL CSS” option provide a solution. (this is a common feature on templates)
If you assign a table a CSS Class in the WordPress editor, you can use CSS to assign style attributes to TR and TD tags within that table.
Begin by assigning a CSS Class to the table in the WordPress editor. In this example, I’ve assigned the CSS Class “wp-install-commands”.
Next, On the WordPress Dashboard, choose Appearance / Customize. Then, if the template provides it, you can select the Additional CSS option.
Style attributes can be assigned to the whole table by addressing only the class. For example the following CSS would put a border around the whole table assigned the CSS Class of wp-install-commands.
.wp-install-commands
{border:solid black 1px}
Adding “tr” will put a border around each row.
.wp-install-commamds
tr
{border: solid black 1px}
To put a border around all the cells in the table, you have to assign the border attribute to TD. If you don’t qualify the TD, the style will be applied to all cells of the table. The following example will put a border around all cells:
.wp-install-commands
td
{border: solid black 1px}
To assign styles to specific rows and cells, you can use CSS Selectors.
More complicated cell selection can be done by combinations of TD and TR selectors – which are treated as the formation of a logical intersection of the selectors.
For example the following CSS will assign styles to the 2nd column except for the first row:
Note that some attributes don’t apply to some tags. For example, style “text-align:center” has no effect on TR. If you wish to center text in cells on a row, you have to combine TR and TD as in this example:
Software for Unix and Unix-like systems can be obtained and installed in a variety of ways. Source code can be obtained, compiled and installed. Binary files can be obtained and installed. And “packages,” designed to simply the software installation process, can be used. It’s similar for Windows – but the nomenclature is different.
Because of their simplicity and reliability – software packages are the most common form of software distribution and installation.
“Package” is the term used for a file containing software modules and scripts that install them properly. Linux operating systems use the term “package” – some other operating systems use other terms.
Linux distributions maintain a “repository” – a central collection of packages. The distribution’s repository contain packages known to be compatible and stable with that distribution. Not all Linux distributions have the same packages in their repositories. Not all Linux distributions have the same versions of packages in their repositories.
A utility program called a “package manger” installs software from the repository. Debian distributions of Linux use APT (Advanced Package Tool) – a package manager designed for interactive use. A variation called “APT-GET” is designed for scripted use.
Many tutorials and references for installing a stack on Debian family Linux distributions for WordPress depict using APT-GET. I strongly encourage using APT. Make use of its interactive features and informative reports.
Debian family package managers resolve dependencies when software modules are installed. If a new module depends on other modules also being installed, the package manager checks for them and installs them automatically as necessary.
For some packages, repositories contain multiple version numbers. This allows the package manager use an earlier version if other software modules have dependencies that require it. By default, the newest version will be installed as long as there are no conflicts.
Because package managers will automatically install the appropriate version of a package, you never have to specify the version number of a package to install. Be careful of postings and tutorials that direct you to install packages that have versions in their name. It is likely to be a mistaken or obsolete information.
Here’s an example from a tutorial book that is wrong:
This tutorial erroneously directs you to install “php7.2-curl”. Instead, you should install “php-curl”. APT will then install the appropriate version of this package in your repository.
One challenge can be knowing the correct name for a package. The “APT list” command can be useful – especially if using the “*” wildcard. If you use the command: APT list *curl*
This will generate a list of all packages in your repository containing the letters “curl”. In the middle of a list of about 30 entries is:
Notice there are four entries containing both “php” and “curl”: php-curl, php7.1-curl, php7.2-curl and php7.3-curl.
Since APT will automatically install the appropriate version, all we have to do is issue the command: sudo apt install php-curl
wp-ops@seebylooking:~ $ sudo apt install php-curl↵
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
php-curl
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 5,992 B of archives.
After this operation, 12.3 kB of additional disk space will be used.
Get:1 http://mirror.pit.teraswitch.com/raspbian/raspbian buster/main armhf php-curl all 2:7.3+69 [5,992 B]
Fetched 5,992 B in 1s (9,052 B/s)
Selecting previously unselected package php-curl.
(Reading database ... 157231 files and directories currently installed.)
Preparing to unpack .../php-curl_2%3a7.3+69_all.deb ...
Unpacking php-curl (2:7.3+69) ...
Setting up php-curl (2:7.3+69) ...
wp-ops@seebylooking:~ $
Using the “*” wildcard again we can verify which modules (and version) were installed using the command: APT list php*curl –installed
wp-ops@seebylooking:~ $ apt list php*curl --installed↵
Listing... Done
php-curl/stable,now 2:7.3+69 all [installed]
php7.3-curl/stable,now 7.3.14-1~deb10u1 armhf [installed]
wp-ops@seebylooking:~ $
Notice that two package modules are installed: php-curl and php7.3-curl
PPA – Personal Package Archive
There are instances where software modules you want are not in your distribution’s repository.
For example, at the time of this writing, the newest version of PHP in the Ubuntu version 18.04 distribution repository is version 7.2. The WordPress “Site Health Status” tool says that this version is out of date.
Unfortunately, attempting to re-install PHP to upgrade to a newer version comes back with the report that PHP version 7.2 is the newest version available.
wp-ops@seebylooking:~$ sudo apt install php↵
Reading package lists... Done
Building dependency tree
Reading state information... Done
php is already the newest version (1:7.2+60ubuntu1).
0 upgraded, 0 newly installed, 0 to remove and 1 not upgraded.
wp-ops@seebylooking:~$
At this point there are two options: 1) Accept PHP version 7.2 until a newer version is available in the repository. Or 2) Use a PPA to install a newer version of PHP.
A PPA can be developed by anyone. There are several PPA in wide use that are maintained by individuals with good reputations.
Using a PPA introduces new administration complexities. The benefits may not outweigh the work and responsibility.
If you’re new to managing a Unix or Unix-like server host software – using the standard package repository, at the cost of missing some WordPress performance gains from newer software versions, may be the wiser choice.
PHP Extensions
PHP Extensions are software modules that extend the capabilities of PHP. WordPress provides a list of extensions it may use.
Unfortunately, there’s not a corresponding list of package names for each of these extensions.
Some of them are easy to figure out. The graphics extension “GD” exists in the package php-gd.
The APT “show” option is a good way to see what’s contained in a package. For example APT show php-gd confirms that this package contains the GD module.
wp-ops@seebylooking:~$ apt show php-gd↵
Package: php-gd
Version: 1:7.2+60ubuntu1
Priority: optional
Section: php
Source: php-defaults (60ubuntu1)
Origin: Ubuntu
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Original-Maintainer: Debian PHP Maintainers <pkg-php-maint@lists.alioth.debian.org>
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Installed-Size: 12.3 kB
Depends: php-common, php7.2-gd
Supported: 5y
Download-Size: 1996 B
APT-Sources: http://mirrors.digitalocean.com/ubuntu bionic/main amd64 Packages
Description: GD module for PHP [default]
This package provides a GD module for PHP.
.
PHP (recursive acronym for PHP: Hypertext Preprocessor) is a widely-used
open source general-purpose scripting language that is especially suited
for web development and can be embedded into HTML.
.
This package is a dependency package, which depends on Ubuntu's default
PHP version (currently 7.2).
wp-ops@seebylooking:~$
Sometimes it’s not so simple. For example, one extension on the WordPress list of requirements is the DOM module. There is no PHP extension or module containing the letters “DOM”. It happens that this module is included in the php-xml package. It took a few google searches to find that.
To confirm that DOM is within the php-xml module, use the APT list php-xml command.
wp-ops@seebylooking:~$ apt show php-xml↵
Package: php-xml
Version: 1:7.2+60ubuntu1
Priority: optional
Section: universe/php
Source: php-defaults (60ubuntu1)
Origin: Ubuntu
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Original-Maintainer: Debian PHP Maintainers <pkg-php-maint@lists.alioth.debian.org>
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Installed-Size: 12.3 kB
Depends: php-common, php7.2-xml
Download-Size: 2024 B
APT-Sources: http://mirrors.digitalocean.com/ubuntu bionic/universe amd64 Packages
Description: DOM, SimpleXML, WDDX, XML, and XSL module for PHP [default]
This package provides a DOM, SimpleXML, WDDX, XML, and XSL module for PHP.
.
PHP (recursive acronym for PHP: Hypertext Preprocessor) is a widely-used
open source general-purpose scripting language that is especially suited
for web development and can be embedded into HTML.
.
This package is a dependency package, which depends on Ubuntu's default
PHP version (currently 7.2).
wp-ops@seebylooking:~$
Another technique for finding extensions is to use the “search” option of APT. The command APT search php- will return a list of package modules in your repository pertaining to PHP along with a brief description.
This may be long list. You can either redirect the output to a file, or pipe the output to the MORE command, or the more useful LESS command. For example: APT search php- | less
The text in the box below is scrollable.
This scrollable file is similar to what you might get using the by piping to search to the MORE command. You can escape out of MORE by pressing “q”.
Beware of Conflicting Information
One tutorial I found instructs installing DOM by installing the extension module php-dom. This module however does not exist in my repository.
Clicking on the link regarding Virtual Packages takes you to a page containing this explanation:
This may explain why the tutorial mistakenly directs the installation of a module that exists only “virtually” and not “physically” – hence can’t be installed.
No matter how much confidence you have in the tutorial you’re using (including this one) its important to verify each step. In the case of installing software on a Debian distribution (such as Ubuntu) it pays off having good working knowledge of APT command to validate modules.
Automatic Extension Installation
Many of extension modules may be installed automatically when PHP is installed. Some of these are necessary for WordPress. Each distribution’s repository may have different extension modules that are installed along with PHP. It’s suggested that you make note of the ones that get installed. In my installation example, the following are installed:
libapache2-mod-php7.3
php-common
php-7.3
php7.3-cli
php7.3-common
php7.3-jason
php7.3-opache
php7.3-readline
wp-ops@seebylooking:~ $ sudo apt install php↵
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
libapache2-mod-php7.3 php-common php7.3 php7.3-cli php7.3-common php7.3-json
php7.3-opcache php7.3-readline
Suggested packages:
php-pear
The following NEW packages will be installed:
libapache2-mod-php7.3 php php-common php7.3 php7.3-cli php7.3-common
php7.3-json php7.3-opcache php7.3-readline
0 upgraded, 9 newly installed, 0 to remove and 0 not upgraded.
Need to get 2,969 kB of archives.
After this operation, 14.0 MB of additional disk space will be used.
Do you want to continue? [Y/n]
If the latest PHP version and the requisite extensions aren’t installed, WordPress may run, but some WordPress restrictions and limitations.
The WordPress “Site Health Status” tool helps identify missing extension modules:
Following most WordPress and stack installation tutorials is likely to get a basic WordPress installation up and running. Then by using “Site Health Status” you can fine tune your PHP extensions and software versions as necessary.
This has implications from how software is installed to the directories where programs and data are stored.
One place to view a Macintosh displaying that it is in fact Unix is the apache2 command: apachectl -v
Last login: Thu Feb 20 13:00:30 on ttys000
computername:~ username$ apachectl -v↵
Server version: Apache/2.4.33 (Unix)
Server built: Apr 3 2018 17:54:07
computername:~ username$
SSH Keys allow a secure SSH connection from a client to a host without using passwords. These same keys work with some other communication utilities such as SFTP.
In some instances the reason for using SSH Keys is the convenience of not having to enter passwords. This may also enable some automated connections to function securely because passwords do not have to be included in the automation.
A key reason to use SSH Keys is that it allows disabling a login to a root account (or other sensitive account) with the requirement of a password only – protecting against a malicious root account login using a discovered password.
The first time a client initiates a SSH connection to a host, the client’s user is prompted with information about the host, and the user is asked to agree that it’s the valid host before establishing the connection. Once accepted, a “public key” from the host is stored on the client in a file named known_hosts.
On future connections, the client user is only asked to validate the host identification again is if host sends a public key that no longer matches the one stored in the client’s known_hosts file. This could indicate a security breech.
A key point in properly implementing SSH Keys is knowing that a public key is placed on the client computer and a private key is placed on the host computer. And neither of these keys are the same key that was automatically stored in the known_hosts file used in establishing the identity the host computer.
These SSH public and private keys are typically generated once on the client’s computer using the command: ssh-keygen
The public key is a file generated by the ssh-keygen command – and it’s implemented on the client by simply moving it to the .ssh directory of the client’s user’s home directory.
The private key is a second file generated by the ssh-keygen command. To implement this private key, it has to be appended to host’s known_keys file. This file is in the .ssh directory of the home directory on the host once the connection is established.
There are several way to append the private key file to the host’s known_keys file. The first article referenced below describes this process using the ssh-copy-id command.
It can also be done by first getting a copy of the private key file from the client to the host computer (via ftp, email, etc.) and then using standard UNIX commands to append the contents of the private key file to the known_keys file.
For example: cat private_key_file >> known_hosts
For examples of these procedures, with use of some of the command options, the following references are suggested:
In the case where a host experiences a change of it’s SSH public key (such as re-installing the operating system on a machine) a SSH connection will be prevented do to risk of “man in the middle” security breech. This is addressed and corrective actions offered here:
Sending a test email to my gmail account resulted in a rejected email response due to failing one or more of several possible checks designed to protect gmail accounts from spam:
This post takes a look at the “behind the scenes” on how WP_Query processes a simple custom sort.
My goal was to have an blog of autobiographical posts presented in ascending order – from oldest to newest – the reverse of the standard WordPress presentation.
This task provided a good opportunity for me to brush up on object oriented programming, and bone up on PHP and some slightly more advanced WordPress programming.
There may be several ways to achieve this result – but my plan was:
Create a child theme
Create a function in the child theme’s function.php file causing WordPress to display the posts by date in ascending order.
Almost all the examples I could find of modifying the WordPress criteria for controlling post presentation have only a single criteria – often something like selecting specific “categories” – to include or exclude.
I needed two criteria – one for what to sort, and the second to specify the sort order.
I finally found an example of using two criteria – and was able to construct my function in the functions.php file to sort the posts by “date” and in “ASC” (ascending) order.
Screen 1 – my child theme’s function.php file:
This functions.php in my child theme accomplished exactly what I wanted.
In order to set more complex criteria in the future (and to satisfy my curiosity) I decided I needed to know why this works.
Searching the WordPress CODEX, I learned that “set( )” is a method of WP_Query class, and “pre_get_posts” acts on an instance of an object of the WP_Query class.
(And I learned that the WP_Query class has 4o to 50 methods!)
I presumed (correctly) that “$query” was an instance of the WP_Query class.
My function “my_sortem” – is where I set the two criteria for my sort.
As each sort criteria requires two values, (i.e. “orderby” and “date”) these criteria “pairs” are set using the “set( )” method, instead of the “->” operator to set a object property.
To learn all this I started by finding the places in the WordPress core where objects of the WP_Query class are instantiated. There are four places in three files.
Screen 2: Search result of all of WordPress for “new WP_Query”:
I later learned that it probably doesn’t really matter where WP_Query class objects are instantiated. What was important was to see that the WP_Query class uses a “constructor” – and it took me quite a while to understand why the first two instantiation statements appear cyclical.
The statement:
$query = new WP_Query($query);
appears to instantiate an object used by it’s constructor. As it happens – I believe it does just that.
My first peek at the code was the beginning of the WP_Query class – which declares a public variable of $query an object identifier – because of the use of $query is in the instantiation statement.
Screen 3 – The first few lines of the WP_Query class:
Buried way down on line 3520 is the “__construct( )” function that performs the constructor function when an instance of the WP_Query object is instantiated.
This constructor function takes the class argument “$query” used in the object instantiation and does the following:
Sets the default value of $query to nothing. (”)
Tests to see if the object $query is empty.
If $query is empty, the current object’s method, “query( )” is called with the $query argument.
Screen 4 – The constructor function of WP_Query:
The “query( )” method does the following to the “$query” object:
Calls the object’s “init( )” method.
Sets the object’s “query” property to the result of the “wp_parse_args( )” function.
Sets the object’s “query_vars” property to the value of the object’s “query” propety.
Returns the result of the object’s “get_posts( )” method. It appears this method is performed – but the calling statement does not receive a value as a result of this method. So the point was simply to call the object’s “get_posts( )” method.
The “query( )” method – Screen 5:
According to the comments in the “get_posts( )” method, it’s function is to retrieve an array of the posts based on the query variables – in my case, the “orderby” and “date” and the “order” and “ASC” pairs.
The query variables are the pairs set back by my “my_sortem” function’s use of the “set( )” method. This method loads them into an array:
The query variables are validated in other functions. Here the “parse_orderby( )” function lists the table columns allowed to be sorted – or “orderedby”.
The “order” is also validated – either “DESC” or “ASC” – in all upper case letters as required by SQL.