Leaderboard
Popular Content
Showing content with the highest reputation on 02/14/2025 in all areas
-
This week we’ve got 2 new versions out: 3.0.246 on the main/master branch, and 3.0.247 on the dev branch. Version 3.0.246 (main/master) contains several minor bug fixes that were discovered after 3.0.244. And 3.0.247 on the dev branch adds support for conditional hooks that can match method return values. The hooks documentation has been updated with a new section that covers all the details here. I’m going to slow a bit on core updates over the next few weeks so that I can dedicate more time to developing the new ProcessWire website. The designers have done a great job and now I need to focus on getting some parts of it developed and new text written, etc. I’ll keep you up-to-date as it moves forward. Thanks for reading and have a great weekend!6 points
-
I ended up using a custom image field as required for the image description to add some notes too. With the following hook on ready.php, I just copy the custom image field description value to the native description field so it can be displayed as alt attribute on RTE images. The native description field no need to be displayed in the editor. It can be as 0 on "Number of rows for description field?" $wire->addHookBefore('Pages::saveReady', function($event) { $page = $event->arguments('page'); if ($page->template->name != "my-template") return; foreach($page->images as $image) { $image->description = $image->image_description; } });1 point
-
I apologize if I sounded rude in my first reply. It had been some years since I’d last worked with WordPress, when an academic friend asked me to help her migrate (and upgrade) her WP site last month to a new provider. This should have been a very straightforward job, but every single one of the plug-in authors had built in limitations that kept me from doing very simple things unless I upgraded to their pro-level versions — and in most cases this would have involved minimum one-year subscriptions. And since my client’s site had been hosted with a provider that allowed no command-line access and only limited SFTP, I was at the plug-in authors’ mercy. Your situation is quite different, of course, but the whole experience reminded me strongly of what I dislike about what WP has become. In my case, I can attest that PW is about 50% of my income, and that I devote about 50% of my work-time towards it, so it’s certainly a viable means of income. But it’s true that creative work, even in IT, is a less predictable income stream than maintenance. Best of luck with ProcessWire, and with going freelance! I hope we’ll continue to see you here in the forum!1 point
-
Hüttenzauber - The magic of the Swiss Alps. Eat, celebrate and sleep in the most beautiful places in the mountains. Today, I am presenting to you a very cool and challenging project we tackled and successfully finished last summer. Obviously, Fruitcake is 100% a ProcessWire agency at this point but still, this project especially proves again and again that ProcessWire’s flexibility and unopinionated structure just works for us every time. Gone are the days where we are breaking and bending other CMSs to work the way we need it to work. “Hüttenzauber” is a well-known brand in the Bernese Alps skiing and hiking destinations. Lately, they expanded into other regions of the Swiss Alps and accumulated a variety of locations they are both managing and running from their central offices at the birthplace of the enterprise, Lenk im Simmental. Coding one of our latest projects to date was a cool but also daring challenge. We set out to replace a few dozen single websites for each of the different locations with one big website. The general goal was to streamline all the information and present a concise yet still quite independent experience to the website’s visitors. In addition to the independent experiences, the website features a plethora of central features like a search map, an illustrative blog, cool events and a web shop whose contents however, are again compiled together from blog articles written for or events happening at the different locations. The website was conceptualized, designed and programmed 100% in-house by us. It features tons of content which is completely available in both German and English (with a small JavaScript language detection function). ProcessWire admin: have exactly one source of truth I think we can be proud of the challenge we set out to achieve: Have every information only ever written down once. This is most beneficial for the client since they can for example change the hotel’s address once and it is then displayed at many different locations automatically. The client factually only needs to work with our database we created in the ProcessWire admin area and the website presents that information in a variety of places automatically. One example of that in action is restaurants. There are two types of restaurants: locations which actually are restaurants but also restaurants inside other locations, e.g. hotels. The client can easily a new restaurant inside a hotel (in PW terms that is just add a “restaurant” as a child of a “hotel”) and just set up all of it’s information like descriptions, menus, booking links and images. This entry will automatically display on the search map as part of the hotel, be added to the “book a table” buttons everywhere across the website and also have it’s information and download links be displayed on the hotel’s detail page. And by the way, the client also can (and does!) add hotels inside hotels, e.g. a small resort with independent booking but which factually is part of a bigger hotel complex. They add, press save and “it just works!” 🤯 To achieve this goal, we made extensive use of the beloved “addHookProperty” method to for example output a list of all the “book-a-table” links for any specific page which makes programming the front end of the website a whole lot easier! 🥳 The culmination of all this is a simple and easy tree structure in the admin area like this (this is just part of it): All the information one might add about a restaurant or hotel is entered in each entry’s fields. Every coordinate, address and image is only ever entered once. All of this for example results in the search map and floating booking buttons completely automatically: Not only there, but also in the menus: Content «Page Builder» In addition to all the meta information, all of the pages should allow to have a completely independent experience for a visitor. That is why any restaurant and hotel gets it’s own landing page which acts as a mini landing page. There, the information is broken down: Booking links show only for the location itself (remember, there still might be multiple 😉), events are automatically filtered by location and sub-restaurants are displayed automatically. Yet still, all of the content feels dynamic because we make heavy use of @ryan’s Repeater Matrix module. For some of the blocks, the information is entered directly but for others, the information is grabbed from the events catalog or the blog entries and automatically filtered as appropriate for the page where the block is displayed on. For example, the events block on a hotel page only displays events for that specific location whereas if the events block is used on the homepage, everything is displayed. Here is a few of the blocks the client can use on any page: Webshop with Print@Home vouchers To finish up this showcase, now for the most interesting part for all developers here, the webshop and all it’s interfaces to external services. From the very beginning, we knew, we needed to use something which will offload the cart and checkout parts of the shop completely because we don’t have the capacity to create a full webshop application for this project and there was nothing around we could build upon (this is only partly true, there is @Gadgetto's SnipWire which was a big inspiration). Obviously, nowadays there are alternatives around the corner like @bernhard’s RockCommerce which might just be the on-page solution for cart and checkout ProcessWire needs. Although the shop might seem small and unimpressive when looking at it from the user’s perspective, a lot has to happen in the background. Part of it is that we had to combine two types of products and part of it is the actual technologies we ended up using. The first product type is your standard product which gets shipped to the buyers. These products are easy compared to the second type - a streamlined experience starting in the shop where the user picks a value and a greeting for a print-at-home voucher, pays for it and together with the order confirmation is sent the voucher as a PDF ready to be printed. This lead us on an adventure where we came across asynchronous payment confirmation, custom payment processors for SnipCart and a small translation layer mapping one API to the other. In the end, we built a system of three modules for ProcessWire like this: The heart of the system is our «Snipart Integration» module. Think of it as a baby-SnipWire. It adds webhook handling, a custom payment provider API and JSON product info endpoints for SnipCart to work on the website. Building on the custom payment provider API, we have the «Wallee interface» which acts as a translation layer from the asynchronous API Wallee speaks to the synchronous one SnipCart uses. Further, we have the «Boncard interface» which adds webhook handlers to reach out to the print-at-home provider to generate and fetch the PDFs and finally sending them to the client, using our fourth and last external provider: SendGrid. Since SnipCart already uses SendGrid, this one was easy to decide. Also, there is a very good integration available with WireMailSendGrid. All of the modules have been built with reusability and modularity in mind: all of them have a configuration screen to add API secrets amongst other settings. They can be used as a package or in parts. This is useful if for example, you don’t need Wallee as a payment provider or do not have Boncard’s print-at-home vouchers in your webshop. Also, more custom payment providers are easily added using the main module’s API and webhook handlers. Conclusion There is still much to tell especially about the shop and custom payment providers’ implementations and challenges we faced. If you guys are interested, I can start working on a case study. Let me know! I will leave you with a few links for you to look at and/or get more information: https://huettenzauber.ch/ our main subject https://www.fruitcake.ch/projekte/huettenzauber/ our portfolio entry about the project COMING SOON link to page on ProcessWire Showcase Also, I don't want you to miss out on what's running behind the scenes: ProFields: Combo ProFields: Repeater Matrix Seo Maestro ProcessRedirects Tracy Debugger WireMailSendGrid All of this rocks on ProcessWire v227.1 point
-
Over the years, I've experimented with using RepeaterMatrix as the basis of a rich page builder. I've gone through at least a dozen concepts, most of which hit the chopping block due to either being too complex, not well thought out, too clever or too limiting. To my knowledge, the only other CMS that takes the "Builder" approach that I've demonstrated is DjangoCMS (meaning, it has a matrix-like field with depth support). While the "Builder" approach works well, it could be too advanced for some people. Therefore the other approach is the "Classic" approach where you don't deal with containers/rows/columns (which instead is handled by template code), and simply enter the content in the respective field. This is easy to understand, but has drawbacks in terms of flexibility. If it were made to be too flexible, it would become a "God" block which is bad. Then I finally thought of a third approach which is a mix between the Builder and Classic approach. It uses the basic builder blocks, combined with the layout from the matrix item template file. By using the basic builder blocks, you get the plethora of options. It requires an extra page to be created behind the scenes however, but live preview still works. I made a video comparing all the above (10m duration). I want to hear your feedback on this as I am ~75% done with my super module (doing a lot of code and concept cleaning at this point) and want to finish off this portion of it. (note: I'm posting this in the Dev Talk forum since this is a discussion / not support request)1 point
-
I've probably thought up a dozen different approaches to creating an ideal page builder in ProcessWire but each of them have their pros and cons. It's very difficult to strike a perfect balance for something that suits both developers and editors. There are so many (!) other variables to consider. This isn't just a ProcessWire dilemma, but just the nature of page building itself. There are trade-offs and complexity must live somewhere. In an ideal world, you'd use RepeaterMatrix in a classic way, but if you run that thought experiment, here's what happens: I'll make matrix-types for all the sections in a particular page. I'll write the templates for those matrix-types, so all an editor has to do is fill in the fields and everything just falls into place. I'll drive off into the sunset and be happy. Well, turns out there are some changes that need to be done. MatrixType X needs another field. I'll add that field and update the template. Well now we need another matrix-type, but it's basically identical to MatrixType X except the columns are flipped. Does this warrant a new matrix-type or a toggle option of some sort? ... You start another new project and it needs a page builder like the first site. You realize there's going to be some heavy re-use of matrix-types from the first site, so you now think... hmm maybe I should somehow modularize this approach where there is a shared matrix-type library. (I've done this) ... Many of the matrix-types between site 1 and site 2 are similar, but with slight differences... some have different css class names, some have different field names. Now this shared matrix-type library has a bunch of matrix-types but you feel unsatisfied because you think there is a better way to refactor this. The ideas in your head about how to refactor end up going against the grain of the classic page builder way / repeater matrix approach and now you're frustrated. I've gone through this thought process a bunch of times. I've researched basically every single page builder out there. It's like trying to solve a puzzle without a definitive end result. One thing that happened is reactive frameworks gave rise to the current generation of page builders (think WP Block Editor / Gutenberg, SquareSpace, and few dozen others). This left the classic page builder approach behind (RepeaterMatrix, ACF Flexible Content). But I like the classic approach because it gives more programmatic control and it's the way ProcessWire works... and editors can't really mess things up since it's a more controlled experience. I feel like there hasn't been experimentation and development for the classic approach since the world has "moved on" to the newer generation approach. I think RepeaterMatrix is good, but maybe it can benefit from some experimentation of some sort.1 point
-
For some inputfield visibility constants it is too late to set them at inputfield render. For Inputfield::collapsedHidden, Inputfield::collapsedNoLocked and Inputfield::collapsedYesLocked these are handled by the InputfieldWrapper class. I've found that a good method to hook for setting the visibility of fields in Page Edit is Field::getInputfield. This example is for /site/ready.php but easy to adapt to a module context: $wire->addHookAfter('Field::getInputfield', function(HookEvent $event) { // Only for ProcessPageEdit if($this->page->process !== 'ProcessPageEdit') return; $field = $event->object; $inputfield = $event->return; if($field->name == 'proj_code_folder') { $inputfield->collapsed = Inputfield::collapsedNoLocked; } });1 point