Willow

Data Fetching and Returning

Context and task are two key aspects of Willow, they are equivalent to Class and Method in PHP and all Willows retrieve data from a single public php method within a class
Version 2.0.5
Latest Changes:

* New: Two view filters added to allow for extension of custom and native WP templates - willow/view/native + willow/view/custom using .willow filetype


Documentation about each release is updated as often as possible, but may lag behind the Master Branch or other generated documentation.

Featured Work
Quinta de Sant’Ana, Portugal
Quinta de Sant’Ana, Portugal

Quinta de Sant'Ana overlooks the picturesque village of Gradil with its cobbled streets, white washed houses and hospitable inhabitants.


Context and Task

Context and task are two key aspects of Willow, they are equivalent to Class and Method in PHP and all Willows retrieve data from a single public php method within a class

Willow comes with the following “contexts”, which can be extended via plugins or themes:

  • action
  • extension
  • group
  • media
  • meta
  • module
  • navigation
  • partial
  • post
  • taxonomy
  • ui
  • user
  • widget
  • wordpress

Their use – in most cases – is totally liberal, as such you can extend the ui context to return data related to taxonomies or wordpress – the available contexts are provided as a broad group of labels by which to organise similar functions, rather than as rigid constraints.

The exceptions to the above rule are the actiongroup and partial contexts which are designed for specific use-cases:


Action

WordPress actions are perhaps what make it such a popular and flexible tool, as they provide developers with a simple and powerful way to change many aspects of how data stored in the database is retrieved and displayed and in turn returned and stored in the db.

Actions are also required to load in assets or to hook callbacks, as such they are a required part of templating – here is a simple example of how Willow can be used to call the wp_head action

{~ action~wp_head ~}

WordPress actions might return data or may load assets, Willow facilitates this behaviour by wrapping the action callback in output buffering, capturing the returned data and adding it to the template in the defined spot where the action is called.


Group

The group context is a set of hooks to ACF field groups and functions, returning data in the correct format for rendering most single field types, relational and repeater fields.

Group fields used along-side JSON formatted ACF configuration settings make for an extremely powerful and portable toolset for development – the ACF classes in Willow mean that little to zero additional data controllers are required between adding fields, saving data and rendering that data correctly in templates.

<div class='col-12 card-columns'>
	{~ group~frontpage_feature {+ 
		"{@ {: frontpage_feature :}
		<div class='card'>
			<div class='card-body'>
				<h5 class='card-title'>{{ title }}</h5>
				<p class='card-text'>{{ content }}</p>
				<a href='{{ [ esc_url ] url }}' class='btn btn-primary'>More</a>
			</div>
		</div>
		@}"
	+} ~}
</div>

The Group context can still be extended like any other context.


Partial

Partials are simply re-usable collections of text, normally plain html but could be any markup or script blocks, which might render a button or a call to action, they cannot contain other Willow tags and are not parsed by Willow before being rendered.

Partials are stored as text files with a .willow extension – here is an example from one of our Q Themes:

{> search_trigger <}

library/willow/partial/partial~search_trigger.willow

<div class="row ml-0">
	<div class="col-12 list-group list-group-flush border-top">
		<div class="list-group-item">
			You can also
			<a 
				class="ml-1 btn btn-primary text-white p-2 q-scroll-top" 
				data-toggle="collapse" 
				data-target="#search_content"
				aria-controls="search_content" 
				aria-expanded="false" 
				aria-label="Search navigation"
				href="#">
				Search our Work
			</a>
		</div>
	</div>
</div>

When you call a Partial, Willow simply looks for a matching stored configuration file and returns the data, as shown below:

file: willow/library/context/partial.php

function get( $args = null ) {

	return $config->get([ 'context' => $args['context'], 'task' => $args['task'] ]);

}

If no matching context/task pair is found, no data will be returned and the partial will render nothing, being removed from the template by the parser clean-up process.

The location and name of the partial file is important due to how the configuration lookups work


Dot Notation

When data returned from a context/task includes arrays of arrays, variables can be accessed directly using dot notation – take the following example which returns both all the commits and also the latest commit version from an ACF field group called work_commit

This Willow is stored in it’s own configuration file, located at library/willow/group/group~work_commit.willow

<span class="ml-1">
	<a 
		class="p-1 p-sm-2 btn btn-primary" 
		href="#commits" 
		data-modal-toggle='modal' 
		data-modal-size="modal-lg" 
		data-modal-title='Commit History' 
		data-modal-body="<table class='table'><thead><tr><th scope='col'>Release</th><th scope='col'>Details</th></tr></thead><tbody>{@ {: work_commit :} <tr><td>{{ work_commit_version }}</td><td>{{ [e] work_commit_message }}</td></tr> @}</tbody></table>" data-modal-target='#q_modal'>
			Version: {{ work_commit.0.work_commit_version }}
	</a>
</span>

The Willow is called simply from the template using the following tag:

{~ group~work_commit ~}

Note that the latest version number is available via Version: {{ work_commit.0.work_commit_version }} this is due to ACF repeater fields returning an indexed array of data, starting from 0 for the first / latest row.

Another example, again pulling data from ACF – this time from a field group called frontpage_work

configuration sits in its own file at library/willow/group/group~frontpage_work.willow

<h5 class="row"><div class="col-12 my-3 ml-3">{{ frontpage_work_title }}</div></h5>

<div class="card mb-3">
	<a href="{{ frontpage_work_top.post_permalink }}">
		<img class="fit card-img-top lazy" style="max-height: 200px" src="" 
			data-src="{{ frontpage_work_top.src {+ [array] config->handle = square-sm +} }}" />
	</a>
	<div class="card-body">
		<h5 class="card-title">
			<a href="{{ frontpage_work_top.post_permalink }}">
				{{ frontpage_work_top.post_title }}
			</a>
		</h5>
		<p class="card-text">frontpage_work_top.post_excerpt</p>
		<span class="badge badge-pill badge-primary ml-1">
			{{ frontpage_work_top.category_name }}
		</span>
	</div>
</div>

The Willow is called from the template using:

{~ group~frontpage_work ~}

One of the fields defined in the field group is named frontpage_work_top and is defined as a Post Object type – the data formatter in Willow has converted the returned Object into a dot notated array, with each field value available at frontpage_work_top.post_excerpt or frontpage_work_top.post_title – these can then be used directly as Willow variables – such as {{ frontpage_work_top.post_excerpt }}


Context Extension

Most Willow contexts include only one task-  a getter method – which looks for a matching context/task ( class->method ) in the plugin – take the following example:

{~ post~title ~}

This Willow will hit the post context and look for a task title, the process for that look up works in the following order:

  1. Check for a registered extension, with a class post and a public method title
  2. Check for a public method within the base post class with a method title
  3. Check for a matching getter method in Willow i.e. method_exists( '\willow\get\post', $method )

The following example shows how to extend the ui context ( it would also work for any other context )

This can be rendered from the template using

{~ ui~hello ~}

With the configuration in a Willow file located at library/willow/ui/ui~hello.willow

{@ {: hello :}
        <div class="col-12">YOU are {{ who }} and the time is {{ time }}</div>
@}

The resulting HTML will be:

<div class="col-12">YOU are Me and the time is Now</div>
<div class="col-12">YOU are You and the time is Then</div>