Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation since 01/19/2021 in all areas

  1. This week we have a new master/main version released after a full year in the making. With nearly 40 pull requests, hundreds of new additions and more than 100 issue reports resolved, this new version has a ton of great new stuff and we’ll cover most of the new stuff here— https://processwire.com/blog/posts/pw-3.0.184-master/
    48 points
  2. Happy New Year! Hope that you all have a great end to 2021 and start of 2022. No major core updates to report this week, just a few minor issue fixing commits, so no version bump today. The dev branch is getting close to 100 commits (and at 7 versions) above the master branch, and with even more improvements/fixes/optimizations than that. So we may try to get a new master/main version out in early 2022, as I'd really like to get more master versions out in 2022 than we did in 2021. Some portion of our audience does not use the dev branch where most of the activity happens, and so it might be nice to share more of that activity on the master/main branch. That's one of many things I'm thinking about as the New Year approaches and am certain 2022 is going to be a great year for ProcessWire and the community. Hope that you have a great weekend and Happy New Year!
    38 points
  3. Here is the first very early concept of a Page Builder. As per the conversation in the 'ProcessWire beyond 2021' conversation, I set myself a challenge to make a clone of YOOtheme Pro's Page Builder. This was mainly spurred by @Jonathan Lahijani's excellent overview of ideas of a page builder for ProcessWire. This is still in very early stages and I am not really sure where it is headed. I would like to hear the thoughts of like-minded persons 😁. I would especially love to hear from @Jonathan Lahijani, @szabesz, @AndZyk and @flydev 👊🏻 please. Concept The page builder in its current state is a Fieldtype + Inputfield supported by other behind-the-scenes Fieldtypes without Inputfields. There are no hidden or extra pages in contrast to Repeater Matrix. All values are stored in the Page Builder fields for the page being edited. The fields do not store values as JSON. Definitions for elements, rows, grids, etc as stored as JSON. Currently, for storage purposes, 4 datatypes are supported - Text (HTML), images, plain text and headlines. From a storage perspective, the latter two are one and the same. Just texts with different 'schemas/definitions'. More on this below. The fields are multitype fields. This means one page can hold multiple texts, allowing for repeatability. Similar datatypes are stored together in one field/table. For instance, there is no reason why a (future) URL element (datatype) should not be stored in the same table as plain text. At the database level, they are both just texts with similar requirements. At the processing level, URLs vs other plain texts (headlines, etc) are handled differently (validation, sanitisation, etc). Each 'element' represents a row in a table for most types (e.g. slideshows are slightly different). Querying and access of field values is via the main Fieldtype - FieldtypePageBuilder. However, the supporting Fieldtypes can be also be accessed and queried individually, if one wishes, using normal ProcessWire selectors. The supporting Fieldtypes, if such need arises could easily become custom tables instead (but best to keep them as Fieldtypes - easier querying with selectors, etc). It is totally CSS-agnostic in relation to frontend output. You bring your own CSS. In the preview, you can also use your own CSS. In the frontend, you can choose to output raw values as you wish or use inbuilt render methods to render the whole layout for you or to render the value of an element as per its tag definition (e.g. headlines as h2, h4, etc) where applicable. Fully multilingual (although the editing UI not yet implemented). Issues The main issue is the real estate needed for InputfieldPageBuilder. Any such page builder would require the whole width of the window. As you can see from the screenshot below, this obviously throws things out of kilter with respect to the ProcessWire page edit UI, in any theme (I believe). I am not a designer so would love to hear from you about possible solutions. My current thoughts are: Modal Open the page builder in a modal for editing. Pros Would allow for use of whole real estate. Title and other fields would not be in the way. Cons Editing in modals can be tricky? Other..? Process Module Pros Solves the real estate issue. Cons Disconnect between the page being edited/created and the page tree. Screenshot No attempt has been made to theme it as per any current ProcessWire theme (that I know of). This was a quick and dirty-ish clone of YTPB. As stated, however, the current ui is not acceptable as an Inputfield for, mainly, real estate reasons. Video Demo This is a demo for the Page Builder app outside ProcessWire. Thoughts? Thanks. PS: I currently have no time to continue working on this (Padloper, etc..)
    33 points
  4. This week we've had a mixture of core updates and more work on the PageAutosave/LivePreview module. In the core we have mostly maintenance updates and issue resolutions. I'm not going to bump the version number this week as I'd like to get a bit more added to this version first. One feature request that appears in the core this week is the ability to specify colors for RepeaterMatrix item types (idea from @Ivan Gretsky). If you have any version of RepeaterMatrix and you use the current core dev branch, you can specify the background color for any repeater item type by placing a color hex code in the repeater type label (like at the end of it, but wherever). For instance, typing in #777777 (or just #777) would make the repeater items of that type have a grey background rather than the default color background. Though whatever color you choose, note that the text color is white, so don't choose too light of a color. (The hex color code is of course removed from the item labels.) The PageAutosave and LivePreview module also got several updates this week, bringing it that much closer to being production ready: Added support for automatic detection of best placement for live preview window position based on available space. It will choose the correct location and size either to the right, left, above or below your page editor window. Added support for remembering live preview window position in a cookie. So if you setup your preferred layout for editor window and live preview window, ProcessWire will continue to use it. Added a new option to support automatic replacement of individual page field values without having to add your own `pw-value-*` classes. Meaning, you can now gain the benefit of field-value updates in your live preview without PW having to re-render the page. This applies primarily to text-based fields (title, body, etc.) that are part of the page being viewed. LivePreview editor and preview windows now talk to each other with JS rather than use SSE/streaming. I found that it just works more reliably that way, puts less load on the server, and [to my surprise] also seems to be faster. The SSE option is still there in the module config, but it's no longer the default. The only time where I think SSE might be preferable is if you want to monitor changes made to the page from outside of the page editor (like from the API) in a live preview fashion, as the SSE option will pick those up too. In addition to the above, numerous minor bug fixes, improvements and optimizations were added. If you want to grab this new version (which is still a development/testing version), it's posted in the ProDrafts, ProDevTools and ProFields boards. There's more to cover with this module still. I've been so focused on it that I haven't yet started working with htmx. Though I did spend quite a bit of time in the docs and it looks amazing. From what I understand as it relates to this module, htmx could bring a lot of greatness to the front-end preview window, so I'm anxious to get into that, and even more excited to explore the possibilities it opens elsewhere in ProcessWire. Also, how awesome is it that the author of htmx stopped by to say hello and answer questions here in the forums, that made my day — big thanks to @totally not an htmx shill for joining the discussion, I hope I'll have some good questions before long too. Thanks for reading and have a great weekend!
    32 points
  5. ProcessWire 3.0.173 adds several new requested features and this post focuses on one of my favorites: the ability to hook into and handle ProcessWire URLs, independent of pages— https://processwire.com/blog/posts/pw-3.0.173/
    31 points
  6. This week the dev branch contains about a dozen issue fixes relative to this time last week. (commit log) While these are all relatively minor things, some have been around awhile and it's always nice to get them figured out. Plus it's often a good opportunity to iterate and improve upon related things in the process. While I think we're very close to being ready to merge to the master branch, I'm going to give it a few more days just in case. I want to make sure no new issues arise (no matter how small) as a result of all the commits we've been doing over the last few weeks with GitHub issue resolutions. Most likely there won't be many more commits on the dev branch before the merge, and perhaps by this time next week, we'll have version 3.0.184 as our next master version. Following that, I'll write up a post that documents everything new relative to the previous master version 3.0.165, as there has been quite a lot! But if you want to upgrade now, I do think there's very little risk in upgrading existing master/main installs to the current dev branch, as it is quite stable at this point, in my experience. Thank you for all of your help in testing and/or reporting issues. Have a great weekend!
    31 points
  7. This is a holiday week here in the US, at least for my kids (school break). With kids home I've been off work this week so don't have any ProcessWire updates to report, but I'm looking forward to getting back to work next week and will have more updates to report then. Yesterday was Thanksgiving here in the the US and that kind of marks the beginning of the holiday season here. So today the Christmas tree went up, the lights are coming out and the holiday music has taken over the radio (or Alexa or Google or whatever we call it). Cheers and Happy Holidays!
    30 points
  8. This week I've been focusing on the dev branch and some low level code optimization, especially as it relates to the PW boot process, translating URLs to pages and identifying the page, language, URL segments, page numbers, etc. from the request URL. I'm breaking down much of the logic (currently in the ProcessPageView module) into more focused parts that can become part of PW's $pages API, increasing reusability of related code. (Don't worry, this won't affect any existing hooks). At the same time, I'm looking for opportunities for optimization and performance improvement, and have already found a few. For instance, the LanguageSupportPageNames module introduces overhead into some page finding operations and there's good improvement potential there, among others. I'm pretty much still in the middle of it all though, so am going to hold off on committing any of this to the dev branch until it's further along. But since we've got a quiet commit log this week, I just wanted to keep you up-to-date. Hopefully some of these fairly significant updates will be stable enough to commit to the dev branch next week. By the way, these updates will also enable the SessionAllow module (from last week) to be configurable by page, as PW will now identify the requested page before starting the session. More soon. Have a great weekend!
    30 points
  9. The UserActivity Pro module in ProDevTools was upgraded this week so that it now uses the Javascript Beacon API, enabling quick and reliable identification of when a user has finished a particular activity. It also now keeps track of when an activity is visible to the user or the window is hidden (like minimized or in a different tab), and it is able to report how many unsaved changes a user has made. All of this is visible from the Access > Activity menu in the admin. On the core side, there have been minor updates, so no version bump this week. But there are still a couple new PRs and useful things to look at in the commit log. The plan for next week: Bernhard Baumrock has been working on a PR that makes it very simple to modify and recompile the CSS of our AdminThemeUikit module... like as simple as placing an admin.less file in /site/templates/ directory. I'll save the details for next week, but after using it a bit here I have to say it's very cool. It also makes it really simple to upgrade the Uikit version. Previously I'd been following the build process as outlined in the Uikit instructions and often found myself in a state of confusion with npm errors and strange dependencies, needing upgrades for unidentifiable tools and producing incoherent warnings that never went away and left me with little confidence in the process. Perhaps it was because I started all this back when Uikit 3 was still beta, but the result was that I didn't much like upgrading Uikit or recompiling our AdminThemeUikit CSS, and I don't think anyone else did either. It made it a little difficult for our AdminThemeUikit module to achieve its original mission of being a simple module that many would extend and build from. Well, Bernhard has found a way to skip over all that nonsense and made it much simpler for all of us, so that AdminThemeUikit can finally be what it set out to be. I look forward to integrating this PR hopefully this coming week and think it means a lot of good things for our admin. Also, huge thanks to Pete for upgrading our forums this week! It's a great upgrade.
    30 points
  10. This week I've had to work on a client project (and that continues for the next week or two), but also have some good progress in the next development branch version of ProcessWire (v3.0.171), which includes the addition to two feature requests: The Repeater Fieldtype (and likewise RepeaterMatrix) was updated to improve support for the "depth" option by introducing something called "family friendly mode". This makes the "depth" setting behave in a manner where items with more indent are considered children of items with less indent (parents). So when you click and drag to move a parent item, it brings along the children too. This works whether changing the location or the indent of the parent. In addition, it enforces the parent/child relationship so that there can't be more than one level of indent between parent and child. So you couldn't (for example) have a parent-to-grandchild relationship in the repeater items. A useful case for this is when using repeaters in page builder contexts, like those Jonathan Lahijani demonstrated with RepeaterMatrix. In fact, the settings in this "family friendly" mode were his idea. More to come here too. To enable "family friendly mode", go to your Repeater or RepeaterMatrix field settings and make sure the "depth" setting is greater than 1. When greater than 1, the family-friendly option will appear as a toggle you can enable. The other thing added to the core this week was a FieldtypeDecimal module that has been requested for awhile. I was planning on making it a setting of FieldtypeFloat, largely to avoid interfering with the existing 3rd party FieldtypeDecimal module. But a few people indicated they'd prefer it to be separate. After testing on an installation that already had the 3rd party FieldtypeDecimal installed, I found it didn't cause any problems, so that alleviated my concern. To be safe, the new core FieldtypeDecimal module uses the same exact setting names as the 3rd party one, so that hopefully they should remain compatible. In my case, I found that deleting my /site/modules/FieldtypeDecimal directory, and then doing a “Modules > Refresh” enabled the core one to take over with any existing decimal fields. However, until we have reports that the same works well for others, I would suggest backing up and confirming it yourself to be safe. It's not often we intentionally introduce module name collisions, and I don't think we've ever done it in the direction where a new core module overlaps with an established 3rd party one. But in this case, it does seem to facilitate the transition a bit. That's all for this week. I've been enjoying and am looking forward to continuing with our roadmap discussions hopefully next week. Have a great weekend!
    30 points
  11. I've got some core updates in progress but nothing major committed yet, so we'll save that for next week. But I wanted to briefly tell you about a module I'm working on here, which I plan to eventually put in core. I built it for some needs I've had here, but it will first be released in ProDrafts (so ProDrafts may start using its API), and in ProDevTools too, since it is also a developer tool. It's a snapshot versioning system for pages, but more of an API tool at this stage, kind of like the $pages API var, but for snapshots/versions of pages. It lets you create a snapshot of any page, including its fields and files (including core fields, ProFields, 3rd party fields, repeaters, nested repeaters, table fields with a million rows, etc.). The snapshots can be restored at any later time. Snapshots may also be restored to a different page, such as a new or existing page. In this manner, a module like ProDrafts may be able to use it to manage draft versions even better than it currently can, or at least that's the plan. Though since it's an API tool, my hope is that when/if it winds up in the core, others may be able to use it for stuff we've not thought of yet too. The module is a little different than my previous attempts (like what's in ProDrafts now) in that it does most of its work directly at the database level (and file system level, where applicable), which enables it work without needing to know much about the Fieldtype. Currently it is fully functional, but I have a few less common cases to work out before it's ready for release. Once installed, every page includes a Snapshots fieldset, which can be located in the settings tab of the page editor, or a separate tab in the page editor (configurable). When installed, every page has one, so long as the user has the appropriate permissions. There's a screenshot of what it looks like in the page editor below, but it is very simple at this stage, basically just enough for testing purposes. Every snapshot has a name that is unique on the page. You can overwrite a snapshot just by saving a snapshot with the same name on the same page. So you could for instance have a hook that creates a snapshot named "undo" right before a page is saved (in a Pages::saveReady hook), and in that way a module could add a basic undo capability to the page editor. This is just a simple example though. Thanks for reading, have a great weekend!
    29 points
  12. While the version remains at 3.0.181 this week, there have been several core updates committed to the dev branch containing a mixture of issue fixes, new features, core optimizations and upgrades. This is likely to continue for another minor version or two while we prepare for our next master branch release. The most visible improvements this week can be found in ProcessField and ProcessTemplate (aka Setup > Fields, Setup > Templates). The main list of fields (Setup > Fields) has been improved with some new supported icon indicators that now identify fields that have template overrides/context settings, among others. All of the existing icon indicators have also been updated with contextual links so that clicking them takes you to the relevant part in the template editor. My favorite update here though is that the "Type" column in the fields list now indicates the Inputfield type in cases where it matters. For instance, rather than saying "Textarea" for the "body" field, it now says "Textarea/CKEditor". Likewise, Page and Options fields indicate what kind of input is used (i.e. "Page/AsmSelect" or "Options/Checkboxes"), as do some other types. Clicking on the "Templates" quantity now takes you to the "Add/remove from templates" field, rather than just showing you a list of templates. Similar updates were made to the ProcessTemplate main list of templates (Setup > Templates) though there wasn't as much to do there. Once you are actually editing a template, the instructions on the "Basics" tab have been improved to clarify what you can do on this screen. For instance, many don't know that you can click a field name/label to edit it in context, or that you can click and drag the percent indicator to adjust the field's width in the editor, all from this tab in the template editor. Now the description outlines these features. When you select a new field to add to your template, it now reveals a note that clarifies you must save before the field becomes editable in the context of that template. These are minor updates, but combined I think they add significant clarity, especially for new users. Stepping outside of the core, I've been working quite a bit this week on the PagesSnapshots module I told you about a couple of weeks ago. It lets you save or restore snapshot versions of pages, and it doesn't have any notable limitations in terms of fields. At this stage it is working fully with repeaters, matrix repeaters, nested repeaters, Page Tables and even paginated Table fields with thousands of rows. It can restore to the original page, to a new page, or to another page of your choice. And it is very fast. Eventually ProDrafts will use its API to handle saving and publishing of draft versions. Initially I plan to release it in one or more of the existing module sets (like ProDevTools or ProDrafts or both), and longer term it may be added to the core. I've got another week or two of work to cover with it, but at this stage the API is fully functional and working well, so I'm now beginning to focus more on the Process module (user interface) side of it. Thanks for reading and have a great weekend!
    29 points
  13. 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!
    29 points
  14. ProcessWire 3.0.179 adds great new admin theme customization tools that put you in full control over the admin styles, thanks to PR #189 from @bernhard — https://processwire.com/blog/posts/pw-3.0.179/
    29 points
  15. 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.
    29 points
  16. This week I've been developing a client site, but also working through some of the feature requests. I'm going through them in order of "thumbs-up" on GitHub and trying to focus more on those that I can get through reasonably quickly. For a summary of what's been added, be sure to see the dev branch commit log. There's still a few more I'd like to add before bumping the version to 3.0.173, so will save that for next week. One of the requests was for the ability to add custom after-save actions in the Page editor. These are the "Save + Exit", "Save + Add New", etc., dropdown actions that you see on the Save button in the page editor. This is something that's already supported, but not formally documented. So I wanted to quickly go through a couple examples of how to do that here, as it is kind of useful and fun. Let's start with a "hello world" example to keep it simple, then we'll move on to a more practical example. Say we want a "Save + Say Hello" dropdown action in our page editor Save button. We need one hook to add the action, and another to process it. These hooks could go in your /site/ready.php file or your /site/templates/admin.php file, or in a module. First we'll want to hook ProcessPageEdit::getSubmitActions() to add our custom "hello" action: $wire->addHookAfter('ProcessPageEdit::getSubmitActions', function($event) { $actions = $event->return; // array of actions indexed by name $page = $event->object->getPage(); // page being edited // add a new action that says hello after saving page $actions['hello'] = [ 'value' => 'hello', // value for action that you will check 'icon' => 'hand-spock-o', // icon to show in action, excluding the 'fa-' part 'label' => '%s + Say Hello', // the '%' is replaced with 'Save' or 'Publish' 'class' => '', // optional class if you need different styling for button/link ]; $event->return = $actions; }); To process our action, we'll need to add a hook to ProcessPageEdit::processSubmitAction(): $wire->addHookAfter('ProcessPageEdit::processSubmitAction', function($event) { $action = $event->arguments(0); // action name, i.e. 'hello' $page = $process->getPage(); // Page that was edited/saved if($action === 'hello') { $notice = new NoticeWarning("Hello! You edited page $page->path"); $notice->icon = 'hand-spock-o'; $event->notices->add($notice); } }); That's all there is to it. That part where I created the $notice above could just as easily been $this->warning("Hello!..."); but I wanted to add a custom icon to it, which is why I created the Notice manually. Many of the built-in after-save actions perform a redirect to another location, such as adding another page, exiting back to the page list, viewing the page on the front-end, etc. If you have a need to perform a redirect after the save, use the $event->object->setRedirectUrl($url); method. This is preferable to calling $session->redirect(); yourself, as it is handled by the page editor after it has finished everything it needs to do. What if you just want to remove one of the existing actions? For instance, maybe you want to remove the "Save + Add New" action. That action has the name "add", so we can remove it like this: $wire->addHookAfter('ProcessPageEdit::getSubmitActions', function($event) { $actions = $event->return; // array of actions, indexed by name unset($actions['add']); $event->return = $actions; }); If there's another you'd like to remove, I'd recommend using TracyDebugger and bd($actions); so you can see and identify all the actions that are present from your hook. Now let's get to a more practical example. Let's say that you are using ProCache and you want to add a save action to automatically prime the cache after performing the save. By "prime the cache" I mean have it perform a page-view on the front-end that makes it save a new cache file for the page. Here's how you could do that: $wire->addHookAfter('ProcessPageEdit::getSubmitActions', function($event) { $actions = $event->return; // array $page = $event->object->getPage(); // page being edited $procache = $event->wire('procache'); if(!$procache) return; // if procache not installed, do not add action if(!$page->isPublic()) return; // page not public is also not cacheable if(!$page->viewable()) return; // page not viewable has no template file if(!$procache->isPageCacheable($page)) return; // page not setup for cacheing $actions['cache'] = [ 'value' => 'cache', 'icon' => 'fighter-jet', 'label' => '%s + Cache', // Save + Cache 'class' => '', ]; $event->return = $actions; }); …and our hook to process the action: $wire->addHookAfter('ProcessPageEdit::processSubmitAction', function($event) { $action = $event->arguments(0); // action name, i.e. 'cache' $page = $process->getPage(); // Page that was edited/saved if($action === 'cache') { $http = new WireHttp(); $response = $http->get($page->httpUrl); if($response) { $size = wireBytesStr(strlen($response)); $event->message("Cache primed for page $page->path ($size)", "nogroup"); } else { $this->warning("Error caching page: " . $http->getError()); } } }); Note that we don't have to clear the cache file here because that's something that ProCache has already done prior to our hook above being called. Thanks for reading and have a great weekend!
    28 points
  17. I developed the new Geffen Playhouse website over the course of 2018/2019 and launched it in September 2019. It has been perhaps the largest project I have been involved in. The Geffen Playhouse went through an entire re-branding done by Base (including a custom font), and I worked with Teak on the new website. Website https://www.geffenplayhouse.org/ Wikipedia https://en.wikipedia.org/wiki/Geffen_Playhouse Base write-up https://www.basedesign.com/work/geffen-playhouse-always-geffen-playhouse-always-new Teak SF write-up https://teaksf.com/work/geffen-playhouse-ticketing-ecommerce-website-design/ Another write-up: https://www.laurentakayama.com/geffen Their previous website was severely antiquated and it wasn't a responsive website (as of 2019!). Instead, it forwarded mobile users to a "mobile-friendly" website on a different subdomain, which I think was hosted by a third party service. However the data containing all the actors, shows, seasons, news and press articles were all in there. So one major aspect of this website was de-duping and importing their data into ProcessWire, along with some post-import cleaning… that's ~25 years of data. The site is built with UIkit 3 for the most part, and also uses FullCalendar for the large and small calendars. There is a custom integration with AudienceView, their ticketing system, which is used to import all the performance showtimes of their shows into ProcessWire. It's not the easiest API to work with (XML), but I eventually got it working. Repeater Matrix is being heavily used for section-based page building. Building out all the necessary matrix types took a long time as there was quite a bit of thinking what types and layouts we needed as we went along. However the end result has given the editors a lot of flexibility. ProCache is being used as well, including a CDN for all assets. This is crucial because when opening season sales are announced, the site gets slammed, but with caching turned on, it's not a problem anymore. On a deeper level, the site uses my new (well 2 years old now), universal and very opinionated base module that provides a menu builder, a standard set of fields/templates/pages, and a bunch of other tweaks that I tend to use on every site. All the fields, templates and pages are set up in a streamlined and editor friendly way. I wasn't able to access their previous CMS backend for various reasons (I only got the MySQL dump), so when developing the site and data model in ProcessWire, I was able to completely re-envision the editor experience and the data model without bias. A quote from one of the marketing directors at Geffen Playhouse: "We absolutely love ProcessWire."
    27 points
  18. The next dev version of ProcessWire is in progress but I'll wait till likely next week to bump the version. So far there are 6 new pull requests added since 3.0.179 and 2 issue resolutions, plus some other updates, with plenty more on the way. A lot of focus this week has also been on FormBuilder updates which include new spam filtering options, improved save-to-page options, improved Combo field support, new entries actions (and the ability to add more via modules and hooks), framework updates, and various minor bug fixes. This version has a lot of nice improvements and I'm hoping to have it ready for you in the next week or so. More details soon. Have a great weekend!
    27 points
  19. 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!
    27 points
  20. 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!
    27 points
  21. All the updates I mentioned last week are committed on the dev branch today, and it's quite a lot of new code and revised code. There's enough here to justify a couple of version bumps, but I'm leaving it at 3.0.185 temporarily because the ProcessWireUpgrade module will see the version change and some people might upgrade automatically. Because there's so much that's been rewritten, refactored, added and changed here, I'd like it to marinate for a week on the dev branch before it triggers any upgrade notifications. Our dev branch tends to be very stable, and this is one week where there's enough new code that I don't want to call it as-stable-as-usual just yet (though it might very well be). In addition, it's also not totally finished as there's still some redundant code to be removed and stuff that needs to be moved around a bit, though everything should be fully functional as-is. I am running it here on the processwire.com site without any issues, so chances are that all is good, but I always like to be cautious. Below is a summary of what's new and changed. It's a bit technical, and there's nothing here that's all that important to know about, but whether you read on or not, just know that the core is getting even better and faster with updates like these. The core PagePaths module has been refactored and has multi-language support. Previously it only worked on single-language sites. Now multi-language sites can take advantage of potentially significant performance improvements offered by this module. This is one module that is not installed by default, but it's definitely worth installing: Modules > Core > PagePaths. The core LanguageSupportPageNames module has been refactored. Assuming I did it well, you shouldn't notice any difference other than that it's faster. For instance, one of the changes is that it drops its old indexes on the pages table and re-creates them in a different way. I discovered some situations where finding pages by multi-language path was resulting in full pages table scans. Using MySQL “explain” statements I found I could prevent that by reversing the order of the columns in the language-specific indexes, preventing the full table scan and making it many times faster. This could make a big difference on large multi-language sites, but is less likely to be noticed on smaller sites. The LanguageSupportPageNames module also gained a new configuration setting that lets you specify what should happen when a page is accessed at a language it's not available in: throw a 404 or redirect to the default language. The core PagePathHistory module has been refactored. It has a powerful new getPathInfo() method, though it's primarily of interest for internal core use. A new PagesRequest class has been added to the core and it can be accessed from $pages->request(). It primarily focuses on one hookable method: $pages->request()->getPage(). The method accepts no arguments but it analyzes the current request, identifies the page to render, and returns it. Previously this logic was in the ProcessPageView module. The benefit of this method is that you can now determine the page to render much earlier, like during the boot process. Previously the current page wasn't identified until after PW booted and the ProcessPageView module loaded. This will enable [for example] a module such as SessionAllow to decide whether or not to allow sessions based on what page was requested. In addition, this method is hookable, so you could have a module that adds its own logic to identify or change the page that should be rendered. A new PagesPathFinder class has been added to the core and can be accessed from $pages->pathFinder(). Like the PagesRequest class, this new class primarily focuses on one method: $pages->pathFinder()->get($path). The given $path can contain any page path, optionally containing language prefix, URL segments, pagination numbers, or even a previously named version of the path. It will find and validate that path and return an array of information about it. PagesPathFinder does its job very quickly. In fact, it's about 10 times faster (in testing/timing locally) than PW could previously identify this information using existing methods. PagesPathFinder will also take advantage of the PagePaths and/or PagePathHistory modules when appropriate, if they are installed. Below is an example of what the return value would be for path /es/hello/bar/baz/page3 where /es/ is the language prefix, /hello/ is the actual page, /bar/baz/ are the URL segments and /page3 is the pagination number segment. It analyzes everything out and returns a 200 "ok" response if the path is good, or in this case, it's returning a redirect because it detected a Spanish URL with English page name and pagination prefix, and it's suggesting a redirect: $info = $pages->pathFinder()->get('/es/hello/bar/baz/page3'); [ 'request' => '/es/hello/bar/baz/page3', // path that was requested 'response' => 301, // one of 200 (ok), 301 (permRedirect), 302 (tempRedirect), 404 (pageNotFound), 414 (pathTooLong) 'type' => 'permRedirect', // ok, permRedirect, tempRedirect, pagePathError, pageNotFound or pathTooLong 'errors' => [], // array of error messages indexed by error name 'redirect' => '/es/hola/bar/baz/pagina3', // suggested path to redirect to, blank otherwise 'page' => [ // info about page that was matched 'id' => 1237, 'parent_id' => 1232, 'templates_id' => 12, 'status' => 1, 'name' => 'hello' ], 'language' => [ 'name' => 'spanish', // name of language detected 'segment' => 'es', // segment prefix in path (if any) 'status' => 1 // language status where 1 is on, 0 is off ], 'parts' => [ // all the parts of the path identified [ 'type' => 'language', 'value' => 'es', 'language' => 'spanish' ], [ 'type' => 'pageName', 'value' => 'hello', 'language' => 'default' ], [ 'type' => 'urlSegment', 'value' => 'bar', 'language' => '' ], [ 'type' => 'urlSegment', 'value' => 'baz', 'language' => '' ], [ 'type' => 'pageNum', 'value' => 'page3', 'language' => 'default' ] ], 'urlSegments' => [ // URL segments identified in order 'bar', 'baz' ], 'urlSegmentStr' => 'bar/baz', // URL segment string 'pageNum' => 3, // requested pagination number 'pageNumPrefix' => 'page', // prefix used in pagination number 'scheme' => 'https', // blank if no scheme required, https or http if one of those is required 'method' => 'pagesRow', // method(s) that were used to find the page ] While you might never need to use this method yourself, ProcessWire now uses it on every request. And now that this logic is isolated from ProcessPageView and has a dedicated $pages API, it's much more open and we can, for example, more easily apply tests to this logic. I've covered a few updates here but there's more if you feel like digging in the commit log https://github.com/processwire/processwire/commits/dev. Thanks for reading and have a great weekend!
    26 points
  22. ProcessWire 3.0.180 contains 20 commits containing various minor new features, issue resolutions and pull requests. While there's no single major feature to write a big blog post around, combined there are a lot of worthwhile and useful updates so this version is definitely worth updating to. More details can be found in the dev branch commit log and at ProcessWire Weekly (issue #370 covered an addition to our $files API var). Yesterday the forums were running a little slow because we had our yearly DDOS’er pay the site a visit once again (remember last time?), and from an apparently unlimited supply of IP addresses around the world this time. We shut down the forums to users that weren't logged in while the load was high. Actually, it does this automatically now. We also updated the forums from using memcached to AWS Redis, which should also help as a nice upgrade for the forums. Big thanks to @Pete and @Jan V. for setting it up and keeping everything running smoothly. I'll keep it short today because it's supposed to rain here all weekend, so I'm going to spend some time outside while I can. Thanks for reading and have a great weekend!
    26 points
  23. ProcessWire 3.0.190 has 15 commits relative to 3.0.189 and contains a mixture of issue resolutions and feature additions. We’ll review these below, in addition to updates for the PageAutosave and ProFields Table modules— https://processwire.com/blog/posts/pw-3.0.190/
    25 points
  24. This week we have some very useful new additions to both the core Repeater Fieldtype and the ProFields Repeater Matrix Fieldtype. This post covers all the details along with a couple of brief demonstration videos— https://processwire.com/blog/posts/new-repeater-and-repeater-matrix-features/
    25 points
  25. It took a little more time this week to wrap up what I was finishing last week (and the week[s] before). But I think it's now at a good spot to move on to something else, and so I started with some Repeater and RepeaterMatrix updates. In Repeater, a new feature was added that's been requested for awhile: the ability to add items anywhere you choose. Previously you could do it only by adding items to the bottom, and then drag them in place. Now you can click insert before/after [icons] in each repeater item header and it will add the new item in place. It is also depth-aware. This is something that I think will also be useful especially for people using repeaters for page builder type contexts. (Note: the feature does not [yet] work if you have all Ajax features turned OFF in your repeater settings). There's a GIF screencast below that shows you how it works. You can click the "insert before" or "insert after" actions and it inserts a new item in place. Alternatively, if you hover either action for a second, it'll show you where it's going to insert an item and you can click either the the item, or the action, to complete the insertion. There's still likely some optimizations and improvements to make in the JS here but so far it seems to be working well. (I made this as a GIF but for some reason IP.Board won't accept it, so here's a YouTube embed instead): Everything in Repeater also gets inherited by RepeaterMatrix, so you'll find this feature there too. But it's not fully functional there just yet. That's because RepeaterMatrix items also have a "type", so I'm working on a new version of RepeaterMatrix that lets you select a type once you've chosen where to insert the item. Another related feature in progress in RepeaterMatrix at the same time is a dropdown/select option for choosing what matrix type you want to add for items. This is an alternative to the current list of links that appears at the bottom. The dropdown also gives you the option of having groups of related types. More on that soon, potentially next week. Thanks for reading and have a great weekend.
    25 points
  26. 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.
    25 points
  27. 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!
    25 points
  28. A couple weeks ago there were a lot of ideas about page builders and different approaches in ProcessWire. Some really interesting ideas actually, and great proof of concepts as well. The conversation started moving faster than I could keep up with, and I think Teppo's summary in ProcessWire Weekly 351 is a great overview, if you haven't yet seen it. These are so great in fact, that I don't think anything I build could live up to what some of you have already built. In part because my focus is more server-side than client-side development, and I can clearly see most of these page builders are much more client-side based than I have expertise in (though would like to learn). Whereas some of you are clearly amazing client-side developers; I'm blown away by what's been built, and how quickly it happened. One struggle I have with page builders is that I don't have my own good use cases for them, with the projects that I work on. Others here (like Jonathan) already have a lot of good use cases. Clearly there are a lot of benefits. I'm fascinated and enthusiastic by all of it, but can't envision how or if I'd use such a tool in my own projects. And having experience with (and particularly close use cases for) a tool is important in hitting the right notes in building it. Likely page builder support belongs in ProcessWire in some form or another, and ProcessWire can be an excellent platform for it. But the actual page builder needs to be designed and built by the people that have expertise in the tools needed to build it, and by the people that will actually use it. I think it should be a community collaboration. For anything needed to support this on the PHP side, count me in. I don't think I've got the background to "lead" the development of the page builder, but I do think I've got plenty to contribute to it. I'd also like to continue building out existing tools like Repeater/Matrix to further support page builder type use cases. I'd like to rebuild and move the auto-save and Live Preview features from ProDrafts into the core, which should also help support some of these page builder cases. Whether these will eventually apply to the larger page-builder project, I don't know, but they'll be useful either way. What are the next steps? Who's interested in working on this? Let's keep the conversion going and move forward with it.
    25 points
  29. https://www.kaumberg.gv.at/ Hello everybody! Today I want to share a project that I've been working on for a year or so: The new website for municipal Kaumberg - a beautiful village near Vienna. To be honest, this project was way more work than I initially expected. The site has tons of content and the client came with lots of good ideas during the process of building this site. For example after we launched the site several organisations of the village realized that the system works great and is easy to use, so they wanted their own section with their own color scheme... Right now the system is maintained by several user accounts that populate content to the site. Some of them only in the news-section, others are allowed to publish to the sub-sites (eg for the fire department). Recently we won the 2nd price out of 190 cities in lower austria - where Kaumberg was by far the smallest one also having the smallest budget of the top rated cities! ### NOTE ### This system was built with scalability in mind. If you know any other municipals (preferable in a german speaking country) that could possibly need a new website using my setup write me a PM. If you are a marketing guru and know how we can sell this product to 100s of municipals, let me know. I know how to do that from the technical point of view 🙂 ### HIGHLIGHTS ### CONTENT Custom multi-level menu for managing loads of content pages that also works well with keyboard navigation 😎 --- EVENT MANAGEMENT Events are managed via the PW backend and presented as calendar on the website plus can be downloaded as PDF calendar in A3 format for printing: --- CONTENT BLOCKS I've developed a new (private) module called RockMatrix for versatile, easy and fool-proof content creation for this project. This setup ensures that even non-tech-savvy users can create content that looks nice and works on all devices from desktop to mobile: --- SITE SEARCH Another new module that was developed for this project is RockSearch. I hate site searches that do work on the first sight but do not on the second. For example if they show older results on top of newer ones. Or if they do not index content that is not stored within a regular text field but for example as image description. On the other hand I did not want to use ElasticSearch because it seemed to be overhead to send data to another service that is already stored in the database of my PW installation... RockSearch shows results based on different weighing mechanisms, for exampe a search for the garbage collection schedule first shows results that are nearer to the current date than others (both future and past). That means that a date two days in the future will be shown above one that is 10 days in the past. Also results get different score based on where the term was found - matches in the site title get higher scores than matches in the body or in image descriptions or the like. Each content block is a RockMatrix block that has a render() method to define the output on the website and - for RockSearch - has a method called "searchIndex()" that defines the content that is written to the search index that is queried for every search request: This setup makes it super easy to add new content elements and to add them to the search index 😎 --- SUB-SITES The client can create sub-sites for different organisations of the village having custom color schemes and managing user access: News can be tagged to show up on different areas of the website: --- OTHER The site uses no cookies and can therefore be used without an annoying cookie banner. Page hit statistics are gathered by PageHitCounter and shown by RockHitCounter Some other little features are short-links for social media (eg https://www.kaumberg.gv.at/goto-1027 ) or the possibility for creating custom subdomains for sub-sites like http://araburg.kaumberg.at/ I'm quite sure I forgot lots of great stuff, but I hope you enjoyed reading this article nevertheless 🙂 Looking forward to your feedback!
    24 points
  30. This week we have ProcessWire 3.0.192 on the dev branch. This is about 20 commits ahead of the previous version and contains 11 issue fixes and 5 pull requests, along with various other updates. PR code contributors in this version including Daun, MrSnoozles, Radon8472, BernhardBaumrock and Tyde. Thanks! For more details see the dev branch commit log. In addition to core updates, in recent weeks I've also been working on a new module similar to the PageAutosave (developed for the admin) except that it is for front-end forms. It works with any front-end form (whether home brewed or from something like FormBuilder) and remembers the entered form values every time a field is changed. If the user doesn't submit the form, they get an email with a link to finish filling out the form after a configurable period of time. This is especially nice for order and reservation forms. Accompanying the module is a separate Process module that lets you view all the forms in progress in the admin. Each form entry has its own unique URL, making them easy for users to return to, from any device. Once the user submits the form, the data gets removed from the pending submissions database. This is something I've been meaning to develop for awhile, and with the admin PageAutosave module still fresh on my mind, I thought now was a good time to do it. Thanks for reading, Happy New Year and have a great weekend!
    24 points
  31. Last week we released the new ProcessWire 3.0.184 master/main/stable version. This is our biggest version release in a year. It's been a very smooth stable version launch with no major issues so we're keeping the version number where it is this week. If you haven't upgraded yet, it's an easy and worthwhile upgrade. For full details see the blog post that covers it all. This week I have 3 new Textformatter modules released in the modules directory. These are modules that I developed earlier for recurring needs that I had, but this week decided to finish them up and release them. I hope that you might find one or more of them useful sometime. TextformatterFindReplace This module applies find/replace patterns to formatted text or markup at runtime. The patterns may be simple text or more complex regular expressions. This module can be handy if you perform a text replacement on all output from a particular field, without having to manually make the change on all instances where it might appear. For instance, maybe you need to insert a trademark symbol ™ after every appearance of a brand name, or maybe your website hostname has changed and you need to replace all references to it, or perhaps you need to replace all <h1> headlines with <h2> headlines. These are just a few examples of any number of possibilities. Read more / Usage / Examples TextformatterMarkdownInMarkup Enables you to use Markdown formatting codes in CKEditor (or HTML). A significant amount of content that is populated into the “bodycopy” field of websites is not actually written in the admin and instead originates from text editors, word processors, and other tools outside of the CMS. It then gets pasted into CKEditor, and then manually formatted into HTML using tools in CKEditor. This process of manually converting links, lists, headlines, bold, and italic text and more can be sometimes very time consuming. This module provides a time saving alternative, enabling use of markdown formatted text in CKEditor (or any HTML/richtext editor). It remains as markdown formatted text in the editor, but as soon as it is rendered on the front-end it is automatically formatted as HTML. This means that text like **this** gets converted to this, links like [this](https://processwire.com) get converted to this, and so on for most types of markdown formatting. This enables markdown formatted text to be written anywhere and the formatting to be rendered properly in your bodycopy when viewed on your website. Using this module means that you can mix richtext and markdown in the same copy. No longer do you have to manually convert all of the links, lists, bold/italic, and so on in pasted in text. This module saves me quite a bit of time when writing blog posts like the one last week. Much of the formatting in that post was markdown based, since I wrote the post in my text editor over a period of a couple weeks. Once I got it into CKEditor, I did some formatting with that too, but when it came to other formatting (especially links and inline `code`) it was a big help to have them just work, and not to have to re-do all of them manually with CKEditor tools. So why not just work exclusively in Markdown? Well I don't like working with just markdown most of the time, I much prefer CKEditor. But I also can't deny the convenience of markdown for a lot of cases too. So being able to use Markdown within CKEditor is the best of both worlds, to me at least. Read more / Supported markdown / Configuration options TextformatterEmoji This module converts more than 800 named shortcode emojis in ProcessWire text or textarea fields to the corresponding UTF-8 emoji character. 😜 This can be especially useful if your ProcessWire database uses the utf8 character set rather than utf8mb4, as it enables you to use emojis on an installation that typically would not be able to save them. This is because emojis usually require utf8mb4 (4 bytes characters) to be used by the database in order to store them. Though when you want to specify an emoji by name, this module will be useful regardless of your database charset. Read more / Supported emojis reference
    24 points
  32. Relative to ProcessWire 3.0.182, today's version (3.0.183) contains about 30 commits and resolves 23 issues. It also contains various small tweaks and improvements throughout. For example, when editing the title of a page, it updates the headline as you type in the page editor (in Uikit and Reno admin themes). I think we've got another 1-2 weeks of these kinds of updates (resolving issues and minor improvements) before we release the next master version, and am currently thinking that version will carry version number 3.0.184. I'm also continuing work here on the page snapshots module I wrote about earlier, but am going to wait releasing it until the next master version is complete. If you have a chance to test out ProcessWire 3.0.183 on the dev branch, please let us know how it works for you, and especially if you run into any issues. Thanks for being here and have a great weekend!
    24 points
  33. This week has been a continuation of last week in terms of ProcessWire development. While a lot of work has been done, there's not much new to report relative to last week, but I like to check in and say hello either way. I enjoyed putting a lot of time into the PagesSnapshots module this week and it's coming along nicely, getting closer every day. Today I've focused primarily on resolving GitHub issue reports, and am going to keep doing that every week till our next master version, which I hope to be ready in 2-3 weeks (same for the new module). But we'll adjust as needed. The next master version is going to be really solid, so I'm getting excited about it. I will likely bump the dev branch version to 3.0.182 next week. There were a couple more minor issues I wanted to get resolved in 3.0.182 but needed to spend a little more time with before I commit to the dev branch. Thanks and have a great weekend.
    24 points
  34. This week there have been various small core updates and fixes but the biggest change was to the installer in 3.0.191. Last week we removed all but the site-blank profile from the core, cutting in half the size of the core. And because of this, the installer now needed to provide more direction about downloading and installing other site profiles. So it now does that and it also links to a new page that describes all of the past and current site profiles, along with additional details on how to create and install site profiles. Speaking of creating site profiles, the Profile Exporter module was also updated this week. It is now PW 3.x exclusive and is updated to recognize and work with various aspects and $config properties that are specific to 3.x. ProcessWire 3.0.191+ and the Profile Exporter module now support a custom /site/install/finish.php file which is a template file that is called when installation of a new ProcessWire and site profile has finished, but before it has cleaned up the installer. It is a plain PHP file that has access to PW's API and the installer, so it can do pretty much anything you could do from a regular template file or module. I added this because I noticed a few issue reports for the Profile Exporter module were requesting support of one thing or another, and I found that nearly all of them could be added just by having a profile-specific finishing file, for those that want it. So if you want your site profile to perform any other types of customizations on top of what you can already do with a site profile, this is the place to do it. This is where things are at this week but perhaps we'll continue to go further with the installer in supporting more things too in the new year, as there have been several good ideas. Thanks for reading and I hope that you all have a Merry Christmas and/or Happy Holidays!
    23 points
  35. There's a new $pages->new() API method on the core dev branch this week. This method is similar to the $pages->add() method, in that it is used to add new pages to the DB, but is a lot better in my opinion. The $pages->add() method has arguments that you have to remember, whereas $pages->new() accepts a single-argument selector string, like many of the other $pages API methods. This new method can also auto-detect some properties that the add() method cannot (like parent or template). Let's take a look at how to use it. Here we create a new page from a selector string, and it returns the new page (saved in the database): $p = $pages->new("template=category, parent=/categories/, title=New Category"); If you prefer, you can also use an array: $p = $pages->new([ 'template' => 'category', 'parent' => '/categories/', 'title' => 'New Category' ]); The page name and parent can be auto detected if you specify a path: $p = $pages->new('path=/blog/posts/foo-bar-baz'); But if you start the selector string with "/" then it is assumed to be the path, so this is is exactly the same thing as above: $p = $pages->new('/blog/posts/foo-bar-baz'); In your selector string or array, you can specify any page property or field name that you want to set with the new page. It's basically just a quicker way to do something that's already pretty easy to do, but I thought people might find this new option even more handy in many instances. To create a new page, it needs to know the template and the parent. If your template family settings are configured in a manner where it can auto-detect, then it will do so, at which point parent or template becomes optional. In the last example above, it detected that the template was "blog-post" and the parent was "/blog/posts/". A few things to note (pulled from the method documentation): If a `path` is specified but not a `name` or `parent` then both will be derived from the `path`. If a `title` is specified but not a `name` or `path` then the `name` will be derived from the `title`. If given `parent` or `path` only allows one template (via family settings) then `template` becomes optional. If given `template` only allows one parent (via family settings) then `parent` becomes optional. If given selector string starts with a `/` it is assumed to be the `path` property. If new page has a name that collides with an existing page (i.e. “foo”), new page name will increment (i.e. “foo-1”). If no `name`, `path` or `title` is given (that name can be derived from) then an “untitled-page” name will be used. The `class` of the Page will be auto-detected when applicable (and something different than `Page`). An exception will be thrown if it doesn’t have enough information to create a new page in the database. I've also updated the existing $pages->newPage() method to accept the same selector string (or array). You might already be familiar with this method, but if not, it creates a new page in memory, but not the database. So you might use it to create a new page that you will call save() upon later. $p = $pages->newPage('template=blog-post, name=hello-world'); This week the core also has a few issue fixes. I'll wait another week before bumping the dev branch version though, as there's more to add first. Though the next few weeks might be little slower on core updates as the end-of-the-year seems to always be the busiest time when it comes to client work... everyone wants to wrap things up before the new year, and I do my best to accommodate that, while also keeping PW updates in progress. Thanks for reading and have a great weekend!
    23 points
  36. 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/
    23 points
  37. ProcessWire 3.0.178 focuses largely in adding pull requests (PRs), which are code contributions by ProcessWire users. We had quite a few great pull requests pending, and in total we have added 26 of them in 3.0.178— https://processwire.com/blog/posts/pw-3.0.178/
    23 points
  38. 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.
    23 points
  39. This week we have a couple of useful new $pages API methods. They are methods I've been meaning to add for awhile but hadn't found the right time. The need coincided with client work this week, so it seemed like a good time to go ahead and add them. I'm doing a lot of import-related work and needed some simple methods that let me work with more page data than I could usually fit in memory, and these methods make that possible. These won't be useful to everyone all the time, but they will be useful in specific cases. The first is $pages->findRaw() which works just like the $pages->find() method except that it returns the raw data from the matching pages, and lets you specify which specific fields you want to get from them. For more details see the findRaw() documentation page. There's also getRaw() method which is identical to findRaw() except that it returns the raw data for just 1 page, and like get(), it has no default exclusions. The next method is $pages->getFresh(). This works just like $pages->get() except that it gets a fresh copy of the page from the database, bypassing all caches, and likewise never itself getting cached. ProcessWire is pretty aggressive about not having to reload the same page more than once, so this method effectively enables you to bypass that for cases where it might be needed. Again, probably not something you need every day, but really useful for when you do. More details on the getFresh() documentation page. I'm going to likely cover these new $pages API methods in more detail in a future blog post, along with some better examples, so stay tuned for that. I noticed there's some pretty great conversion and examples happening in the posts on page builders here, but have been so busy this week I haven't had a chance to dive in, but I'm really looking forward to doing so. Thanks and I hope you all have a great weekend!
    23 points
  40. A few days ago I stumbled upon this old module, which had been laying in the modules directory of one of my sites since 2017 in a half-finished state. I have no recollection why I left it like that, but figured it might be useful for someone, so here we go: https://github.com/teppokoivula/Snippets https://processwire.com/modules/snippets/ Snippets is a tool for injecting front-end code snippets (HTML/JS/CSS) into page content. The way it works is that you create a snippet — say, a Google Analytics tag — and then choose... which element it should be tied to (there are some pre-populated choices and custom regex option), whether it should be placed before/after said element or replace it entirely, and which pages the snippet should apply to. The "apply to" option also has some ready to use options (such as "all pages" and "all non-admin pages") or you can select specific pages... or use a selector. Snippets are regular markup, with the exception that you can use values from current page (behind the scenes the module makes use of wirePopulateStringTags()). Available hooks: Snippets::isApplicable, which receives the snippet object and current Page object as arguments and returns a boolean (true/false). Snippets::applySnippet, which receives the snippet object, page content (string), variables (an object derived from WireData), and an array of options for wirePopulateStringTags() as arguments and returns the modified page content string. That's just about it. It's a pretty simple module, but perhaps someone will find this useful 🙂
    22 points
  41. Like last week, this week, updates continued on the core and matrix repeater fields. Repeater and matrix fields can now be configured to use fewer pages. When set, it won't create placeholder pages for repeater items until at least one repeater item exists for a given page and field. This can drastically reduce the number of pages consumed by repeaters in your system, and even more so if you are nesting repeaters. Eventually, this will become the default setting, but for now we are playing it safe and making it optional with a new toggle that you'll find on the Details tab when editing a repeater or matrix field: After enabling the "Use fewer pages..." Setting, the "Find an optionally delete unnecessary pages" checkbox will take care of cleaning up anything that isn't necessary for existing repeaters already in the database. If you have a large site with a lot of repeaters, this could be deleting a lot of now irrelevant stuff, so just be aware of that and backup ahead of time to be safe. Thanks to @Jonathan Lahijani for the idea/suggestion. Also new this week is the ability to copy and paste repeater items, as well as to clone above or below existing items. It handles this by replacing the existing "clone" icon action with a dialog that now lets you choose among various related actions. Among them is the ability to copy/paste from the same page or between different pages. The only requirement is that the repeater (or matrix) items are from the same field. See the video below for an example of how this works: This works with either Repeater or Repeater Matrix fields. But if you want this feature in Repeater Matrix, you'll want to upgrade to ProcessWire 3.0.188 and download the new version posted today (v8 beta) in the ProFields download thread. The ability to copy/paste repeater items was an idea originally from @David Karich and a module he developed called Repeater Matrix Item Duplicator. Thanks for reading and have a great weekend!
    22 points
  42. Hello @ all I want to share a new module with you, which makes the creation and validation of forms easy. Take a look at the following example of a simple contact form: // A very simple example of a contactform for demonstration purposes $form = new Form('contactform'); $gender = new Select('gender'); $gender->setLabel('Gender'); $gender->addOption('Mister', '0'); $gender->addOption('Miss', '1'); $form->add($gender); $surname = new InputText('surname'); $surname->setLabel('Surname'); $surname->setRule('required'); $form->add($surname); $name = new InputText('name'); $name->setLabel('Name'); $name->setRule('required'); $form->add($name); $email = new InputText('email'); $email->setLabel('E-Mail'); $email->setRule('required'); $form->add($email); $subject = new InputText('subject'); $subject->setLabel('Subject'); $subject->setRule('required'); $form->add($subject); $message = new Textarea('message'); $message->setLabel('Message'); $message->setRule('required'); $form->add($message); $privacy = new InputCheckbox('privacy'); $privacy->setLabel('I accept the privacy policy'); $privacy->setRule('required')->setCustomMessage('You have to accept our privacy policy'); $form->add($privacy); $button = new Button('submit'); $button->setAttribute('value', 'Send'); $form->add($button); if($form->isValid()){ print_r($form->getValues()); // do what you want } // render the form echo $form->render(); This piece of code creates a simple contact form and validates it according to the validation rules set. Inside the isValid() method you can run your code (fe sending an email) Highlights: 30+ validation types Support for UiKit 3 and Bootstrap 5 CSS framework SPAM protection Highly customizable Hookable methods for further customization Multi-language You can download and find really extensive information on how to use at https://github.com/juergenweb/FrontendForms. Please report errors or suggestions directly in GitHub. Best regards and happy testing 🙂
    22 points
  43. This week ProcessWire has gone on a diet. I've been working on reducing the size of the core by moving all (except site-blank) installation profiles out of the core and into their own repositories. This cuts the size of the core in half, going from 15.5 MB down to 7.5 MB, which is quite a slim down! This means the site-regular, site-default, site-beginner, site-languages, and site-classic now live in their own dedicated repos on ProcessWire’s GitHub. The site-blank one remains, but I've updated it a bit to make the template files more useful for beginners while still keeping it a blank profile. I may do a little more with it and rename it to be site-basic or something, and then have an even more trimmed down site-blank in its own repo as well. I'm not yet sure about that, so will do a little more with it next week also. I also went through each of these site profiles and cleaned up a few things, corrected old and outdated links, and updated a lot of text in readme files and such. I think a lot of the more experienced users would also prefer not having extra profiles included in the core as well. This update came at the request of the community a few months back (I think it was Robin S. that requested it, but not positive). It's not like any of the current site profiles have a lot of bling or marketing value, as they really are more just technical examples and starting points. So I think it's kind of a win/win to trim down the core in this way. Though maybe one day we'll have a site profile that looks good and has good marketing value. But until then I think we gain more by keeping the core size nice and trim. The downside is that there's a little more for new users to figure out (downloading a profile), so in the next week or so I'm planning to update the installer to hopefully lessen that issue and maybe even build in the ability for the installer to download and install site profiles from the modules directory. That comes with its own security considerations, so I'm not yet sure we'll go that far just yet, but it's one of a few options I'm looking at. Thanks for reading and have a great weekend!
    21 points
  44. Hi all, The forums have just had a fairly major upgrade - everything seems brighter and cleaner though as always if you spot any areas we may have missed that don't look quite right (broken rather than different), please comment here.
    21 points
  45. ProcessWire 3.0.185 is the latest version on the dev branch this week. Relative to the current master (3.0.184) this is 9 commits ahead and contains various minor fixes, improvements and additions. Since our current master version is quite stable and no significant issues have surfaced since release, we'll likely be focusing on the dev branch for several versions before merging back to the master/main branch. For details on what's new in 3.0.185 dev see the commit log. ProcessWire Weekly #383 also includes some details on a few new selector features added last week that you'll find in this version, read about it here. Today I've posted a new module in the directory called Session Allow. This module enables you to configure whether to allow sessions for each request based on simple configured rules. Currently it requires ProcessWire 3.0.184 or newer. The reason I built this module is that I find the current $config->sessionAllow setting (where you define a custom function) can be a little complicated to work with, especially since it gets called before most of ProcessWire’s API can even be used. This module aims to make control of sessions a lot simpler than that. The benefit of being able to control when a session is allowed is that it lets you better focus your resources for sessions to just the requests where they will be needed, helping to reduce server overhead and improve performance. Currently it supports allowing (or disallowing) sessions based on page path matching rules and hostname matching rules. I also plan to add support for sessions allowed/disallowed per page template, which I think would be really useful. But it'll take some changes to the PW core to support that, as ProcessWire starts the session before determining what page has been requested (and thus what template will be used). So I'm going to make the necessary core updates and then save that feature for version 2 of this module. I'm releasing the module as "alpha" right now because I rushed a bit to get it out for today and feel it needs more testing before I can call it stable. So if you are interested in using it, make sure to test everything out in a development environment first. And if you do get a chance to test it, please let me know how it works for you. Thanks for reading and have a great weekend!
    21 points
  46. 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/
    21 points
  47. In preparation for testing of the initial (alpha/early beta) release of Padloper 2, I would like to gather expressions of interest. In the past, some of you expressed a willingness to help with testing. It has been many days since and your position might have changed. In addition, I would like to do this in an organised manner so we cover as much ground as possible. The grounds I’d like to cover are usability and technical aspects with a bias towards the latter. Please also note that there are a number of planned features that will follow the initial release. Hence, we shouldn’t focus much on those. These and similar thoughts will be added to a planned features list (more on this below). The main focus of this testing is to make Padloper 2 production-ready. In order to properly organise this testing, I will need to gather some information from you. I will be doing this via Google Forms. The most important detail will be your email address. I will need this in order to inform you how to access Padloper 2 as well as for other necessary communication. I will not use your email address for any other purposes nor pass it to any third-party 🙂. Other information to be captured in the form would be what areas of testing you will you want to be involved in and your preference for planned features (since I will need to prioritise them). Forms are better than plain emails in this respect. Please note the following if you wish to be involved in the testing programme: Pricing and subscription will follow the model I have previously stated (similar to ProcessWire Pro Modules). However, for the testing programme, your subscription period will NOT start counting down until after the production-ready release. You will still also have VIP support (please note the nature and location of this may change). To be fair to other testers, anyone joining the programme needs to actually spend time testing the product. If you won’t have time to do this, please wait for the production release. This initial release is NOT a production release. Although it may work for some in that regard, it will not be tagged as production-ready (hence the alpha tag). Licences will be the usual three: (i) Basic/Single Site Licence, (ii) Developer Licence and (iii) Agency Licence. I can explain the different between these three if anyone needs clarity. The initial release will have the introductory prices of €150, €300, €900 for single, developer and agency licences respectively. Cooling period will be 14 days (within which a full refund can be requested, no questions asked). Please note that this time period may change for the production release. Here is the link to the Google Form to express your interest in the testing programme. The form will close in 10 days. Many thanks for your patience. Hope to see you soon in the testing programme. I trust you will enjoy Padloper 2 as much as I have had the pleasure (and honour) of developing it 🙂.
    20 points
  48. ProcessWire 3.0.182 is now posted on the dev branch. For a review of what's in this version, see the "Latest core updates" section of ProcessWire Weekly #374 and #375 plus this week there have been 12 additional commits with new issue resolutions, improvements and additions which can be found in the dev branch commits log. It's possible that ProcessWire Weekly #376 will also cover some of these updates when it is released too. I'd planned on even more in this version, but ended up losing a day of work yesterday as we had no electricity all day (it happens). So I worked outside in the yard instead— 3 issues were resolved, 4 improvements were made and 1 garage was organized. Focus in the coming weeks is on our next main/master version (core, not yard). If you have a chance, please take a moment to add sites you've built with ProcessWire to our sites directory. And if it's one that's already in the directory, feel free to add it again when/if it goes through a major redesign or redo. I'm really motivated by seeing the great work that all of you do and always enjoy seeing more of it. Plus, I'm thinking @teppo also likely looks at the newly submitted sites when considering the site of the week for his ProcessWire Weekly issues. If you find the existing categories on the submission form don't quite match a site you want to add, please send me a PM to let me know and I may be able to add new categories. Thanks for reading and have a great weekend.
    20 points
  49. A Fieldtype for dynamic options that are generated at runtime via a hook. Configuration Inputfield type You can choose from a range of inputfield types on the Details tab of a Dynamic Options field. Your field will return a string or an array depending on if the selected input field type is for "single item selection" or "multiple item selection". Maximum number of items You can define a maximum number of items the field is allowed to contain. The core inputfields supported by this module will become disabled once the limit is reached. This option is only applicable if you have selected an inputfield type that is for multiple item selection. Format as Pagefile/Pageimage object(s) If the field will store paths/URLs to Pagefiles/Pageimages then you can enable this option to have the formatted value be a Pagefile/Pageimage object for "single" fields or an array of Pagefile/Pageimage objects for "multiple" fields. There is a related Select Images inputfield module that allows you to visually select image thumbnails. Defining selectable options Selectable options for a Dynamic Options field should be set in a FieldtypeDynamicOptions::getSelectableOptions hook in /site/ready.php. The hook should return an array of options as 'value' => 'label'. An example hook is shown on the Details tab of a Dynamic Options field: $wire->addHookAfter('FieldtypeDynamicOptions::getSelectableOptions', function(HookEvent $event) { // The page being edited $page = $event->arguments(0); // The Dynamic Options field $field = $event->arguments(1); if($field->name === 'your_field_name') { $event->return = [ 'red' => 'Red', 'green' => 'Green', 'blue' => 'Blue', ]; } }); Formatted value If a Dynamic Options field uses a "single" input type then its formatted value is a string, and if it uses a "multiple" input type then its formatted value is an array. The unformatted value of a Dynamic Options field is always an array. Also see the Configuration section above for description of an option to have the formatted value be Pagefile/Pageimage object(s). Examples of possible uses $wire->addHookAfter('FieldtypeDynamicOptions::getSelectableOptions', function(HookEvent $event) { // The page being edited $page = $event->arguments(0); // The Dynamic Options field $field = $event->arguments(1); // Select from the "files" field on the page if($field->name === 'select_files') { $options = []; foreach($page->files as $file) { // Value is basename, label is description if one exists $options[$file->basename] = $file->get('description|basename'); } $event->return = $options; } // Select from files in a folder if($field->name === 'select_folder_files') { $options = []; $path = $event->wire()->config->paths->root . 'my-folder/'; $files = $event->wire()->files->find($path); foreach($files as $file) { // Value is full path, label is basename $options[$file] = str_replace($path, '', $file); } $event->return = $options; } // Select from non-system templates if($field->name === 'select_template') { $options = []; foreach($event->wire()->templates as $template) { if($template->flags & Template::flagSystem) continue; $options[$template->id] = $template->name; } $event->return = $options; } // Select from non-system fields if($field->name === 'select_field') { $options = []; foreach($event->wire()->fields as $field) { if($field->flags & Field::flagSystem) continue; $options[$field->id] = $field->name; } $event->return = $options; } // Select from FormBuilder forms if($field->name === 'select_formbuilder_form') { $form_names = $event->wire()->forms->getFormNames(); // Use form names as both keys and values $event->return = array_combine($form_names, $form_names); } }); https://github.com/Toutouwai/FieldtypeDynamicOptions https://processwire.com/modules/fieldtype-dynamic-options/
    20 points
×
×
  • Create New...