Jump to content

ryan

Administrators
  • Posts

    17,231
  • Joined

  • Days Won

    1,697

Everything posted by ryan

  1. This week I've been working on a combination of core improvements, optimizations, and fixes, plus a dozen pull requests have been added. Thanks for all of the great pull requests to the core that many of you have submitted. PR authors will appear in our GitHub contributors list once the changes are merged to the master branch (that's apparently how GitHub works). I do think soon we'll focus on getting a new master version out, as 3.0.165 is starting to feel old relative to the current dev branch. You can see all that's been changed and added this week in the dev branch commit log. Next week we'll be doing more of the same, though planning to get into some of the PRs that I didn't this week because they required more review and testing (those that involved more than a few lines of code changes). We're not going to bump the dev branch version till likely next Friday, since this week's work will continue into next week. Thanks for reading and have a great weekend!
  2. This week we focus in on a new and unique Inputfield module added to the core that enables a lot of useful new input capabilities for tags, sortable multiple selection and custom user input. I introduced it in last week's forum post, but it was further improved this week and reached a point where I thought it would need some dedicated documentation, so this post dips into that and goes quite a bit more in-depth than last week’s. I never got around to bumping the version to 3.0.176 because the module wasn't quite done till Thursday (kept updating with improvements), but just in case there's any confusion about versions between last week and this week, I bumped it to 3.0.177 even though it contains what was originally intended for 3.0.176, plus more— https://processwire.com/blog/posts/pw-3.0.177/
  3. Instance refers to an object instance of the "ProcessWire" object, and there can be more than one. When used, it has full access to the instance it connects to, so it's not something that could be done through http. Though if you need to share some data through http then this is very simple to do in PW (especially now with URL/path hooks), but it's something completely different in this case. I'll take your word about the technical semantics. I don't think we intended that broad of a definition for the forum rules, though perhaps they need to be modified to better clarify. I was thinking more of "relating to the government or political party of a country" type political stuff. If someone wants their avatar to communicate they like running, swimming or biking, or that they are against racism, cancer or school shootings, or they want to have a bow to support breast cancer awareness, a puzzle piece to support autism awareness, support diversity, etc., seems fine. Though if they want to open a topic about it, we'd want it in the beer garden or one of the other off-topic boards. I'd also say the difference between positive and negative matters too. Hopefully we veer on the positive side as being a place for inclusion where everyone is welcome and we support and help each other out, at least I think of you all here as my best friends.
  4. @Torsten Baldes I think it works well. We use it for https://processwire.com/modules/, where it pulls (and manipulates) all the data from a separate PW installation using the multi-instance support. I recommend keeping all instances running the exact same PW version. Supporting multi-instance does sometimes require recognition from installed modules, and and I think it's likely some 3rd party modules might not fully support it (though don't know of any specifically), so the fewer 3rd party modules installed I would think the less likely you are to run into issues, but I'm only guessing there. I don't know what's up with the chains and fire in the logo (looks potentially violent), but I just googled it and ended up here. They don't appear to be promoting racism and do not appear to be affiliated with a political or religious group, unless you guys know something I don't? It looks like it's for an exercise/running group and clothing brand with a seemingly positive message "Running is to unite people, not to disconnect or isolate them". Or are the graphic elements the logo inferring something bad or affiliated with a religious/political group?
  5. The latest version on the dev branch will actually get the version bump tomorrow, as I'm currently on a 7-day work schedule with shorter days (factors outside my control). So what I'd usually be doing Friday is happening Saturday or Sunday instead. But the updates in 3.0.176 are well enough defined to write about here, and everything is there already, it's primarily just additional testing that remains before the version bump. Relative to 3.0.175 version 3.0.176 contains about 25 commits or so with most of the focus being resolution of minor issue reports. However, 25 commits is a lot so there are also some new things here too. First off, as requested, PW now supports multiple database read-only configuration settings rather than just one. When more than one is present, it will select one randomly. To use multiple read-only connections, simply specify a regular PHP array of 2 or more associative arrays in your /site/config.php file, like this: $config->dbReader = [ [ 'host' => 'mydb1.domain.com' ], [ 'host' => 'mydb2.domain.com' ], [ 'host' => 'mydb3.domain.com' ], ]; In each array item, you can specify 'host' (as above), along with any other setting (name, user, pass, port, etc.) that differs from the primary DB connection. There's another benefit to having multiple dbReader hosts as well: If the connection for one fails, it'll move on to the next, and keep moving on till it either finds a working connection or finishes the list. Next up, ProcessTemplate (Setup > Templates) gained a "Manage Tags" feature just like the one you have in ProcessField (Setup > Fields). So now it's a lot easier than before to define and manage tags for multiple templates as a group. In addition to this, both ProcessField and ProcessTemplate now have an actual Tags field (like the one available for files/images) rather than just a plain text input. The Template class also gained several new API functions for working with tags on templates. Templates in PW have supported tags for a long time, but now they are backed up by a much better API and admin interface to them. In order to support the new tags inputs in ProcessTemplate and ProcessField, a Tags Inputfield module was developed, named InputfieldTextTags (the name InputfieldTags was already taken). This module is now in the core, and it uses the existing Selectize tags functionality already present in the core, but previously only used by file and image fields. While developing this, I found it was a nice alternative to AsmSelect for sortable multiple selection, so made it available as an additional input option for both Page and Options fields. When used in a multiple-selection context, it ends up being a multiple selection input that takes up no more space than a text input, which can be quite handy for a lot of situations, and more space friendly then AsmSelect or even PageAutocomplete. I've noticed travel websites using a similar solution for multiple selection of destinations or amenities in search forms, and perhaps this one has some front-end potential as well. Since it's just an Inputfield without a dedicated Fieldtype, it is likely to work just as well on front-end forms (like FormBuilder) as it does on admin forms. Longer term I imagine we'll have an optional FieldtypeTextTags module as well, which will be useful for supporting user-entered tags sharable between pages. Currently it does support user entered tags if you choose it as an input option for a regular "text" field (see bottom of Details tab in field editor), and it can optionally be combined with predefined selectable tags as well. While all of these updates are on the dev branch now, look for the version bump this weekend after I've had a little more time testing. Though if you'd like to help test, feel free to grab it now. Thanks for reading and have a great weekend!
  6. @fedeb Looks like I missed a spot on the updates to the Event class, I have fixed that and removed the references to the old fields (location, notes). 1. In ProcessWire a Page can be in a "output formatted" or unformatted state. You can toggle output formatting on with $page->of(true); or toggle it off with $page->of(false); Or you can get the current state with $formatted = $page->of(); When output formatting is on, values returned from the page are intended for output and thus can contain runtime formatting such as entity encoding. This is good for output, but definitely not something you'd want saved the database, so when you are creating pages or saving values on pages you want to have its output formatting disabled, i.e. $page->of(false); This should be done before getting, setting or modifying values that will be saved. 2. The location and notes aren't supposed to be there. I removed them in favor of making the module simpler by just having "title" and "date", and then people can add any additional columns they want. 3. The set() and get() functions are inherited from the WireData class. (Event extends WireData) 4. InputfieldEvents won't be included unless something asks for it (like the page editor in the admin). If you are just using the API side, then the InputfieldEvents module likely will never be loaded or come into play. It's still nice to have in case you ever want to see or edit your data in the admin.
  7. This week I didn't get as much time as I'd hoped to work on the core, but still managed to get a few things done. I did get some small core updates in place, but not enough for a version bump, and got the second covid vaccine, kids back to in-person school (3 hours a day, after a year of being away), and a couple more major module upgrades released. In last week's post, someone asked for an update to the ProcessWireUpgrade module, and I had a look and a realized it was long overdue for one, so I tried to cover a lot of ground there. The new version is now out and improved throughout. Grab this latest version of ProcessWireUpgrade if you are interested. It's always been pretty useful, but it's even more so now. I've also updated the modules directory feed so that it can let you know when Pro module upgrades are available as well (as requested). The ProcessWireUpgrade module reports this Pro module information in a clear manner too. Some improvements have also been made to the core version updating features as well. The other module updated was FieldtypeEvents, a module that demonstrates how to create simple a Fieldtype+Inputfield module pair that has repeatable rows of multiple columns. The last version was made for PW 2.x, so I largely rewrote the module while updating it for PW 3.x. It's been simplified quite a bit so that it can be even more clear how to adapt it to create your own custom module. Being PW 3.x exclusive also opened more doors in keeping it simple but powerful. If you don't mind doing a little customization in adapting the code for your purposes, this module can be every bit as powerful in solving custom needs as Repeaters, but without Repeater overhead. I updated this module because another ProcessWire user was asking about how to store multiple columns of repeatable data for 20-million pages. Repeaters would be too much overhead at that scale, though FieldtypeTable could fit the bill. But at such a large scale, I thought a custom Fieldtype would be even better. So FieldtypeEvents shows you how to do it, and it's [hopefully] simpler than you might think. This has nothing to do with PW, but to follow up from last week, that second dose of the covid vaccine was an interesting experience. I got the shot (jab?) and strangely didn't feel a thing. I walked home and took the band-aid off my arm and noticed there was no sign of anything, no little pin prick or red spot, and a completely clean band-aid. I started to wonder if I'd been fooled or something. If someone sticks a needle in your arm, you should feel it right? And there should be some evidence of it? Well there wasn't (and no I didn't watch the needle, who would do that?). They also told me I'd feel ill for a day or two, and I felt completely fine even the next morning. But then 10 am rolled around and my arm started feeling sore and I was suddenly very tired. So tired that it was laborious to walk, sit at the computer, or do anything other than chill on the couch. That might sound undesirable, but it wasn't uncomfortable, and it was kind of funny being so ridiculously tired, but also really relieved. It meant it was working and my body was getting a download on how to battle covid, and putting all its resources into taking it seriously. It was fascinating, so I just crashed on the couch, relaxed and let it do its thing. By the next day, full energy was back, batteries recharged, upgrades installed. From what I understand, some people have no side effects, but I was one of those that did. Though if anything I enjoyed the different experience for a day, and the comfort of clear evidence it was working.
  8. @Hector Nguyen getcsv() does return an array, but it is an array representing and consuming the memory of just one line from a CSV file (i.e. the columns from 1 row). fgetcsv() is just a layer on top of the fgets() function, which reads one line at a time from a file, which is what makes it memory friendly. On the other hand, PHP functions like file() or file_get_contents() do read the entire file in memory, so they are not memory friendly, even if they are fast. @fedeb I think the best route to take for your groupID+start+end+sequence would be a custom Fieldtype. This would give you all of the benefits of having a repeater, and without any of the overhead. Custom fieldtype may sound complicated, but it's not at all. I've developed a module that can very easily be adapted for this need. See FieldtypeEvents which was created as an example to build exactly this sort of thing from. If you are interested in that route and have any questions, I'm happy to walk you through it.
  9. @fedeb Glad that moving the $parent outside the loop helped there. The reason it helps is because after a $pages->save() is the automatic $pages->uncacheAll(), so the auto-assigned parent from the template is having to be re-loaded on every iteration. By keeping your own copy loaded and assigning it yourself, you are able to avoid that extra overhead in this case. Avoid getting repeaters involved. I wouldn't even experiment with it here. That will at minimum triple the number of pages (assuming every protein page could have a repeater). Repeaters would be just fine if you were working in the thousands-of-pages territory, but in the millions-of-pages territory, it's not going to be worth even attempting. Using a ProFields table field would be the best alternative if you needed it to be queryable data. If you didn't need it to be queryable data (groupID, start, end, sequence), I would leave them as they are, space-separated in a plain textarea field — they can easily be parsed out at runtime so you can access them as as properties of the page. (If that suits your need, let me know and I'll get into how that can be done). When working at large scale, it's also always good to consider custom building a Fieldtype module for the purpose too (that's another topic, but we can get into it too). For your groupID, if the same groupID is referenced by multiple proteins, and there is more information about each "group" (other than just an ID) then I think it would make sense for it to be a Page reference field. What is the max number of groupID+start+end+sequence rows that a protein can have? If there is a natural limit and it's not large, then that would open up some new storage possibilities too. Another optimization you can make in your loop: $page->sort = $i; This prevents it from having to detect and auto-assign a sort value based on the quantity of children the parent page has. For the $page->name, if each page will have a unique "protein-name" then you might also consider using that rather than the ("protein" . $i), as it will be more reflective of the page than a generic index number.
  10. @cb2004 Got it. I'll put out an update to the ProcessWireUpgrade module this week. Support for identifying the latest version of Pro modules is a function of the modules directory rather than the upgrades module. I've been meaning to do this, so thanks for the reminder. I have gone ahead and updated it so that it can now identify the latest versions of all Pro modules. Though I can't add support for download+install upgrades of Pro modules, as they are access controlled so there can't be public download URLs for these. I also think that in general it's always better to install or upgrade modules directly on the file system, as that prevents permissions problems (for when apache is not running as your user account), and makes it easier to troubleshoot and resolve issues when installing or upgrading modules.
  11. @Hector Nguyen This is cool to see generators in action. Though as far as I know, PHP's fgetcsv() never loads the whole file in memory at the same time, regardless of which method is used to call it. I think it just loads one line at a time (?), but this reminds me that an optimization to fgetcsv() is to tell it what the longest possible line might be (as 2nd argument), so that it doesn't have to figure it out. Fedeb's example has 0 as the 2nd argument to fgetcsv(), which means "let PHP figure it out", so some overhead could be reduced here by giving it a number like 1024 or whatever the largest line length (in bytes) might be. There may be other benefits to using generators here though? I haven't experimented with them much yet so am curious.
  12. Unless I'm forgetting something, the $pages->uncache($page); won't help here because $page is a newly created Page that wasn't loaded from the database. So it's not going to be cached either. Uncaching pages is potentially useful when iterating through large groups of existing pages. For instance, if you are rendering or exporting something large from the contents of existing pages, you might like to $pages->uncacheAll() after getting through a thousand of them to clear room for another paginated batch. Though nowadays we have $pages->findMany() and $pages->findRaw(), so there are fewer instances were you would even need to use uncache or uncacheAll, if ever. ProcessWire actually does an uncacheAll() internally after saving a page already. This is necessary because changes to a page or additions/deletions to the page tree may affect other pages, and we don't want any potential for old cached data to appear in future $pages->find() or other operations. Just one example is if we called $parent->children() before a save, and then after the save called it again, we'd want our new page to be in the children rather than having it return the previously cached value. There are a lot of similar cases, so the safest bet is for PW to uncache the results of future page get/find operations after a save as the default behavior. So that's the way it's always done it. As far as I can tell from fedeb's example (and often other with import operations), it may be better to tell PW to skip this "uncacheAll-after-save" behavior. That's because imports often involve Page reference fields, and you don't want PW to have to reload referenced pages after every save. So you could potentially reduce overhead by telling it not to uncache after save, i.e. $pages->save($page, [ 'uncacheAll' => false ]); I'm not sure if fedeb's import involves loading of any other pages, whether for page reference fields, or anything else. So it may not matter one way or the other here, but wanted to mention it just in case. I know about ProcessWire tuning, but not about MySQL server tuning. When dealing with 20 million rows that seems like getting into the territory where optimizations to the DB configuration deserve a lot of focus, so I would bet that BitPoet's suggestions are going to make the most difference.
  13. @fedeb That's the largest quantity of pages I've heard of anyone creating in ProcessWire, by a pretty large margin. So you are in somewhat uncharted territory. But that's really cool you are doing that. I would be curious how different the graph would be if you split it up into batches so that you aren't creating more than a certain quantity per execution/runtime. For instance, maybe you create 10k in one execution and another 10k in the next, etc., or something like that. Would the same slowdown still occur? If so, I would start to think it might be the database index and increased overhead in maintaining that index as the quantity increases. On the flip side, if restarting the process to create each set in batches solves the slowdown, then I would think it might be memory or resource related. A couple things you can do to potentially (?) improve your page creation time: 1. At the top of your code (before the loop) put: $template = $templates->get('protein'); Then within the loop set: $page->template = $template; 2. I don't see a parent page assignment. How are you doing that? Double check that you aren't asking PW to load the parent page every time in the loop and instead handle it like with the template in #1 above. 3. What kind of fields are on your "protein" template? Depending on their type, there may be potential optimizations. Especially if any are Page references. Can you paste in a line or two from the CSV? 4. If you can assign a $page->name = "protein" . $i; rather than having PW auto-generate a name from the title, that will save some resources too.
  14. @cb2004 I'm not sure I understand what you mean by "removing older official repositories". Can you expand on this? Which social embeds? I often use the MarkupSocialShareButtons module for this stuff. But if there are oembed providers for social links then a similar strategy would work. I know that Twitter has an oembed service, and Facebook apparently used to, but then killed it. I was originally thinking about expanding this module (or adding another) to support any oembed provider, except there is a TextformatterOEmbed module that apparently does this so thought I might try that one out first. Within the last few weeks they opened it up to everyone here. Previously it was just people 65+ or with health conditions, etc. I think the vaccinations are going well for the people that want them (which seems to be the majority), but apparently there is still a portion of the population that doesn't want to get the vaccine, so that could keep the virus spreading and mutating as long as that remains the case.
  15. @markus_blue_tomato Great, glad to hear it's working well! @StanLindsey This would be very simple to add, I'll plan to add it this week. Question: would just an array of DB hosts be adequate, or would it need separate configuration (host plus db name, user, pass, port, etc.) for each of the readonly db hosts?
  16. @markus_blue_tomato Sorry to hear that, I hope they have it available soon. I figured we'd be the last to get it here because the for-profit healthcare system in the US doesn't often lend itself well to public health, unless you are wealthy. (Just getting a covid test was $400). Luckily it seems the vaccine isn't being handled by the healthcare companies, and it's free. My parents got their vaccine at an appliance store drive-through, my wife got hers at the grocery store, and I got mine at the office of some technology company in our town square. That might sound sketchy but they are all legitimate and it seems to be working well for once.
  17. It's spring break here and my kids are going back to school next week after being out for more than a year. Since it's a break week, the weather is great, and it's also the last week of the year-long covid break from school, I've spent a little less time at the computer this week. I've focused on some smaller module projects rather than the core. More specifically: posted a major update and refactor of the TextformatterHannaCode module, and a completely rewritten TextformatterVideoEmbed module. While making these updates, I've also made note of and attempted to resolve any reported issues in the GitHub repositories. Next week, it's back to the core, with both issue resolutions and pull requests scheduled for upcoming versions. Next week I also get my 2nd shot of covid vaccine, and I'm told it may slow me down a bit for a day, but will be well worth it. I had a day of tiredness from the 1st shot, but it was greatly outweighed by feelings of gratitude and reduction of worry. I highly recommend it as soon as you can get it, if you haven't already.
  18. This week ProcessWire gained the ability to maintain separate read-only and read-write database connections to optimize scalability, cost and performance. The post covers why this can be so valuable and how to configure it in ProcessWire— https://processwire.com/blog/posts/pw-3.0.175/
  19. @monollonom I knew there was a reported PDO issue pending, but didn't remember the details so was going to be looking for it this coming week to make sure it was included (along with any others), thanks for pointing me to it.
  20. @MrSnoozles @teppo This is not a limiting factor in scalability at least. First off, at least here, the file-based assets are delivered by Cloudfront CDN, so they aren't part of the website traffic in the first place (other than to feed the CDN). If you wanted scalability then you'd likely want a CDN serving your assets whether using S3 or not. But a CDN isn't a necessary part of the equation in our setup either. File systems can be replicated just like databases. That's how this site runs on a load balancer on any number of nodes. Requests that upload files are routed to node A (primary), but all other requests can hit any node that the load balancer decides to route it to. The other nodes are exact copies of the node A file system that update in real time. This is very similar to what's happening with the DB reader (read-only) and writer (read-write) connection I posted about above, where the writer would be node A and there can be any number of readers. Something like S3 doesn't enhance the scalability of any of this. Implementing S3 as a storage option for PW is still part of the plan here, but more for the convenience and usefulness than scalability. You can already use S3 as a storage option in PW if you use one of the methods of mapping directories in your file system to it. But I'm looking to support for it in PW more natively than that. It is admittedly more complex than the DB stuff mentioned above. For instance, we use PHP's PDO class that all DB requests go through, so intercepting and routing them is relatively simple. Whereas in PHP, there is no PDO-type class that the file system API is built around, and instead it is dozens of different procedural functions (which is just fine, until you need to change their behavior). In addition, calls to S3 are more expensive than a file system access, so doing something as simple as getting an image dimensions is no longer a matter of a simple php getimagesize() call. Instead, it's more like making an FTP connection somewhere, FTP'ing the file to your computer, getting the image dimensions, storing them somewhere else, then deleting the image. So meta data like image dimensions needs to be stored somewhere else. PW actually implemented this ability last year (meta data and stored image dimensions). So we've already been making small steps towards S3-type storage, but because the big picture is still pretty broad in scope to implement, it's more of a long term plan. Though maybe one of my clients will tell me they need it next week, in which case it'll become a short term plan. ?
  21. This week I've been working on something a little different for the core. Specifically, ProcessWire's database class (WireDatabasePDO) has been rewritten to support separate read-only and read-write database connections. Jan, who administers the processwire.com server, asked if I could implement it. I looked into it and thought it had significant benefits for ProcessWire users, so it worked out that now was a good time to implement it. The rewritten database class is actually complete and now running on a live test installation, but I have not yet committed it to the core dev branch because I want to fully document it first. This will happen next week in a blog post. By then I'll have processwire.com using it too. But I can already say that it's a cool thing watching the graphs in AWS show the difference it makes when we start hitting the site with crawlers. You might be wondering what the benefits are in having separate read-only and read-write database connections. I'll get into some of the details next week. But essentially, read-only database connections can scale in a way (and at much lower cost) than read-write connections can. And when using a service like Amazon Aurora, they can scale on-the-fly automatically according to traffic and demand for resources. Not only does it open up the ability for a ProcessWire-powered site to scale much further than before, but it has potential to reduce the costs of doing so by perhaps 50% or more. If you are interested in reading more, we are currently testing the features using Amazon Aurora and RDS Read Replicas (see also Replication with Aurora). However, the ProcessWire core support for this feature is not bound to anything AWS specific and will work with any platform supporting a similar ability. Thanks for reading, I'll have more on this next week, and also have it ready to use should you want to try it out yourself.
  22. I hope everyone is having a good week! Commits to the core this week include 10 issue report resolutions (so far). This will likely continue next week as well, and then I'll bump the version up then. Also included this week is an CKEditor upgrade from 4.14.0 to version 4.16.0. While that may sound like a minor CKEditor version bump, there's actually quite a list of updates in the CKEditor 4.x changelog, including a few security-related fixes, though none that I think are likely to affect PW users. I do still have a couple of core feature requests in progress as well, but there's more work still to do on those. Nothing too exciting this week, but I like to check in and say hello either way. I hope you all have a great weekend!
  23. @tcnet If possible, add a ModuleName.info.php file, or a ModuleName.info.json file to your repo, where "ModuleName" has the same name as your repo. Here's an example of an info.json file: { "title": "Your Module or Site Profile Name", "summary": "One sentence summary of the module or site profile.", "version": 1, "author": "Name of author" } We haven't had any site profiles added since the directory was recently updated, so if you find that doesn't work, please send me a PM with your repo URL and I'll figure it out here.
  24. @teppo When a module doesn't connect to your profile, it means that the module was submitted with a different email address than the one on your account. When that happens, I just fix them manually so that they connect to your account. I have fixed ProcessChangelog and all 3 or 4 others I could find so that they connect to your account now. Thanks for letting me know. PM or email me if there are any others, as I don't always know when someone tags me so it's easy for me to miss. @adrian I don't know about PageEditSoftLock specifically, but there is an automatic purge of older modules that match these conditions: they don't indicate support for PW 3.x, haven't been updated in 2+ years, and the author is not active. They are still technically in the DB, so if there is someone else that wants to maintain an inactive module, or if there's a known reliable module despite not being active, or if it just appears to be a mistake, let me know and I can re-publish.
  25. I was glad to see there was interest in the new URL hooks added last week, thanks! There were still a few details to work out, so thought I'd take care of those this week before moving on to other updates, and they are now in 3.0.174. Today I've also updated last week's blog post with the additional info, so that it's all in one place. This will likely be converted over to a dedicated documentation page, but for now, here is what's been added: The post last week introduced you to using named arguments. This week another kind was added, called simple named arguments (click the link for details). The idea is based off an example from another post in these forums by BitPoet. The handling of trailing slashes vs non-trailing slashes was undefined last week. This week it has been defined and is now enforced by ProcessWire. All of the details are here. Pagination was another grey area last week, but no longer. Here are all of the details on how you can utilize pagination in URL/path hooks. In addition, in 3.0.174 URL/path hooks can now have control even after a Page (template file) throws its own 404, whether by wire404() or throw new Wire404Exception(). I found this was necessary because it is possible to enable URL segments for your homepage template. And, depending on your homepage template settings, that means it is possible for the homepage to be the recipient of all URLs that don't match pages. This would leave no opportunity for URL/path hooks to execute. So now ProcessWire gives URL/path hooks another opportunity to run if it matches the URL, even after a 404 is thrown from a Page template file. Beyond the above, there's been a lot of additional optimization and improvement to the hooks system that handles the path/URL hooks, but nothing further that affects its API... just internal improvements. ProcessWire 3.0.174 also adds a feature requested by Adrian, which was to add object return value support for the recently added $pages->findRaw() method. The method by default returns arrays for everything, which can be helpful in making clear you are working with raw data, in cases where it matters. (As opposed to formatted or prepared page data). But if you specify objects=1 in your selector to the method, it will instead return StdClass objects where it previously returned arrays. This makes working with the data more consistent with how you might work with Page object data, even if it is still raw data. Should you be using any findRaw() data for output purposes, you can now also specify entities=1 in your selector to have it automatically entity-encode all string values, or entities=field, replacing "field" with pipe-separated field names you want entity encoded. The following example summarizes all of the recent additions to findRaw, as pretty much everything here was not possible on the first implementation: $items = $pages->findRaw("parent=/blog/posts, fields=title|url, entities=title, objects=1"); foreach($items as $item) { echo "<li><a href='$item->url'>$item->title</a></li>"; } Thanks for reading and have a great weekend!
×
×
  • Create New...