Learning best practices from WordPress code – Tableform

Learning new frameworks is always a good idea even if you’re not going to use them in your job. For instance I don’t like WordPress, but there are things inside worth mentioning. One of them is how they output tables.

So, imagine you traveled to year 2100, where refrigerators finally managed to detect food an got their sites in the internet. You are assigned a task to write a front-end for refrigerator website. Luckily you have all the data about the products stored in the MySQL v21.1 database table.

The table is called products and has following fields

  • id, INT
  • name, VARCHAR
  • category, VARCHAR
  • created, DATETIME
  • last_accessed, DATETIME
  • expiry_date, DATETIME
  • screenshot, VARCHAR # URL to the image file on server
  • temperature, DECIMAL
  • etc. (add more fields in comments)

For simplicity let’s output the data only from this table, not from other referenced tables (categories, tags, refrigerator_sections etc.).

Okay, so that’s the task. You have $records array and $columns list and you need to fill a function:

function display_rows() {
  // Get the records
  $records = $this->items;
  // Get the registered columns
  $columns = $this->get_columns();
  // ???
}

How would you do it? Probably the first thing that you figure out is

function display_rows() {
  // Get the records
  $records = $this->items;
  // Get the registered columns
  $columns = $this->get_columns();
  foreach ($records as $record) {
    extract($record);
    echo "<tr>";
    echo "<td>" . $id . "</td>";
    echo "<td>" . htmlspecialchars($name) . "</td>";
    echo "<td>" . htmlspecialchars($category) . "</td>";
    echo "<td>" . $created . "</td>";
    echo "<td>" . $last_accessed . "</td>";
    echo "<td>" . $expiry_date . "</td>";
    echo "<td>" . '<img src="' . $screenshot . '"/>' . "</td>";
    echo "<td>" . $temperature . " °C </td>";
    echo "</tr>";
  }
}

Fine. Now a customer from LG is calling you. “Hey, our temperature sensors are a bit buggy”, he says, “can you please remove that field for our fridges?”. Then a customer from Samsung shows up: “Hey, we did tested your site on our very old phone, Samsung Galaxy S4, and the site is too wide for it. Can you please show for the mobile version only two fields, expiry date and a name, in that order?”. Finally your boss comes to you and says that we need to give user an ability to hide any column and rearrange them in any order, otherwise we’ll get sued for public discrimination of varchars and datetimes.

The solution for this problem implemented in WordPress is very simple and elegant. You just have to ensure that $columns contains only visible columns in the correct order and then use switch statement. Here you go.

function display_rows() {
  // Get the records
  $records = $this->items;
  // Get the registered columns
  $columns = $this->get_visible_columns();

  foreach($records as $record) {
    echo "<tr>";
    foreach ($columns as $column) {
      switch ($column) {
        case 'id':
        case 'created':
        case 'last_accessed':
        case 'expiry_date':
          echo "<td>" . $record[$column] . "</td>";
          break;
        case 'temperature':
          echo "<td>" . $record[$column] . " °C </td>";
          break;
        case 'name':
        case 'category':
          echo "<td>" . htmlspecialchars($record[$column]) . "</td>";        
          break;
        case 'screenshot':
          echo "<td>" . '<img src="' . $record[$column] . '"/>' . "</td>";
          break;
      }
    }
    echo "</tr>";
  }
}

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.