Dev Notes

Various Cheat Sheets and Resources by David Egan/Carawebs.

Parse YAML in PHP Using Symfony YAML


Composer, PHP, WordPress, YAML
David Egan

I do a lot of work in WordPress. I also build a lot of static websites - both for rapid design in-the-browser and as a low-cost small-business website solution. I mainly use the excellent Jekyll static site generator.

Jekyll uses YAML for config and data files (it can also use CSV format, but that’s another story). WordPress doesn’t use YAML.

I like YAML because it is very human friendly - the whole team (including non-developers) can easily build YAML config files in a way that you’re not going to see with formats like JSON or XML. This is an example of a YAML array used to create JavaScript variables for use in a Google map:

# Map centre Latitude & Longitude
# ------------------------------------------------------------------------------
latitude: 52.7157856867271
longitude: -8.8741735070805

zoom: 15
#height: 548px

# Set custom colour variables
# ------------------------------------------------------------------------------
waterColour: "#398A8D"
landColour: "#dec7c7"
mainRoadColour: "#777777"
minorRoadColour: "#a9a9a9"

# A nested array
# ------------------------------------------------------------------------------
test:
  - One
  - Two
  - Three

In the context of Jekyll, you could use this as a data file (e.g. map.yml), writing JavaScript variables into <head> something like this:

<script>
var cwCentre = {
  latitude:{{ site.data.map.latitude }},
  longitude:{{ site.data.map.longitude }},
  zoom:{{ page.map-zoom }},
  mainMarker:"{{ site.baseurl}}/{{ site.data.map.mainMarker }}",
  secondaryMarker:"{{ site.baseurl}}/{{ site.data.map.secondaryMarker }}",
  waterColour:"{{ site.data.map.waterColour }}",
  landColour:"{{ site.data.map.landColour }}",
  mainRoadColour:"{{ site.data.map.mainRoadColour }}",
  minorRoadColour:"{{ site.data.map.minorRoadColour }}",
  title: "{{ site.data.map.title | escape }}",
  description:'{{ map_description | markdownify | strip_newlines }}',
};
{% if "multi-centre" == page.map-type %}
var markers = [
  {% for location in site.data.secondary-map-coords %}
    [
      '{{ location.name | escape }}',
      {{ location.latitude }},
      {{ location.longitude }},
      '{{ location.description | escape }}'
    ]
    {% unless forloop.last %},{% endunless %}
  {% endfor %}
];
{% endif %}

</script>

YAML in WordPress

I recently needed to convert a Jekyll site to a WordPress theme. Moving the map config settings required parsing YAML data into a PHP array. Fortunately this can be achieved pretty easily thanks to the Symfony YAML component.

I’m a recent convert to Composer, and find it amazingly powerful. You can add the Symfony YAML component with a single composer command.

Add Symfony/YAML Using Composer

composer require symfony/yaml

When you run this, composer will add a new symfony/yaml directory under the project vendor directory. It will also add the relevant namespace to the autoload_psr4.php file, so that the new class will be autoloaded.

Using the YAML parser

To read the YAML contents of the config fiel into a PHP array:

<?php
use Symfony\Component\Yaml\Parser;

$yaml = new Parser();

$value = $yaml->parse( file_get_contents( get_template_directory() . '/assets/map.yml' ) );

For the YAML content presented above, the following will be output:

$value = array (
  'latitude' => 52.715785686727102,
  'longitude' => -8.8741735070804992,
  'zoom' => 15,
  'waterColour' => '#398A8D',
  'landColour' => '#dec7c7',
  'mainRoadColour' => '#777777',
  'minorRoadColour' => '#a9a9a9',
  'test' =>
  array (
    0 => 'One',
    1 => 'Two',
    2 => 'Three',
  ),
);

This array can be passed to wp_localize_script() when enqueuing the map script.

The WordPress/PHP way would be to collect such data from a form on an admin page, storing the data in the wp_options table. However taking variables from YAML files can be a good way to quickly port settings, which might even be used as defaults. It might also be a good way to configure certain project settings.


comments powered by Disqus