Several core updates this week including a new way to perform $pages->find() searches by using Field tags, a new Field tag manager, new methods added to our $input API variable, new Inputfield traversal methods, and more…
A new way to search with upgraded tags for fields
Not everyone knows about this, but for a few years now, you've been able to assign tags to fields in ProcessWire (found in Setup > Fields > your_field > Advanced). When tags are assigned to a field, that field gets grouped with other fields having the same tag in the main fields list (Setup > Fields). Any field can have any number of tags (one field can be in multiple tags). In the past, tags have only been useful in providing some visual connection among fields when on the screen that lists them all. As the quantity of fields in your site increases, this grouping becomes more useful.
But this week, we expanded the purpose of tags, made them a lot more useful and a lot simpler to manage. Tags can now be used as fields in selectors to
$pages->find() and similar API calls. You simply use the name of a tag where you would otherwise use the name of a field. When you do so, it will search all of the fields that have that tag assigned.
Example of how they work
Lets say that I have a search engine on my website, and I want it to search these fields: title, body, sidebar, summary, bio. Currently my API call to find pages in those fields looks like this:
$results = $pages->find("title|body|sidebar|summary|bio~=text");
That's kind of a mouthful. And if at some point I want to change what fields get searched (like adding a new one, or removing an existing one), I've got to go in and update the code above.
In ProcessWire 3.0.106, now you can use a tag to accomplish the above. Simply go to Setup > Fields > Manage Tags, and create a new tag. I'll name mine “search_text”, and assign the fields mentioned above to it. Now my API call can be done like this:
$results = $pages->find("search_text~=text");
The above call would produce an identical result to the previous one. Only now my API code doesn't have to keep track of which fields are searchable—something I can now maintain more appropriately in the admin, where my fields are defined. Should I need to search the same group of fields somewhere else, reusability has now been greatly improved.
Not just for text fields…
While the above example demonstrates finding in text fields, tags are by no means limited to being used with text fields. You can use them with whatever types of fields you want to. Though if you are mixing different types of fields in the same tag, and plan to use them in a search, just be mindful that fields generally have to have similar types in order to be searched together, as different fieldtypes support different search operators in selectors.
Use tags anywhere you’d use a field
In page find()'ing selectors, these tags can be substituted in just about any spot that a regular field could be. For instance, they can be used in cases where a subfield might be used, like
pageref.tag. Or we can even specify a subfield after the tag, like
tag.title, which is what we might do if “tag” represented multiple page reference fields. Tags can also be used as part of an existing OR set of fields, like
Simple to define and maintain
In addition to the new usefulness of tags in searches, the management of tags has been greatly improved. No longer do you have to manually enter them when editing a field. Now there is a built-in “Manage Tags” section of ProcessField. This is best demonstrated by screenshots. First, the “Manage Tags” button appears at the bottom of the fields list (Setup > Fields):
When we click on that button, we get a list of tags we have defined, along with an input to start a new one:
If we click to edit a tag, you can see how we add/remove fields from the tag:
When viewing our main fields list (Setup > Fields), fields are organized by tag. This is not new to 3.0.106, but just showing this for those that may not have used tags before:
New $input methods
$input->urlSegmentStr($verbose = false, $options = array());
The urlSegmentStr() method was updated to accept new $verbose and $options arguments (which are both optional). Previously it accepted no arguments. The default behavior of the method is to return the URL segment string for the request, i.e. “foo/bar/baz” (URL segments 1, 2 and 3 separated by slashes). The urlSegmentStr() has never included a pagination number or trailing slash. But if you specify true for the new $verbose option, it will include pagination number and trailing slash settings of the current $page as part of the URL segment string that it returns. This makes it more useful for some instances where you are re-using the URL segment string to construct a URL for output. The new $options argument is likely to be used rarely, but lets you specify what URL “segments” (array) should be used, what the current “pageNum” is (pagination number), and what should be considered the current “page” (Page object). All these $options are determined automatically when not specified.
$input->pageNumStr($pageNum = 0)
A new pageNumStr() method was added, which corresponds to the existing pageNum() method, except that it returns the string like “page123” rather than integer, for page 123. The prefix “page” will be consistent with the configured setting and language-specific settings. This method is more useful than the existing pageNum() method when you are constructing new URLs for links or output during runtime. You can specify a $pageNum argument to the method and it will use that, otherwise it'll use the current pagination number.
A new httpHostUrl() method was added, which returns the current scheme and hostname in a string, and excludes any path. For example “https://processwire.com” is what it would return for this site. Previously if you wanted this value, you would have had to construct it manually from $config settings, or extract it from some other call that returns a URL with scheme.
New $inputfield traversal methods
Added this new method which returns the furthest InputfieldWrapper from the Inputfield it is called from. If the Inputfield has already been added to a form, this would be the InputfieldForm element.
Added this new method which returns the InputfieldForm instance that this Inputfield is part of. This is similar to the getRootParent() method mentioned above, except that it will return null if the root parent is not a form.
Other updates in 3.0.106
user-admin-all permission to enable user admins with this permission to be able to assign roles with user-admin permission (per request on GitHub).
Fixed several minor issues with our front-end page editing (PageFrontEdit module) and improved rendering when paired with AdminThemeUikit. In addition, several optimizations and code improvements were made to our core ProcessPageEdit module.
I also updated our built-in pagination module (MarkupPagerNav) to automatically populate
$config->pagerHeadTags, which contains the appropriate
<link rel='next'> and
<link rel='prev'> tags for search engines to better understand your pagination. To use, simply populate them in your document
<head> after pagination has been rendered, whether from the PageArray renderPager() method or some other call that uses MarkupPagerNav. Of course, you can always render these <link> tags yourself using the
$config->urls->prev, which have been populated by MarkupPagerNav in all PW 3.x versions. But the new pagerHeadTags property makes it that much simpler.
In addition to the above, like most ProcessWire versions, 3.0.106 also contains several minor tweaks and fixes in response to GitHub issue reports. That's all for this week. Hope that you all have a great weekend, and stay up-to-date with ProcessWire Weekly issue #214 tomorow (Saturday).
Your e-mail is kept confidential and not included with your comment. Website is optional.