ryan Posted September 2, 2022 Share Posted September 2, 2022 This week on the core dev branch we’ve got some major refactoring in the Page class. Unless I broke anything in the process, it should be more efficient and use less memory than before. But a few of useful new methods for getting page fields were added in the process. (A couple of these were also to answer feature request #453). Dot syntax You may have heard of dot-syntax for getting page fields, such as $pages->get('parent.title') where “parent” can be any field and “title” can be any field that has subfields. This is something that ProcessWire has supported for a long time, but it doesn’t get used much because it was disabled when output formatting was on. So it wasn’t something you could really count on always being there. Now you can — it is enabled all of the time. But it’s also been rewritten to be more powerful. When using dot syntax with a multi-value field (i.e. any kind of WireArray value) you can also specify field_name.first to get just the first value or field_name.last to get just the last value. i.e. $page->get('categories.first'); will take a value that was going to be a PageArray (‘categories’) and return just the first Page from it. Bracket syntax With bracket syntax you can call $page->get('field_name[]') with the (‘[]’ brackets at the end) and it will always return the appropriate array value for the type, whether a PageArray, WireArray, Pagefiles/Pageimages, or regular PHP array, etc. This is useful in cases where you know you’ll want a value you can foreach/iterate. Maybe you’ve got a Page field that set set to contain just 1 page, or maybe you’ve got a File/Image field set to contain just 1 file. But you want some way to treat all of your page or file/image fields the same, just append “[]” to the field name in your $page->get() call and you’ll always get an array-type value, regardless of the field settings. This bracket syntax can also be used for getting 1 value by index number. Let’s say you’ve got a page field named “categories” that contains multiple pages. If you want to get just the first, you can just call $page->get('categories[0]'); If you want to get the second, you can do $page->get('categories[1]'); This works whether the field is set to contain just one value or many values. Using the first index [0] is a good way to ensure you get 1 item when you may not know whether the field is a single-value or multi-value field. Another thing you can do with the bracket syntax is put a selector in it to filter a multi-value field right in the $page->get() call. Let’s say you want all categories that have the word “design” in the name. You can call $page->get('categories[title%=design]'); If you want just the first, then $page->get('categories[title%=design][0]'); What’s useful about using selectors in brackets is that this does a filter at the database-level rather than loading the entire ‘categories’ field in memory and then filtering it. Meaning it's a lot more memory efficient than doing a $page->get('categories')->find('title%=design'); In this way, it’s similar to the already-supported option to use a field name as a method call, for instance ProcessWire supports $page->field_name('selector'); to achieve a similar result. Dot syntax and bracket syntax together You can use all of these features together. Here’s a few examples from the updated $page->get() phpdocs: // get value guaranteed to be iterable (array, WireArray, or derived) $images = $page->get('image[]'); // Pageimages $categories = $page->get('category[]'); // PageArray // get item by position/index, returns 1 item whether field is single or multi value $file = $page->get('files[0]'); // get first file (or null if files is empty) $file = $page->get('files.first'); // same as above $file = $page->get('files.last'); // get last file $file = $page->get('files[1]'); // get 2nd file (or null if there isn't one) // get titles from Page reference field categories in an array $titles = $page->get('categories.title'); // array of titles $title = $page->get('categories[0].title'); // string of just first title // you can also use a selector in [brackets] for a filtered value // example: get categories with titles matching text 'design' $categories = $page->get('categories[title%=design]'); // PageArray $category = $page->get('categories[title%=design][0]'); // Page or null $titles = $page->get('categories[title%=design].title'); // array of strings $title = $page->get('categories[title%=design].title[0]'); // string or null // remember curly brackets? You can use dot syntax in there too… echo $page->get('Page “{title}” has {categories.count} total categories'); I’m not going to bump the version number this week because a lot of code was updated or added and I’d like to test it for another week before bumping the version number (since it triggers the upgrades module to notify people). But if you decide to upgrade now, please let me know how it works for you or if you run into any issues. Thanks for reading, have a great weekend! 20 4 Link to comment Share on other sites More sharing options...
Fuzen Posted September 2, 2022 Share Posted September 2, 2022 This is awesome stuff. Thanks @ryan. Link to comment Share on other sites More sharing options...
adrian Posted September 2, 2022 Share Posted September 2, 2022 Hi @ryan - all sounds very cool! I just upgraded by local sandbox install and now I am seeing: Error: Call to a member function isDefault() on bool in /wire/core/PagesLoaderCache.php:311 It seems to be coming from the $page->get('process=236') call, but you should see it if you have Tracy running with any of these panels open: Let me know if you have any troubles reproducing. 2 Link to comment Share on other sites More sharing options...
pwired Posted September 3, 2022 Share Posted September 3, 2022 While this might be all great ... the more I see these weekly upgrades ... the more I start to wonder: is processwire made to learn coding or to make websites ... Or maybe both ? Link to comment Share on other sites More sharing options...
cb2004 Posted September 3, 2022 Share Posted September 3, 2022 @pwired for me it helps me with both. How about you? 1 Link to comment Share on other sites More sharing options...
pwired Posted September 3, 2022 Share Posted September 3, 2022 Quote for me it helps me with both. How about you? You forgot to mention in what way it helps you with both ... any examples ? After so many weekly updates already with new xyz coding options added ... To be honest, I simply cannot keep track of them anymore ... But maybe you can ... After a while ... who is still going to remember all of them ? How many are really going to use them ? Being productive has my focus ... not getting fragmented in weekly new added xyz coding options Link to comment Share on other sites More sharing options...
kongondo Posted September 3, 2022 Share Posted September 3, 2022 (edited) 20 hours ago, adrian said: I just upgraded by local sandbox install and now I am seeing: Error: Call to a member function isDefault() on bool in /wire/core/PagesLoaderCache.php:311 Same here. In fact, the upgrade changed my multilingual site's default language to German ?. Edit: It also converted a non multilingual site to multilingual and made German the default. Edited September 3, 2022 by kongondo 1 Link to comment Share on other sites More sharing options...
bernhard Posted September 4, 2022 Share Posted September 4, 2022 I'm also having troubles with my RockMatrix module that worked great until the last commit and now stopped saving any content. I'm investigating... Link to comment Share on other sites More sharing options...
bernhard Posted September 4, 2022 Share Posted September 4, 2022 Turns out it is not an issue with my modules... I've installed a fresh installation of the latest PW. I have even done that manually to make sure it has nothing to do with the installation process of RockShell. When I try to edit the "Home" page and rename the title from "Home" to "Home2" the page saves but the change is not saved: This is my config - maybe it makes a difference which settings to use on install? <?php namespace ProcessWire; if(!defined("PROCESSWIRE")) die(); /** @var Config $config */ /*** SITE CONFIG *************************************************************************/ $config->useFunctionsAPI = true; $config->usePageClasses = true; $config->useMarkupRegions = true; $config->prependTemplateFile = '_init.php'; $config->appendTemplateFile = '_main.php'; $config->templateCompile = false; /*** INSTALLER CONFIG ********************************************************************/ $config->dbHost = 'db'; $config->dbName = 'db'; $config->dbUser = 'db'; $config->dbPass = 'db'; $config->dbPort = '3306'; $config->dbCharset = 'utf8mb4'; $config->dbEngine = 'InnoDB'; $config->userAuthSalt = 'xxx'; $config->tableSalt = 'xxx'; $config->chmodDir = '0755'; // permission for directories created by ProcessWire $config->chmodFile = '0644'; // permission for files created by ProcessWire $config->timezone = 'UTC'; $config->defaultAdminTheme = 'AdminThemeUikit'; $config->installed = 1662291609; $config->httpHosts = array('dev-save-issue.ddev.site'); $config->debug = true; Link to comment Share on other sites More sharing options...
ryan Posted September 4, 2022 Author Share Posted September 4, 2022 @adrian @bernhard Thanks, I think I've fixed these issues and they are now on the dev branch. @kongondo I wasn't able to duplicate the language issues you mentioned, but am guessing they must be related to the things Bernhard and Adrian mentioned, but please let me know if you continue to see them. 3 Link to comment Share on other sites More sharing options...
bernhard Posted September 4, 2022 Share Posted September 4, 2022 Everything working as expected now, thx @ryan ? Link to comment Share on other sites More sharing options...
adrian Posted September 4, 2022 Share Posted September 4, 2022 Looks good here now too - thanks Ryan Link to comment Share on other sites More sharing options...
kongondo Posted September 4, 2022 Share Posted September 4, 2022 30 minutes ago, ryan said: @kongondo I wasn't able to duplicate the language issues you mentioned, but am guessing they must be related to the things Bernhard and Adrian mentioned, but please let me know if you continue to see them. Thanks Ryan. The language bit was a weird one. After more tests, it seemed to be related to the use of ProcessDatabaseBackups. I couldn't replicate the issue a third time so didn't debug further. Will keep an eye out, thanks. Link to comment Share on other sites More sharing options...
cb2004 Posted September 6, 2022 Share Posted September 6, 2022 On 9/3/2022 at 2:11 PM, pwired said: You forgot to mention in what way it helps you with both ... any examples ? After so many weekly updates already with new xyz coding options added ... To be honest, I simply cannot keep track of them anymore ... But maybe you can ... After a while ... who is still going to remember all of them ? How many are really going to use them ? Being productive has my focus ... not getting fragmented in weekly new added xyz coding options I work every day with ProcessWire as 90% of our websites are built with it. We have a base install that we use for every new project, if anything from the weekly updates is an improvement on what we use in there, then we update our base install which will have the improvement on our next project. We also have a lot of retained clients who pay monthly to keep things running smoothly, again if there are any improvements in the weekly updates, we can slowly apply these to the retained projects going forward. The last major improvement in our workflow was the combo field which we use on all our latest projects, we wouldn't know about that if the weekly updates didn't exist. You mention being productive which I think is the best thing about ProcessWire. We have installs from years ago that are still running, and we don't have to worry about them, or care how they were built even if the client is not on a retainer, we just leave them. However, the client may come back and request some updates, we can start with running all the upgrades knowing that we have had very few issues in the past with just running upgrades, and we already know that behind the scenes there will be improvements in doing this, and improvements if we wish to use them with our coding. I guess what I am trying to say is you don't need to worry about the weekly updates if they don't have an impact on you, but the next time you check the documents you may see something that you can use as an improvement. I am sure nobody remembers all the improvements, I don't, nobody uses all of them, I don't, but they are there to use if you want and know about them. Everything still works with a site that you have already built if you just run an upgrade. There may be 51 weekly posts in a year I have no interest in, but 1 weekly post which is golden, I will take that for something I don't pay for (other than through the Pro modules). How does it make me learn coding, every day is a school day and seeing how things are done in ProcessWire makes me think in different ways when I am using other tools, I suppose that is what will happen when 90% of our websites are built with ProcessWire. 10 Link to comment Share on other sites More sharing options...
bernhard Posted September 6, 2022 Share Posted September 6, 2022 53 minutes ago, cb2004 said: I work every day with ProcessWire as 90% of our websites are built with it. Would be interested to hear what the other 10% are and why they are not ProcessWire as well ? Factual question - no offense in any way. 1 Link to comment Share on other sites More sharing options...
pwired Posted September 6, 2022 Share Posted September 6, 2022 Quote ..... and seeing how things are done in ProcessWire makes me think in different ways when I am using other tools ..... Although I only asked for some coding examples your reply about Processwire in general is very welcome. Ryan is a very clever coder and this forum is full of very clever coders with a lot of experience. If I was a very clever coder too then I would never post my comments from which I know some find them irritating. As as solution I am building my own personal database where I can store, evaluate, sort out and apply the weekly new added coding options. With it I already could apply new coding options to expand on the delayed output strategy that I am using all the time. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now