Leaderboard
Popular Content
Showing content with the highest reputation on 09/11/2021 in all areas
-
This week there are a few minor updates on the dev branch, though not enough yet to bump the version. The most notable are a few improvements to the database selectors you can use with $pages->find() and similar API calls. While working through issue reports a few weeks ago, there were a couple issue reports that indicated one selector or another not working. What I found was that it was working as designed/built, but they were just selector features that had never been supported. But they also seemed like good/useful shorthand syntax to support, so I was enthusiastic to add support for them. I just wanted to wait till we were back on the dev branch, as we are now. Here's what's been added: Support for OR values on "status=" selectors. Now you can match one status or another with PageFinder selectors by specifying a selector like "status=hidden|unpublished", and this will find all pages that either have hidden or unpublished status. The hidden and unpublished are just likely the most common examples, but you can use any other status name, or as many statuses as necessary in your OR condition. Previously it was possible to match pages having one status or another by other means, but it was far from straightforward. Now it's nice and simple. Support for OR values on "sort=" selectors. This one isn't technically an OR condition since we are giving a command to the selector engine about how it should sort, rather than trying to match something. You can tell it how to sort with the syntax "sort=date|title" as an example. That would be shorthand for "sort=date, sort=title", which is saying "first sort by date, then by title". Support for combined start and limit selectors. Previously you have had to specify "start=x, limit=y" separately, if you needed it. Now you can optionally specify both as part of the "limit", for example "limit=5|10" which is shorthand for "start=5, limit=10", and actually kind of similar to what it translates to in MySQL, which is "LIMIT 5,10". I suspect that not many people ever use "start=" in their selectors unless using "start=0" to prevent a set from paginating. So if you wanted a set of 10 pages that don't follow the current pagination, you could specify "limit=0|10" in your selector, or the more verbose "start=0, limit=10" will work in any PW version. Support for matching children paths. This is a small one, but previously you couldn't do "children=/path/to/page" to match a page having the given child path. Though you could do "children=123" where 123 is the ID of the child page. It has been updated so that it can now support paths in addition to IDs, just as "parent" does. I'm not sure why we didn't have support for this one before, it likely just hadn't come up yet. You can use OR values here too if you'd like. As before, you can also use subfields on "children" as well. Worth mentioning is that these are additions for our PageFinder engine which queries the database. We also have the lesser used in-memory selectors which don't yet support all of these, but I've put it on my to-do list. In-memory page finding selectors come into play if you are post-filtering pages that you have already loaded from the database into a PageArray. We like these to maintain some consistency with the database selectors when possible, so I'll likely have that working here soon. From this end, I'm also putting ~2 hours of work into the new Pages Snapshots module every day, with a lot of progress but also still a lot of ground to cover. Separately, I'm working on pulling more than 4 million articles out of an older proprietary legacy CMS for a newspaper organization and converting them to a standard XML format for import elsewhere. A lot of data conversion has to take place in terms of cleaning up markup for each article. ProcessWire is the tool that all of this is being done in, and I'm using a lot of $sanitizer methods as well as keeping HTML Purifier busy! Thanks for reading and have a great weekend!6 points
-
Ok - this write up got quite long so I reckon it counts as a case study. Crest Research is a hub for academic articles and information about security research collated by the University of Lancaster and other universities in the UK. Their old site had been running for several years on Word Press. There was a lot of content that wasn't brilliantly organised and there was lots of plugins that had been added to WP (honestly one of the things I like least about WP is that it's too easy for users to add plugins without really understanding the implications). We persuaded the University that it would be much better to make the move to Processwire. No small part of that was being able to demonstrate that PW was a much better option from a security point of view. We also wanted to be able to develop an API that provides content to a native app we built for Crest a while back; that probably would have been doable in WP but much easier in PW. This was our first reasonably large move from WP to PW so we learnt a lot on the way. So - first step was to import all of the posts from WP. For this we headed to Adrian's ProcessMigrator module which worked well at getting the data over. Once we had the data over we used Wanze's ProcessBatcher module to do bulk updates and moves to try and organise things (including deleting a load of WP tags we didn't want to keep). We found that we needed import certain things manually as well, in particular some thumbnail images. For these we just created an import script that read through a CSV of data that we'd dumped from the WP database. Honestly PW is just great at this - we had a column of page aliases and a column of image URLs and with about 10 lines of code we manged to download the images and add them to our imported pages. We've used this method of a CSV and an import script on a couple of other projects where we've needed to load content from other platforms and it's been very straightforward and effective. Once we had the content over there were a couple of other bits of functionality from the WP site that needed to replicate. One of these was a download manager. The old site kept statistics of the number of file downloads which we needed to replicate (and retain the old data) so we built a modue to handle that. This was pretty much our first foray into PW module development and Bernhard's blog on building admin modules was very useful. We tried to remove as many WP short codes as possible but those we need to keep we replicated in the Hanna Code module. The search on the new site was very important to the client - a lot of their targe audience is researchers and academics. We ended up with a system of filters (author, tag etc) together with the text matching operators that appeared in 3.0.160. The client also asked if we could add some kind of fuzzy searching for misspelled words and US / UK spelling differences which we did by adding to the lemmas in Ryan's WireWordTools module. Our additions our available on GitHub. I think there's still plenty of refining to do on the search but it works well. Another thing the client asked for was an indication of 'Reading Time' for an article as Medium have on their articles. We added a hook to calculate the reading time for an article when the page is saved. Can't seem to find the blogpost on Medium where they explained their formula but I've stuck the code we ended up with up on GitHub as a gist here. Other modules we used include: AIOM+ - this was before we got a license for ProCache. We used AIOM and then some hooks to generate cached versions of some chunks of html using MarkupCache. Probably wouldn't bother now and just use ProCache. Redirects - we tried to keep the site structure the same as the old site for SEO, but there was quite a lot of organising. We grabbed the top few hundred pages from Google Analytics and then ran those through a PHP script to check their status on the dev site (gist of that script on GitHub as well ). We dumped those results into a spreadsheet and decided where they needed to be directed to. Then we imported that list back in the Redirects module. Other honourable mentions go to Connect Page Fields, Page Field Edit Links, Dashboard, Schedule Pages and of course Tracy Debugger (which was particularly useful on this project). So... I'm sure you're asking (assuming anyone has made it this far) what the end site was like and whether the client was happy? Well comparing the old and new sites in Lighthouse gave us this: And Mozilla Observatory gave these rather nice results (especially since it's a security focused site) This resulted in a big upswing in traffic. We're seeing about a 500% increase in vistors compared to this time last year (and from pretty good numbers in the first place). IMO the biggest factor in this increase was the improved page speeds. Now - of course we probably could have got similar results in WordPress if we'd spent enough time and energy on the site but by using PW we've ended up with a much cleaner site which the client is happy to use. Logging into the old site with it's upselling of plugins and so on is just painful. We've also educated the client as to why adding random plugins is not a good thing; the old site loaded 18 javascript files from various sites most of which we didn't know anything about - we have 3 now (and one of those is analytics which we tried to persuade them to lose.). Anyway - they're happy and we've got plans to keep developing the site over the next couple of years so hopefully it's just going to keep getting better. s.3 points
-
I know I'm super late to this party, but since I've been away for quite some time - but absolutely love ProcessWire - and Ryan mentioned that this roadmap could extend beyond 2021, I thought this was the most appropriate place to comment. Thanks to @teppo's PW Weekly I've been able to, mostly, recount (in summarized form) multiple years of development (with plenty of tangential links, often reading the full blog posts by Ryan) both of PW and in 3rd party development efforts, so I don't feel too terribly left behind. Something a little different not yet discussed: Zooming out and looking at the bigger picture, within regards to the CMS/CMF landscape, I think an area that PW lacks is in marketing of itself, and I don't mean this as a knock on ProcessWire - the product speaks for itself and word of mouth is awesome, and marketing efforts can oftentimes detract from active development time. Marketing isn't exactly a "core feature" of the codebase, but it is something that I think can be code-adjacent. ProcessWire is capable of so, so much, but from just looking at it, or installing it from source, it's hard to see that from the eyes of a first-time user. ProcessWire doesn't use templates like WordPress, but templates are a big business with WordPress. Although some WordPress templates come bundled with custom plugins which starts skirting the line of what ProcessWire does (site profiles), there's a plethora of ready-to-go, custom designed websites with a only the simple task, after installing, of adding content. ProcessWire is more developer focused (which I personally love), but that doesn't mean we can't, or shouldn't, also cater to an audience that may want to see what designs or functionality can be made (almost) immediately available after install. As a simplistic first step here: currently Site Profiles are listed under Modules as its own category, but that's not too intuitive for findability - if this were to have its own landing page and higher level navigation, with feel good images based on the profile (for those that provide them), I think it might help to attract more potential users. On the topic of Site Profiles, since ProcessWire is capable of so much (that many of us aren't even entirely aware of), having some custom built, premium Site Profiles built as premium starter kits (kind of like what my buddy Jack McDade is doing with Statamic) it might be another boon, and additional income source. He's also considering selling branded merchandise, which I think we'd tried before and it didn't take off, but it's easy to do (via something like CafePress) and every little bit helps I suppose? On these notes, should there be - or has there been thought to - an official marketplace via the ProcessWire website for things like these (with a percentage going back to PW)? Pro Module Thoughts: 1. Search: I remember a mention of the front-end search functionality of the current version of the PW website potentially being packaged up into a Pro Module. What's the status on that? I think that - if it could be packaged into a pro module - it would be a fairly popular one. I realize that language issues would be a hurdle and there were strides made towards that endeavor such as with WireWordTools but don't know if the feasibility was broken down once multi-language was considered or if it's still able to be worked on and released. 2. Recurring Dates / RRule I too would have a use for this. Realistically, most businesses could if they want to attempt to accurately list their open hours when they celebrate holidays, as holidays have recurrence, and can have annoying recurrence (like the American Thanksgiving) which is the 4th Thursday of November. API-based things might have a need/want to integrate LazyCron into a non-standard recurrence. My personal usage would be for events - honestly I'm surprised the school websites Ryan's worked on haven't had a need for this. Reporting to Google for JSON-LD on its recurrence may also be helpful to have an API-level access to it as well (I'm not familiar enough to know for sure though). The largest difficulties in handling recurring events is exception management. There are usually two ways to generate recurrence - tie them to a single entry and assign a recurrence rule and extrapolate from that dynamically on call, or use the recurrence rule to generate the actual entries, individually (and usually have them tied to an original). How would exceptions be handled if a single date, or time, needed an adjustment? If one or more were cancelled? If one or more were to be added? If editing the primary edits them all, does it overwrite all others even if individual changes were made? Whether convention or configuration, these are just some potential issues with recurrence. ? Image Reference Field and/or Central Image Manager: It's certainly not necessary to a website being used, created, or maintained - but it would certainly be helpful if it was part of the core, whether optionally (in page settings) or statically (as a field/input setting). Teppo did a great job illustrating why: I'm essentially a technician (title is Web Administrator, but 85% of my job's time is help desk / support), professionally I'm a programmer/web developer, but the business I've worked for has 100+ people who are extremely varied in their technical expertise. 40 or so of them will be expected to have access to the administrative back-end for the primary website I'm (finally) redoing in one way or another, as they will be the content authors/maintainers (I work for a public library, so these are city-level librarians). They would not take the time to find a reference to an image already in the system when they could more easily just upload another completely brand new copy of the same image (let's say it's a 200MB file) multiple times, and resize it to a 240px width. I know that I could create a page that contained a "shared" image repository, or use one of the various modules, but the fact is that it can be very useful for various reasons. Layout Tool / Editor: From my own personal experience, I would agree with bernhard here. I think, based on the 5th time I've read through this topic, that it's been decided that Editor.js, specifically, is not a good fit, but continuing on... I'd done some testing of my own, like bernhard, and found limitations and issues with it. I'd also tried showing it to some basic-skilled coworkers with minimal (but enough) instruction and they struggled, hard. Showing them a CKeditor field (without instruction), however, they were able to do what they wanted and although were confused with certain things, weren't struggling. That said, from what I've seen of Bard and Editor.js, a similar approach can be managed using styling and JS adjustments with the RepeaterMatrix fieldtype, even if it's apparently overkill where storage needs come in. I do like that individual fields are still independently searchable within RepeaterMatrix though, which I think wouldn't be the case with an Editor.js fieldtype solution. How is RepeaterMatrix similar to Editor.js with style and JS changes? Robin S. and monollonom essentially had similar ideas - that the layout is different for Editorjs/Bard type fields, they're more compact and seemingly integrated. From the observation of the front-end GUI interface of Editor.js and Bard, it's doing something fairly similar to what RepeaterMatrix currently does - you create a new item (or start of a block of items) from a predetermined set of options. It's just that the interface of the other two has a different "wow" factor. Click a hoverable + button, choose from the available options, and then go about adding the related content. So if a fieldtype was created that's similar to RepeaterMatrix but stored data in a more efficient way, and was intended to be a more concise and (for lack of a better word) all-enclosed field, I would think using similar markup to RepeaterMatrix with a much more visually minified styling could help here. I'd love to understand more about how the $page-meta() can be used to integrate non-field stored data like bernhard was asking about, because that could be a way for developers to setup layout-like interfaces within custom-made template builders. Actual Page Builder - an Alternative: Fieldtype There are a few open source visual page builders for email templates (ex: GrapeJS). These are well-tested and I'm thinking that for the purposes of single page instances or landing pages, something like that could be used and created into a fieldtype of its own. Remove all of the markup from it afterSave to get only the text content, and place that content in a separate data field in the DB to make it searchable and it's now capable of being a standard page/template in PW. It would be up to the developer to place appropriate limits on it, but beyond that... Just a thought. I ♥ ProcessWire. (I also love all of the work that's been done since this topic was created, too!)2 points
-
The module has been lying around on GitHub for some time now, so I thought I'd give it its own forum topic so I can give it a module list entry. SymmetricEncryptedText Symmetric encryption for text based fields (supports multi language fields). Module page. Link to the GitHub repo. Description This module adds an encryption option to all text fields (and those derived from FieldtypeText). Field contents are encrypted using a symmetric key when a page is saved and decrypted when loaded from the database. The module by default uses sodium (if loaded) in PHP versions >= 7.2, otherwise it falls back to the bundled phpseclib. Multi-Language fields are supported too. WARNING! Setting a field to encrypted and saving values in those fields is a one-way road! Once encrypted, the contents cannot be unencrypted without writing a program to do so. Disabling the encryption option on a field after the fact gets you encrypted "garbage". Usage Download the zipped module through the green button at the top right of the GitHub repo or (once available there) from the official PW module repository Extract in its own directory under site/modules. In the backend, click "Modules" -> "Refresh", then install "Symmetric Encryption for Text Fields". Go to module settings. An appropriately sized, random key will be generated if this is your first use. Copy the supplied entry into site/config.php Add fields or configure already present fields. On the "Details" tab you can enable encryption for the field in question Edit a page with such a field, enter a value there, save and enjoy Existing, unencrypted values are left untouched until a new value is saved. That way, you can do a smooth upgrade to encryption, but you have to save all pre-populated pages to have their values encrypted in the database. Thus it is recommended to avoid adding encryption to already populated fields. Advanced Usage You can hook after SymmetricEncryptedText::loadKey to retrieve your key from somewhere else, e.g. a different server.1 point
-
The change goes live on November 1st. You can read about the impacts here: FAQ: The Coming Domains API Change To Remove The SMTP Password On November 1, 2021 – Mailgun Help Center and specially this part Will this change impact the application I have integrated with Mailgun? The short answer: maybe, but most likely not.1 point
-
To be honest, I don't know if this is a standard processwire file. But with language files one can use it as follows: Instead of adding each string to an own variable, you can add a second parameter to all the language strings you use around in different template files or module files or where ever you need them: __('Text 1', '/path/to/your/_strings.php'); __('Text 2', '/path/to/your/_strings.php'); ... And instead of adding the '/path/to/your/_strings.php' as text all the time, I use a functions call for that. This way you do not have to include the file and can use it everywhere handled through the PW translations system, because you tell it that the current string is the same as a string in the centralized _strings.php In /site/init.php I define this function, that simply returns the path to my centralized translation file: /** * TRANSLATABLE STRINGS * Include translatable strings */ if(!function_exists('ProcessWire\mystrings')) { function mystrings() { return '/site/_strings.php'; // absolute URL or absolute filepath to the central translation file } } My _strings.php would look like this: <?php namespace ProcessWire; /** * TRANSLATABLE STRINGS * Define globally available translatable strings * * USAGE * * __('Lesen Sie mehr ...', mystrings()); * * The function mystrings() returns the textdomain of this file. * **/ ... __('Datenschutzerklärung'); __('Die Maße des Werks sind:'); __('Dieses Bild drucken!'); __('drucken'); ... __('Text 1'); __('Text 2'); ... __('Zurück zur Übersicht'); To sum up, this way I don't need to include a _strings.php and it also works every where.1 point