This week updates were focused on covering GitHub issue reports and feature requests, plus some great new performance improvements to our page traversal methods. More
ProcessWire 3.0.25 and 2.8.25
This week we've got a pretty major upgrade to our page finding selectors that we think you will find useful in a lot of cases! Now you can accomplish much more with less, and this really brings our selectors to the next level.
In ProcessWire, the most basic representation of an item within a selector string follows the format
field=value (see Selectors documentation). We use these throughout ProcessWire, but most commonly for finding pages via API calls like $pages->find("selector").
Within that context, you've been able to specify not only
field=value, but also
field.property=value, where "property" can be any property of the field. This enables you to match values from field types that might have multiple properties. Page fields are the most common case here.
Going forward in this post, we'll refer to
What you haven't been able to do is to go beyond that 2-part
a.b syntax for the field/property portion of the selector. Meaning you've not been able to do things like
a.b.c.d=value, when it comes to matching pages.
Syntax and examples
For example, lets say you wanted to find all pages using template "building" that have architects located in the city of Chicago. For our example, we're assuming that both "city" and "architects" are Page fields in ProcessWire. You may have done something like this – find the architects in one operation, and the buildings in another:
$architects = $pages->find("template=architect, city.title=Chicago"); $buildings = $pages->find("architect=$architects");
That's easy enough, but wouldn't it be nicer if you could just do this?
$buildings = $pages->find("architect.city.title=Chicago");
As of ProcessWire 3.0.25 (and 2.8.25) now you can! We'll refer to the above 3-part field as
a.b.c. You can nest those properties as deep as you want to, for instance
a.b.c.d.e (if you find the need).
Lets say that we wanted to broaden our query to include buildings designed by all architects in the state of Illinois. We'll assume that "state" is a Page field attached to template used by "city" pages, and we'll assume "abbr" is a text field used to hold the state abbreviation:
$buildings = $pages->find("architect.city.state.abbr=IL");
Broadening further, perhaps we want buildings from all architects in the USA:
$buildings = $pages->find("architect.city.state.country.abbr=USA");
Or perhaps both USA and Canada:
$buildings = $pages->find("architect.city.state.country.abbr=USA|CA");
The point to get across here is that you can get a lot more granular with your matching than previously. While you could have also accomplished this with nested sub-selectors, the syntax may have kept you from pursuing it, even when you could. This new syntax provides a more clear and readable alternative that should help you to accomplish more with less.
Details and usage
This syntax is primarily useful when dealing with Page fields, as they form the basis of cross references between pages in ProcessWire. So the
a part of
a.b.c should always be the name of a Page field, or something else that references a Page. For instance
children keywords may be used here to reference the family hierarchy the page(s) to be matched might live within.
In addition to Page fields, and the "parent" and "children" keywords, support has also been built in for Repeater, RepeaterMatrix, and PageTable fields. Meaning, any of these can represent the "a", "b", or "c" portion of the field.
The last two components of the "field" (i.e. "b.c") do not necessarily have to reference any of the above. They can be any field that has a property to match. For instance, if we wanted to find all buildings where the architect also had one or more images:
$buildings = $pages->find("architect.images.count>0");
Basically, the syntax should work just about anywhere you would expect to. Though there are a couple of limitations, mentioned below.
While you can use OR conditions in the value portion of the selector, you can't with the field portion. Meaning, you can do
a.b.c but cannot do
As this syntax is brand new, you might also find it may not work in some of the more complex usages of OR-groups, sub-selectors and such. So for the short term, try not to combine this syntax with those more complex selector features. Or if you do, verify your results before assuming it works – we'll be slowly introducing support for more complex usages as time goes on.
The last limitation to mention here is that this "a.b.c" syntax is implemented for database-driven page finding operations (powered by our PageFinder class), and not currently implemented for in-memory matching. Though it's unlikely you would need this syntax for pages/assets that are already in memory, but wanted to mention it just in case. Of course, the vast majority of API functions you supply selector strings to are database-driven page finding operations, so this new usage is supported by most API calls you are likely to use.
We hope you enjoy these enhancements to page-finding selectors in ProcessWire 3.0.25 and 2.8.25! Please let us know how they work for you, and likewise if you run into any issues while using them.
With support for paginated Fieldtypes, ProcessWire’s scalability has moved to the next level. Not sure what this means? Don't worry, this post has a screencast that makes it clear. We've also got some other nice upgrade for ProFields Table. More