Jump to content

Leaderboard


Popular Content

Showing content with the highest reputation since 01/25/2018 in all areas

  1. 55 points
    Hey guys, Thought I would share a quick preview of Designme. A module we (Eduardo @elabx and I) are building for visually laying out your templates/edit screens. 🙂 This is a really quick, zero polish screen grab. FYI. Video #2 - UPDATE This new video shows the following features in Designme: Re-arranging fields via Drag & Drop Re-sizing fields via Dragging. Adjusting field settings - with live refresh. Working on "hidden" fields while Designme is active. Creating New fields. Deleting fields. Creating/Deleting Tabs. Dragging fields between tabs. Creating fieldsets. Tagging/Un-tagging fields. Fields without headers expand when hovered (like checkboxes). Live filtering of fields in the sidebar. Ability to adjust (all) Template settings without leaving Designme. Template File Tree Editing Template files source code with ACE Editor. Editing Multiple files with ACE Editor. (New Tabs) Saving files. Techie stuff Fields load their own js/css dependancies. *ready to use on creation (*most fields) Everything happens via Ajax to ProcessPageEdit (via module + hooks). Designme has a JS api that you can use. All actions trigger events. We would love any detailed feedback on what you see so far. If you are interested in testing Designme. Let me know below. 🙂 Video #1.
  2. 45 points
    Happy new year, everybody 🥬 I've been sitting on this Dashboard module I made for a client and finally came around to cleaning it up and releasing it to the wider public. This is how it looks. ProcessWire Dashboard If anyone is interested in trying this out, please go ahead! I'd love to get some feedback on it. If this proves useful and survives some real-world testing, I'll add this to the module directory. Download You can find the latest release on Github. Documentation Check out the documentation to get started. This is where you'll find information about included panel types and configuration options. Custom Panels My goal was to make it really simple to create custom panels. The easiest way to do that is to use the panel type template and have it render a file in your templates folder. This might be enough for 80% of all use cases. For anything more complex (FormBuilder submissions? Comments? Live chat?), you can add new panel types by creating modules that extend the DashboardPanel base class. Check out the documentation on custom panels or take a look at the HelloWorld panel to get started. I'm happy to merge any user-created modules into the main repo if they might be useful to more than a few people. Disclaimer This is a pre-release version. Please treat it as such — don't install it on production sites. Just making sure 🍇 Roadmap These are the things I'm looking to implement myself at some point. The wishlist is a lot longer, but those are the 80/20 items that I probably won't regret spending time on. Improve documentation & add examples ⚙️ Panel types Google Analytics ⚙️ Add new page 🔥 Drafts 🔥 At a glance / Page counter 404s Layout options Render multiple tabs per panel panel groups with heading and spacing between ✅ panel wrappers as grid item (e.g. stacked notices) ✅ Admin themes support AdminThemeReno and AdminThemeDefault ✅ Shortcuts panel add a table layout with icon, title & summary ✅ Chart panel add default styles for common chart types ✅ load chart data from JS file (currently passed as PHP array) Collection panel support image columns ✅ add buttons: view all & add new ✅
  3. 40 points
    I'm so glad I wanted to share that with you today. Since November 2017, all of the company's infrastructure is built on ProcessWire. Whether it is the showcase website or the millions of transactions recorded in the database as pages or all the custom modules to interact with the company's data. Just to say that I feel lucky to work all the day with what I love, and when I remember that I was demoralized thinking I had to learn Wordpress or I don't know what, because before ProcessWire I never worked with a CMS and it was becoming vital. Then I stumbled on ProcessWire (hooray!). And now, a new step for me appeared yesterday. I have a trainee for a month. And my task is to teach him how to work with ProcessWire! This make me really proud ! Have a nice day everyone and again, thanks to this community and this software! 👍
  4. 39 points
    ProcessWire 3.0.157 on the development branch continues the trend of core refactoring that’s been happening quite a bit in 2020. Rather than doing a rewrite every few years (like some CMS projects) we instead refactor parts as we go, constantly improving and optimizing the core. This works because the core design/architecture is right where it needs to be, even 10 years in. But there’s always still bits of legacy code, and code that can be improved. So in the context of ProcessWire, refactoring means incrementally rewriting code on the inside, without changing its behavior on the outside (other than making it faster and/or more secure). This has been happening regularly over the last 10 years, and will likewise continue happening over the next 10 years and likely beyond. This week the code behind ProcessWire’s core Database and PageFinder classes got a major refactoring. This is some of the most used code in PW, as it handles everything involved in taking a selector and converting it to a database query. But it’s always been a little bit of a pain point for me because it had to build queries in a way that I thought wasn’t ideal, in order to make it possible for lots of different modular parts (mostly Fieldtype modules) to contribute to the query and for PageFinder to put it all together. It was fast and secure, but still one of those parts that felt like a little too much duct tape to me. But considering how crucial the code is, I’ve always been reluctant to make major changes, since it all worked just fine. Spending lots of years thinking about it (on and off), a desire to work out any pain points, and having better tools available (like Phpstorm and Tracy) made it possible to finally massage out this pain point. Some work still remains to be done, but it’s mostly there and I’m feeling good about it. Stuff like this is key for the maintenance and longevity of the core, and involved a lot of time and effort, but makes very little difference to users, even if it makes a lot of difference to me in maintaining the core. It would make a boring blog post for sure—lots of work and changes, but no new toys to show for it. Nevertheless, it has that feeling of a good house cleaning, even if you can't see it from the outside. The scope of changes here means that there may actually be new bugs to work out, so to be on the safe side, consider 3.0.157 to be a little more “beta” than the dev branches usually are. Though I’m running it here on processwire.com and it’s working well. Beyond the fairly major updates to the Database classes, there are also a few new Sanitizer convenience methods that are primarily variations on existing ones, but useful ones for sure. Thanks for reading and have a great weekend!
  5. 38 points
    Hey folks! I'm happy to finally introduce a project I've been working on for quite a while now: it's called Wireframe, and it is an output framework for ProcessWire. Note that I'm posting this in the module development area, maily because this project is still in rather early stage. I've built a couple of sites with it myself, and parts of the codebase have been powering some pretty big and complex sites for many years now, but this should still be considered a soft launch 🙂 -- Long story short, Wireframe is a module that provides the "backbone" for building sites (and apps) with ProcessWire using an MVC (or perhaps MVVM – one of those three or four letter abbreviations anyway) inspired methodology. You could say that it's an output strategy, but I prefer the term "output framework" since in my mind the word "strategy" means something less tangible. A way of doing things, rather than a tool that actually does things. Wireframe (the module) provides a basic implementation for some familiar MVC concepts, such as Controllers and a View layer – the latter of which consists of layouts, partials, and template-specific views. There's no "model" layer, since in this context ProcessWire is the model. As a module Wireframe is actually quite simple – not even nearly the biggest one I've built – but there's still quite a bit of stuff to "get", so I've put together a demo & documentation site for it at https://wireframe-framework.com/. In addition to the core module, I'm also working on a couple of site profiles based on it. My current idea is actually to keep the module very light-weight, and implement most of the "opinionated" stuff in site profiles and/or companion modules. For an example MarkupMenu (which I released a while ago) was developed as one of those "companion modules" when I needed a menu module to use on the site profiles. Currently there are two public site profiles based on Wireframe: site-wireframe-docs is the demo&docs site mentioned above, just with placeholder content replaced with placeholder content. It's not a particularly complex site, but I believe it's still a pretty nice way to dig into the Wireframe module. site-wireframe-boilerplate is a boilerplate (or starter) site profile based on the docs site. This is still very much a work in progress, but essentially I'm trying to build a flexible yet full-featured starter profile you can just grab and start building upon. There will be a proper build process for resources, it will include most of the basic features one tends to need from site to site, etc. -- Requirements and getting started: Wireframe can be installed just like any ProcessWire module. Just clone or download it to your site/modules/ directory and install. It doesn't, though, do a whole lot of stuff on itself – please check out the documentation site for a step-by-step guide on setting up the directory structure, adding the "bootstrap file", etc. You may find it easier to install one of the site profiles mentioned above, but note that this process involves the use of Composer. In the case of the site profiles you can install ProcessWire as usual and download or clone the site profile directory into your setup, but after that you should run "composer install" to get all the dependencies – including the Wireframe module – in place. Hard requirements for Wireframe are ProcessWire 3.0.112 and PHP 7.1+. The codebase is authored with current PHP versions in mind, and while running it on 7.0 may be possible, anything below that definitely won't work. A feature I added just today to the Wireframe module is that in case ProcessWire has write access to your site/templates/ directory, you can use the module settings screen to create the expected directories automatically. Currently that's all, and the module won't – for an example – create Controllers or layouts for you, so you should check out the site profiles for examples on these. (I'm probably going to include some additional helper features in the near future.) -- This project is loosely based on an earlier project called pw-mvc, i.e. the main concepts (such as Controllers and the View layer) are very similar. That being said, Wireframe is a major upgrade in terms of both functionality and architecture: namespaces and autoloader support are now baked in, the codebase requires PHP 7, Controllers are classes extending \Wireframe\Controller (instead of regular "flat" PHP files), implementation based on a module instead of a collection of drop-in files, etc. While Wireframe is indeed still in a relatively early stage (0.3.0 was launched today, in case version numbers matter) for the most part I'm happy with the way it works, and likely won't change it too drastically anytime soon – so feel free to give it a try, and if you do, please let me know how it went. I will continue building upon this project, and I am also constantly working on various side projects, such as the site profiles and a few unannounced helper modules. I should probably add that while Wireframe is not hard to use, it is more geared towards those interested in "software development" type methodology. With future updates to the module, the site profiles, and the docs I hope to lower the learning curve, but certain level of "developer focus" will remain. Although of course the optimal outcome would be if I could use this project to lure more folks towards that end of the spectrum... 🙂 -- Please let me know what you think – and thanks in advance!
  6. 37 points
    I hope that you have had a great week! I’ve been working hard on finishing up the LoginRegisterPro module this week and actually have it ready. But I’ve been told I have to get off the computer in 20 minutes, so so I think I’ll wait till Monday to release it. But I do have the new info page (which is kind of like last week's blog post) and new documentation page now online. The documentation page in particular is pretty comprehensive. In last week’s post there was a form to request more info once it’s released, so if you are interested in this module and haven’t filled out that form, please do. That’s how I’ll be sending out the introduction coupon code this time around, for those that want it. There have also been some core updates this week, but it was just a few commits, so not enough to warrant a version bump today. That’s actually a good thing, as no major new issues turning up means one step closer to merging onto the master branch. There will be a new master version before this year is done! Thank you for reading and I hope that you all have a great Christmas and/or holiday week next week!
  7. 36 points
    I hope everyone here is doing well, staying in, and staying healthy. Our town here is under a “stay at home” order, and it’s now the law that you can’t get within 6 feet of any other person when out walking. So haven’t left the house (other than for walks and bike rides) in about 2 weeks now. Though with the whole family home all the time, it admittedly feels a lot busier than before this Coronavirus stuff, I think because there’s now a lot more people to attend to during the day (especially kids). Not much silence compared to before. 🙂 Not a bad thing, just very different. If we’ve got to spend a few months, or even a year this way, it’ll be alright, so long as the internet keeps working. I’m just thankful to have a job where I’m already used to working this way, as I know many of you do too. It seems that this whole situation is going to move a lot of activity online that previously wasn’t, so I anticipate it’s going to be potentially a very busy and important year for web development. Online communication and content delivery is going to be that much more important for the world, making reliability, scalability and security every bit as important. These are always our focus, but just want to emphasize this even more as we look forward. With a world in temporary disarray, you can count on ProcessWire to be an especially stable and reliable tool that gets even better every week, and our community always a friendly and helpful place. I’ve got several things in progress in the core, but nothing far enough along to write about just yet. I’ve also been putting a lot of work into ProCache this week, which is long due for a version update. The module still has quite a bit of PW 2.x architecture that I don’t think is needed anymore, so I’m refactoring and improving quite a bit, in addition to feature updates. Thanks for reading and I hope that you have a good and safe weekend!
  8. 35 points
    Hi all, I have posted this in the VIP support forum of Padloper as well. Some of you do not have access to that board so posting here as well. Hopefully it doesn't count as spamming🙂! In June 2018, Antti announced that he was looking for a new product owner for Padloper. Sometime after, I had a fruitful discussion with him about my vision for the project if I was to take over. We agreed that commitment, motivation and a concrete plan were all important ingredients for the continued success of Padloper. I would like to officially announce that I am now the product owner and lead developer of Padloper. For those who may not know, I am the author and maintainer of several ProcessWire modules, both free and commercial. I am also a moderator in the ProcessWire forums. I would like to share with you a number of things regarding what’s going to happen next. This will be a long read. First, I would like to thank Antti for developing a great product. A lot of man-hours, dedication, passion and love has gone into making Padloper what it is today. Secondly, I would like to thank all users of Padloper. A great product is nothing without active users utilising it, putting it to the test, reporting bugs (even offering possible solutions) and proposing new features. So, thank you for helping make Padloper great! Support Thousands of hours have gone into developing Padloper. Although the code is well-written and easy to follow, Padloper is a big application with many moving parts. As such, it will take some time before I can fully grasp its inner workings. To make this transition as smooth as possible, Antti will help me with support for Padloper for some time. Currently, Padloper has a dedicated support forum. This is an arrangement between Ryan and Antti. The support forum works great as it allows the opening of multiple support threads to cover different issues. I have yet to speak to Ryan whether this arrangement can continue. However, given that I have other pro modules that I support in the open forums, it is unlikely that I will be requesting Ryan to let Padloper’s dedicated forum carry forth. A dedicated forum for one of my pro modules and open forums for my other pro modules will lead to confusion and questions from users of those other modules. Hence, Padloper support in the forums will move to the open forums. The disadvantage here is obviously the fact that support will be offered in one single (and maybe massive) support thread. To get around a ‘single thread support forum’, I am thinking of developing a simple online support queue system for all my modules. Meanwhile, support will continue in a new single thread and via email. Roadmap This list is neither exhaustive nor cast in stone. Its aim is to give an overview of my plans for Padloper. · Padloper 2 – a new major release · New backend for Padloper · Optional pro frontend module for Padloper · Documentation · New payment modules Let’s talk a bit about this list. Padloper 2 Release Padloper 2 will be a major release that incorporates a new, central backend shop for Padloper. This will be a new process module that pulls from the existing parts of Padloper (data models, etc) into one interface (more on this below). This version will also be extensible in the frontend, allowing for the plugging in of a new, optional, commercial frontend shop (full featured shop profile). Padloper 2 will not support the current ‘any page can be a product’ paradigm. Technically, products will still be pages. However, all products will utilise the same Padloper template. These will be invisible to the shop users themselves (e.g., hidden in admin tree). Only superusers will have full control of the Padloper system stuff. Support The current Padloper will continue to be supported until the new Padloper 2 is released. New features will be included in Padloper 2 only. Once Padloper 2 is released, legacy Padloper will only receive security fixes. All other support will cease. Upgrade There will be no upgrade path from the current Padloper to Padloper 2. Although their underlying architecture is the same, making sure that everything works in different setups and environments will be time consuming. However, for those who really need to migrate, if time allows and for an agreed fee, I could develop a custom script for the migration. Backend A new backend interface will be the major visual difference between the existing Padloper and Padloper 2. It goes beyond visual differences though. The new backend will be the single gateway for managing all shop-related features, both current and new ones. The backend will unify and include: · Easily add shop products. · Ability to add as little or as many custom fields to products as required (title, SKU, price, discount field, image/photo, description, categories, tags, etc). · Discounts manager (including auto start/expire discount codes). · Customers manager. · Invoices manager. · Taxes management. · Payment gateways manager. · Improved digital products management. · Stock management. · Manual order creation. · Graphical sales report. · Customer support. · Access-controlled shop editors/staff. · Dashboard for shop metrics. · Shop settings. · Product variations. · Import/export products as CSV or JSON. · Products search/filter. · Etc. Users will be able to turn off backend features that they do not need. This will enable a more streamlined experience for users. I plan to release Padloper 2 within 4 - 6 months, hopefully sooner. This is a major undertaking, hence the timescale. Please note that the first release of Padloper 2 will not include all of the above planned features. The idea is to build incrementally, adding new features in minor updates, focusing on stability, usability and security. Frontend Past requests have included the development of a full featured frontend shop. This is planned for Padloper 2. However, this will be an optional pro module priced separately from Padloper itself. The ability to build own frontend shops using Padloper API will still continue. For those who want a plug-n-play solution, this frontend shop will come in handy. The frontend shop profile will feature an ajax-powered shopping cart and a customisable ready-to-go theme. Pricing Model There are no plans to change the current prices of the 3 Padloper licences (Single, Developer and Agency). However, in order to continue to provide Padloper as a stable product with great features, it is also important that it remains a competitive and financially sustainable project. In order for this to happen and to also bring Padloper in line with my existing pro modules, the pricing model itself has to change. Starting from Padloper 2, the pricing model will shift to an ‘annual subscription’ model rather than the current ‘lifetime licence model’. I am fully aware that there are different opinions for and against annual subscriptions. However, I believe that this model is the most equitable approach that suits both the developer and the clients. The annual subscription will allow users (licence holders) to get 12 months of free VIP support for Padloper as well as future updates available within that time period. After the 12 months, users will be able to renew (online) their subscription at a discounted cost (worked as a fraction of the full purchase price) for a further 12 months (perpetually). Users will be able to continue to use Padloper for life even if they don’t renew their subscriptions. Upgrading current licences to Padloper 2 will be a paid upgrade. Current users of Padloper will get an attractive discount. This will be a time-limited offer (maybe a couple of months) that will start with the release of Padloper 2. New customers will pay the full price for Padloper 2. I hope the planned features are reason enough for you to consider upgrading to Padloper 2. Payment Modules I will be taking over as the maintainer and lead developer of the existing payment gateways (Payment base class, PayPal and Stripe). New payment modules are also planned. Payment modules will continue to be free. However, only ProcessWire 3+ support will be provided going forward. Padloper Domain and Future Downloads I have also taken charge of the Padloper domain. Within the next 12 months, purchase and download of Padloper will shift to processwireshop.pw. Please note that this is not the official shop for ProcessWire! It just bears a name that reflects its product offerings 😊. Eventually, traffic to padloper.pw will redirect to processwireshop.pw. Feedback I would love to hear your thoughts about the upcoming changes and any feature requests you might have for Padloper 2. Whilst I cannot guarantee that any request will be implemented, I can promise that I will thoughtfully consider all feedback. Thanks for reading and thank you for supporting Padloper! kongondo
  9. 35 points
    A module helping you to manage SEO related tasks like a boss! Automatically generates and maintains a XML sitemap from your pages. Includes a Fieldtype and Inputfield to manage sitemap settings and meta data for pages (Title, Description, Canonical URL, Opengraph, Twitter, Structured Data etc.) Multi language support for the sitemap and meta data. Configure default values for meta data on template level and let pages inherit or overwrite them individually. Map existing fields to meta data, reducing the need to duplicate content. Live preview for content editors how the entered meta data appears on Google. Live preview for content editors how the entered Opengraph data looks like when sharing a page with Facebook. Check out the README on GitHub for more details, including usage instructions. The module is currently released as beta and needs testing! Please report any issues on GitHub or in this forum thread, if you find time to give it a try 🙂 Examples Here is an example of rendered meta data you will get from a single SeoMaestro field: <title>Sed dictum eros quis massa semper rutrum. | acme.com</title> <meta name="description" content="Si lobortis singularis genitus ibidem saluto. Dolore ad nunc, mos accumsan paratus duis suscipit luptatum facilisis macto uxor iaceo quadrum. Demoveo, appellatio elit neque ad commodo ea. Wisi, iaceo, tincidunt at commoveo rusticus et, ludus."> <meta name="keywords" content="Foo,Bar"> <link rel="canonical" href="https://acme.com/en/about/"> <meta property="og:title" content="Sed dictum eros quis massa semper rutrum."> <meta property="og:description" content="Si lobortis singularis genitus ibidem saluto. Dolore ad nunc, mos accumsan paratus duis suscipit luptatum facilisis macto uxor iaceo quadrum. Demoveo, appellatio elit neque ad commodo ea. Wisi, iaceo, tincidunt at commoveo rusticus et, ludus."> <meta property="og:image" content="https://acme.com/site/assets/files/1001/og-image.jpg"> <meta property="og:image:type" content="image/jpg"> <meta property="og:image:width" content="1600"> <meta property="og:image:height" content="1200"> <meta property="og:image:alt" content="Lorem Ipsum"> <meta property="og:type" content="website"> <meta property="og:url" content="https://acme.com/en/about/"> <meta property="og:locale" content="en_EN"> <meta name="twitter:card" content="summary"> <meta name="twitter:creator" content="@schtifu"> <meta name="twitter:site" content="@schtifu"> <script type="application/ld+json"> { "@context": "https://schema.org", "@type": "BreadcrumbList", "itemListElement": [ { "@type": "ListItem", "position": 1, "name": "About", "item": "https://acme.com/en/about/" } ] } </script> <meta name="generator" content="ProcessWire"> <link rel="alternate" href="https://acme.com/en/about/" hreflang="en"> <link rel="alternate" href="https://acme.com/en/about/" hreflang="x-default"> <link rel="alternate" href="https://acme.com/de/ueber/" hreflang="de"> <link rel="alternate" href="https://acme.com/fi/tietoja/" hreflang="fi"> And some screenshots of the UI:
  10. 35 points
    Last week I worked primarily on GitHub issues, and did some of that this week as well. Likely I'll be doing a lot of this in October. Thank you for all of your reports. While there's already a lot of commits on the dev branch, I'm going to wait till next week to bump the version, as I've got some stuff in progress that I want to get committed first (more on that below). Next week I'm releasing version 40 of FormBuilder that supports paginated forms, as well as forms within forms (not to mention some other minor additions). Basically, all the stuff that was covered in this video from a few weeks ago, plus a little more. I actually think it's ready right now, but as is often the case, I started writing instructions for using the new features today and thought of a couple minor tweaks that would be helpful along the way. So I'm going to apply those early next week, finish the instructions, test it all out again, and then release it... likely mid-week next week. For the ProcessWire core, one feature people have been asking for for quite awhile is the ability to specify custom fields with file and image fields. I've been working on that here quite a bit this week, and have the initial test cases working quite nicely! Unlike the Description and Tags fields that come as built-in options with file and image fields, the new option instead uses a subset of ProcessWire's Fieldtype and Inputfield modules to support this (note: it does not use pages like repeaters do). This gives you more flexibility in defining what you want and how you want it to look. Though there are some limitations of what kinds of fields you can use here, but I think you will like what it offers and how it works. For those that just need a description and/or tags, then of course those features will remain as they are. But for those that need something more for file/image fields, you are going to have a whole lot of new options in 3.0.142. Unless I run into any roadblocks in finishing development of this part, I'll have it ready by this time next week along with a blog post that outlines it in more detail.
  11. 33 points
    Hope you guys are having a great week. I'll keep this week's update short since everything I'm working on is in-progress rather than ready to post. But I can tell you about a few things you'll likely see in next week's post: First is that I've got multi-page/paginated form support just about ready to release in FormBuilder. What this means is that you can take forms (especially long forms) and break them up into multiple paginations. This makes for multi-part forms that are more digestible and easy to use for users. The end of each pagination has "Next" and "Prev" buttons for navigation between them. FormBuilder validates each pagination independently as it is submitted so that any errors are taken care of as the user proceeds rather than all at the end. And these are true paginated forms, rather than a JS manipulation of existing forms. More on this next week. I'm also working here on a new Inputfield module called InputfieldToggle. It's an alternative to the core InputfieldCheckbox and the intention here is to make it a selectable alternative for FieldtypeCheckbox fields. Unlike InputfieldCheckbox, it is presented as two radio buttons for "on" and "off" states. (It's also possible to have a "no selection" state distinct from the "no" state, where supported). It comes predefined with several toggle types (Yes/No, On/Off, True/False, Enabled/Disabled), along with the ability to specify your own (multi-language too of course). Like a checkbox, because it is a toggle, it holds a value of either true (1) or false (0). There is also null for no selection. While this is a relatively simple Inputfield, it answers a common need (at least in my experience) and often can provide a better experience than a standard checkbox, depending on the input need. Not to mention, it's a lot more efficient than using an Options or Page field to accomplish the same thing. In addition to sites and apps running in ProcessWire, I think this particular Inputfield has a lot of potential use in the core and its administrative forms, so I might include it in the core, though not yet certain. I'm already using it quite a bit in forms I'm developing for clients in FormBuilder, where in many cases I find it a better fit than InputfieldCheckbox. Lastly, there are some nice UI enhancements just about ready for manipulating column widths of fields in ProcessWire. It makes it a much simpler and quicker job than it currently is, so I'll have more on that next week too. Have a great weekend!
  12. 33 points
    Just a quick update this week rather than a blog post. I’ve been continuing to work through the PW issues repo with Netcarver and it seems to be working well, so am planning to just keep working through it till we’ve covered everything there. Thanks to Netcarver and everyone else helping there. When we get the issues repo to the point where it’s pretty empty, I thought we’d then move on to the requests repo and PRs if possible. While there have been several commits to the core this week (mostly related to the issues repo), I don’t think there’s anything major enough to warrant a version bump, so will get another week’s worth of updates in place before bumping it to the next version number. This week I’ve been putting the finishing touches on the ProMailer module, getting that ready for release. A copy of ProMailer will be available to current subscribers of the ProDevTools package that want it. A few people have indicated that they’d also like to see it as a product independent of the ProDevTools, and actually I think that makes sense because ProMailer has become a much more comprehensive product than originally planned, and it really needs its own dedicated support board, as well as dedicated dev and agency versions. So I will make those available separately from ProDevTools. If you are a current ProDevTools subscriber and you’d like to get the first version of ProMailer when it is ready, please send me a PM here in the forums indicating that, and I will get a copy to you when it is released in beta. Even if you aren’t a ProDevTools subscriber, but would still like to be notified when ProMailer is available, please send me a PM as well. If all goes well, it should be available by this time next week or earlier. Next month we’ll hopefully be back to work on the website here as well, and develop the new modules directory.
  13. 33 points
    I would like to just show my appreciation to ProcessWire and all the guys that have put work in to make it what it is now. I have use many, many CMS's in my time. Statamic, Drupal, WordPress, ConcreteCMS, CraftCMS etc... And they all have their strengths and weaknesses. But I can honestly say, ProcessWire is by FAR the best Content Management System I've ever, EVER used. I can honestly say the only weakness ProcessWire is the lack on eCommerce. But, that isn't even a weakness of ProcessWire. The tools are there for us to create an eCommerce system. I'm a front-end developer but with ProcessWire it empowers me to realise anything. Honestly, when one of the designers asks "Can we do this?" it feels so great to say YES! I, with very little backend experience built a real-estate system that completely runs on ProcessWire pulling in from an external feed (Vebra) and I did it with ease! I just wanted to say thank you, thank you for creating a framework in which, people like myself, who love front-end but find back-end daunting can pick it up and literally do anything with EASE. ProcessWire gives me so much confidence and makes me feel so good about myself. I've recently been working on an WooCommerce website, and I can't tell you how much I've been missing ProcessWire. Thank you @ryan for making a system that is so simple, even simpletons like myself can dream big. Lots of love, Tom Edit: Interestingly I feel like it would be easier to build an eCommerce system using ProcessWire than it would trying to completely reskin WooCommerce, like seriously, WooCommerce stop injecting markup and putting them in core functions.
  14. 32 points
    We recently rebuilt the Architekturführer Köln (architectural guide Cologne) as a mobile-first JavaScript web app, powered by VueJS in the frontend and ProcessWire in the backend. Concept, design and implementation by schwarzdesign! The Architekturführer Köln is a guidebook and now a web application about architectural highlights in Cologne, Germany. It contains detailled information about around 100 objects (architectural landmarks) in Cologne. The web app offers multiple ways to search through all available objects, including: An interactive live map A list of object near the user's location Filtering based on architect, district and category Favourites saved by the user The frontend is written entirely in JavaScript, with the data coming from a ProcessWire-powered API-first backend. Frontend The app is built with the Vue framework and compiled with Webpack 4. As a learning exercise and for greater customizability we opted to not use Vue CLI, and instead wrote our own Webpack config with individually defined dependencies. The site is a SPA (Single Page Application), which means all internal links are intercepted by the Vue app and the corresponding routes (pages) are generated by the framework directly in the browser, using data retrieved from the API. It's also a PWA (Progressive Web App), the main feature of which is that you can install it to your home screen on your phone and launch it from there like a regular app. It also includes a service worker which catches requests to the API and returns cached responses when the network is not available. The Architekturführer is supposed to be taken with you on a walk through the city, and will keep working even if you are completely offline. Notable mentions from the tech stack: Vue Vue Router for the SPA functionality VueX for state management and storage / caching of the data returned through the API Leaflet (with Mapbox tiles) for the interactive maps Webpack 4 for compilation of the app into a single distributable Babel for transpilation of ES6+ SASS & PostCSS with Autoprefixer as a convenience for SASS in SFCs Google Workbox to generate the service worker instead of writing lots of boilerplate code Bootstrap 4 is barely used here, but we still included it's reboot and grid system Backend The ProcessWire backend is API-only, there are no server-side rendered templates, which means the only PHP template is the one used for the API. For this API, we used a single content type (template) with a couple of pre-defined endpoints (url segments); most importantly we built entdpoints to get a list of all objects (either including the full data, or only the data necessary to show teaser tiles), as well as individual objects and taxonomies. The API template which acts as a controller contains all the necessary switches and selectors to serve the correct response in <100 lines of code. Since we wanted some flexibility regarding the format in which different fields were transmitted over the api, we wrote a function to extract arbitrary page fields from ProcessWire pages and return them as serializable standard objects. There's also a function that takes a Pageimage object, creates multiple variants in different sizes and returns an object containing their base path and an array of variants (identified by their basename and width). We use that one to generate responsive images in the frontend. Check out the code for both functions in this gist. We used native ProcessWire data wherever possible, so as to not duplicate that work in the frontend app. For example: Page names from the backend translate to URLs in the frontend in the form of route parameters for the Vue Router Page IDs from ProcessWire are included in the API responses, we use those to identify objects across the app, for example to store the user's favourites, and as render keys for object lists Taxonomies have their own API endpoints, and objects contain their taxonomies only as IDs (in the same way ProcessWire uses Page References) Finally, the raw JSON data is cached using the cache API and this handy trick by @LostKobrakai to store raw JSON strings over the cache API. Screenshots
  15. 31 points
    Just a brief update today. I’m going to give it another week before bumping the core version, as I don’t think there’s enough changes yet to warrant a version bump. For whatever reason, several of my clients have needed integration with Stripe (payments) over the last few weeks. I’d not worked with it before the last month or so, but now all of the sudden am working with it a lot, because that's what my clients have asked for. I’ve found myself working on four different Stripe integrations on existing PW sites, both Stripe Elements and Stripe Checkout. None of these are for sites that have an actual “store” where they would need a cart, but rather just “pay for your reservation”, “buy this book”, “buy this song”, and “make a donation of $10”, “make a recurring donation”, type things. After doing a few of these, I thought it would make a lot of sense to have this built into FormBuilder, which would save us time on this stuff. So this week I built Stripe support into FormBuilder (using the Stripe Elements API). It’s already fully functional, so I will be releasing a new version of FormBuilder with this capability quite soon. To add a Stripe payment input to your form you just add a new field of type “Stripe payment for FormBuilder”, and then it asks you for some info about it (like amount to charge) and then your form works as a payment processor. Stripe has a clever way of making this all work, so that the user never leaves your site, but your site (and FormBuilder) never sees credit card numbers or anything like that, so it’s secure and you don’t have to consider things like PCI compliance. I've also got some other unrelated updates for FormBuilder that I'll be covering soon as well. Have a great weekend!
  16. 31 points
    This week I’m glad to report the development progress on the new ProcessWire.com website is ready for preview and I’ve placed it in a subdirectory for testing. You can find it here: https://processwire.com/newsite/ Of course, this is just version 1 of the new site, but it’s now got quite a bit more updated content than the existing site, so I don’t want to wait much longer to replace the existing site. I’m still working out a few small details, but it should be 99% functional. I expect to replace the existing main site early next week. If you have a chance to test it out, please let me know how if you come across anything that isn’t working or any browser/platform specific issues. Thanks for taking a look and testing it out. I’ll have more details next week, along with a new core version on the dev branch with several updates currently in progress. Have a great weekend!
  17. 30 points
    I've seen a couple of questions regarding namespaces and autoloading floating around the forum recently, so I decided to write a little tutorial. In general, I often see people getting confused when they try to wrap their head around namespaces, autoloading, Composer and the mapping of namespaces to directory structures all at once. In fact, those are very much independent, distinct concept, and it is much easier to explain and understand them separately. So this guide is structured as follows: How namespaces work in PHP. How autoloading works in PHP. Conventions for mapping namespaces to directory structures: PSR-4. How autoloading works in Composer and ProcessWire's class loader. How to use the class loader in a ProcessWire module. Feel free to skip the sections you're already familiar with. Namespaces in PHP The purpose of namespaces in PHP is to avoid naming conflicts between classes, functions and constants, especially when you're using external libraries and frameworks. Nothing more. It's important to understand that this has nothing at all to do with autoloading, directory structures or file names. You can put namespaced stuff everywhere you want. You can even have multiple namespaces inside a single file (don't try this at home). Namespaces only exist to be able to use a generic name – for example, ProcessWire's Config class – multiple times in different contexts without getting a naming conflict. Without namespaces, I couldn't use any library that includes a Config class of it's own, because that name is already taken. With namespaces, you can have a distinction between the classes ProcessWire\Config and MoritzLost\Config. You can also use sub-namespaces to further segregate your code into logical groups. For example, I can have two classes MoritzLost\Frontend\Config and MoritzLost\Backend\Config– a class name only needs to be unique within it's namespace. You can declare the namespace for a PHP file using the namespace statement at the top: // file-one.php <?php namespace ProcessWire; // file-two.php <?php namespace MoritzLost\Frontend; This way, all classes, methods and constants defined inside this file are placed in that namespace. All ProcessWire classes live in the ProcessWire namespace. Now to use one of those classes – for example, to instantiate it – you have a couple of options. You can either use it's fully qualified class name or import it into the current namespace. Also, if you are inside a namespaced file, any reference to a class is relative to that namespace. Unless it starts with a backward slash, in this case it's relative to the global namespace. So all of those examples are equivalent: // example-one.php <?php namespace ProcessWire; $page = new Page(); // example-two.php <?php use ProcessWire\Page; $page = new Page(); // example-three.php <?php $page = new ProcessWire\Page(); // example-four.php <?php namespace MoritzLost\Somewhere\Over\The\Rainbow; $page = new \ProcessWire\Page(); The use statement in the second example can be read like this: “Inside this file, all references to Page refer to the class \ProcessWire\Page” How autoloading works Every PHP program starts with one entry file – for ProcessWire, that's usually it's index.php. But you don't want to keep all your code in one file, that would get out of hand quickly. Once you start to split your code into several individual files however, you have to take care of manually including them with require or include calls. That becomes very tedious as well. The purpose of autoloading is to be able to add new code in new files without having to import them manually. This, again, has nothing to do with namespaces, not even something with file locations. Autoloading is a pretty simple concept: If you try to use a class that hasn't been loaded yet, PHP calls upon it's registered autoloaders as a last-ditch attempt to load them before throwing an exception. Let's look at a simple example: // classes.php <?php class A { /** class stuff */ } class B { /** class stuff */ } // index.php <?php spl_autoload_register(function ($class) { include_once 'classes.php'; }); new A(); new B(); This is a complete and functional autoloader. If you don't believe me, go ahead and save those two files (classes.php and index.php) and run the index.php with php -f index.php. Then comment out the include_once call and run it again, then you'll get an error that class A was not found. Now here's what happens when index.php is executed (with the autoloader active): Our anonymous function is added to the autoload queue through spl_autoload_register. PHP tries to instantiate class A, but can't because it's not loaded yet. If there was no autoloader registered, the program would die with a fatal error at this point. But since there is an autoloader ... The autoloader is called. Our autoloader includes classes.php with the class definition. That was a close one! Since the class has been loaded, execution goes back to the index.php which can now proceed to instantiate A and B. If the class was still not loaded at this point, PHP would go back to the original plan and die. One thing to note is that the autoloader will only be called once in this example. That's because both A and B are in the same file and that file is included during the first call to the autoloader. Autoloading works on files, not on classes! The important takeaway is that PHP doesn't know if the autoloader knows where to find the class it asks for or, if there are multiple autoloader, which one can load it. PHP just calls each registered autoloader in turn and checks if the class has been loaded after each one. If the class still isn't loaded after the last autoloader is done, it's error time. What the autoloader actually does is pretty much wild wild west as well. It takes the name of the class PHP is trying to load as an argument, but it doesn't have to do anything with it. Our autoloader ignores it entirely. Instead, it just includes classes.php and says to itself “My job here is done”. If class A was in another file, it wouldn't have worked. This process has two main advantages: Since autoloaders are only called on-demand to load classes just in time, we only include the files we actually need. If in the example above class A and B are not used in some scenarios, the classes.php will not be included, which will result in better performance for larger projects (though this isn't as cut and dry, since autoloading has it's own overhead, so if you load most classes anyway during a single request, it will actually be less efficient). If the autoloader is smart enough to somehow map class names to the files they're located in, we can just let the autoloader handle including the classes we need, without having to worry about jamming include statements everywhere. That brings us to ... PSR-4, namespaces and directory structures As you see, namespaces and autoloading are both pretty limited concepts. And they aren't inherently linked to each other. You can namespace your classes without ever adding an autoloader, and you can autoload classes that are all in the same namespace. But they become useful when you put them together. At the core of all that autoloading talk is a simple idea: By putting classes in files named after their class names, and putting those files in directory hierarchies based on the namespace hierarchy, the autoloader can efficiently find and load those files based on the namespace. All it needs is a list of root namespaces with their corresponding directories. The exact way class names and namespaces are mapped to directory structures and file names is purely conventional. The accepted convention for this is PSR-4. This is a super simple standard which basically just sums up the ideas above: A base namespace is mapped to a specific directory in the file system. When the autoloader is asked to load a class in that namespace (or a sub-namespace of it), it starts looking in that folder. This "base" namespace may include multiple parts – for example, I could use MoritzLost\MyAwesomeLibrary as a base and map that to my source directory. PSR-4 calls this a "namespace prefix". Each sub-namespace corresponds to a sub-directory. So by looking at the namespace, you can follow subdirectories to the location where you expect to find the class file. Finally, the class name is mapped directly to the file name. So MyCoolClass needs to be put inside MyCoolClass.php. This all sounds simple and straightforward - and it absolutely is! It's only once you mash everything together, mix up language features, accepted conventions and proprietary implementations like Composer on top that it becomes hard to grasp in one go. Composer and ProcessWire's class loader Now all that's left is to talk about how Composer and ProcessWire provide autoloading. Composer, of course, is primarily a tool for dependency management. But because most libraries use namespaces and most developers want to have the libraries they're using autoloaded, those topics become a prerequisite to understanding what Composer does in this regard. Composer can use different autoloading mechanisms; for example, you can just give it a static list of files to include for every request, or use the older PSR-0 standard. But most modern libraries use PSR-4 to autoload classes. So all Composer needs to function is a mapping of namespace prefixes to directories. Each library maintains this mapping for it's PSR-4-structured classes through the autoload information in their composer.json. You can do this for your own site to: Just include the autoload information as shown in the documentation and point it to the directory of your class files. Composer collects all that information and uses it to generate a custom file at vendor/autoload.php — that's the one you need to include somewhere whenever you set up Composer in one of your projects. Bells and whistles aside, this file just registers an autoloader function that will use all the information collected from your own and your included libraries' composer.json to locate and include class files on demand. You can read more about how to optimize Composer's autoloader for production usage here. If you want to read up on how to set up Composer for your own sites, read my ProcessWire + Composer integration guide instead. And finally, what does ProcessWire do to handle all this? Turns out, ProcessWire has it's own autoloader implementation that is more or less PSR-4 compliant. You can access it as an API variable ($classLoader or wire('classLoader'), depending on context). Instead of using a static configuration file like Composer, the namespace -> directory mapping is added during the runtime by calling $classLoader->addNamespace. As you would expect, this function accepts a namespace and a directory path. You can use this to register your own custom namespaces. Alternatively, if you have site-specific classes within the ProcessWire namespace, you can just add their location to the class loader using the same method: $classLoader->addNamespace('ProcessWire', '/path/to/your/classes/'). Utilizing custom namespaces and autoloading in ProcessWire modules Now as a final remark, I wanted to give an example of how to use custom namespaces and the class loader in your own modules. I'll use my TrelloWire module as an example: Decide what namespace you're going to use. The main module file should live in the ProcessWire namespace, but if you have other classes in your module, they can and should use a custom namespace to avoid collisions with other modules. TrelloWire uses ProcessWire\TrelloWire, but you can also use something outside the ProcessWire namespace. You need to make sure to add the namespace to the class loader as early as possible. If either you or a user of your module tries to instantiate one of your custom classes before that, it will fail. Good places to start are the constructor of your main module file, or their init or ready methods. Here's a complete example. The module uses only one custom namespaced class: ProcessWire\TrelloWire\TrelloWireApi, located in the src/ directory of the module. But with this setup, I can add more classes whenever I need without having to modify anything else. /** * The constructor registers the TrelloWire namespace used by this module. */ public function __construct() { $namespace = 'ProcessWire\\TrelloWire'; $classLoader = $this->wire('classLoader'); if (!$classLoader->hasNamespace($namespace)) { $srcPath = $this->wire('config')->paths->get($this) . 'src/'; $classLoader->addNamespace($namespace, $srcPath); } } Source Thanks for making it through to the very end! I gotta learn to keep those things short. Anyway, I hope this clears up some questions about namespaces and autoloading. Let me know if I got something wrong, and feel free to add your own tips and tricks!
  18. 30 points
    https://gitlab.com/baumrock/RockForms It uses the great NetteForms from Nette Framework (docs: https://doc.nette.org/en/2.4/forms ) Features: Client AND Server-side validation in one go (you only need to code your rules ONCE) CSRF protection (by processwire) Honepot spam protection (custom) Helper to create PW pages from submitted forms ($form->createPage($parent, $template, $title)) Add ?success=yourform tag to url ONLY after successful submission (for analytics) Recover fields after unsuccessful submission (server side validation error) Define custom actions + message on successful submission UiKit form renderer (more can be accepted by pull requests) Sample Form Setup: <?php namespace ProcessWire; $form = $modules->get('RockForms')->form; $form->addRadioList('salut', 'Anrede', ['m' => ' Herr', 'w' => ' Frau']); $form->addText('forename', 'Vorname'); $form->addText('surname', 'Nachname'); $form->addText('email', 'E-Mail-Adresse') ->setRequired('Bitte geben Sie Ihre Mailadresse an') ->addRule(Form::EMAIL) ; $form->addSubmit('submit', 'Anfrage senden'); $form->onSuccess = function($form) { $form->createPage(1017, 'mailitem', date('d.m.Y H:i:s') . ', {forename} {surname} {email}'); // send email // do whatever you want // return success message return 'thank you for your subscription'; }; echo $form->render(); For all available fields you can look here: https://doc.nette.org/en/2.4/form-fields Validation: https://doc.nette.org/en/2.4/form-validation Rendering: https://doc.nette.org/en/2.4/form-rendering More complex form example of the screencast: Module is alpha and not well tested yet. It should be save to use, but there might be breaking changes in the future. Also I'm quite sure that not all possible situations are covered. There are some switch() statements that check for the fieldtype and I only implemented the ones I needed so far. All others are easy to add - please make pull requests if you find any unsupported fields. Thank you. LIMITATIONS: Multiform support limited Changelog: 6.8.18 add multiform support 8.4.18 v2 little bugfix + load assets automatically 19.3.18 alpha release
  19. 30 points
    If you're looking to do an elaborate a page builder with ProcessWire and don't want to pull your hair out, I highly recommended viewing this video: A couple notes: with the css grid specification, you can assign multiple blocks to the same grid-area but they will overlap each other. I've "overcome" this by combining multiple blocks into a parent div and assigning that instead. pretty easy to do. i didn't demonstrate it, if your blocks have a grid structure within them (like built with flexbox), you can still assign that block to a grid-area. so if your blocks themselves have a grid structure, that's ok. for example, if your css grid layout is 6 columns, but you have a block that has a grid inside of it (built with like uikit's grid that's 5 columns), you can assign that block to the grid-area. with the css grid specification, the flow of the blocks does not have to match the flow of the grid-areas. this is insanely powerful. Enjoy.
  20. 29 points
    Modules Manager 2 provides an easy to use interface to download, update, install, uninstall and configure modules. It is meant to provide an optimized alternative to the core ProcessModule dashboard. Maybe @ryan agrees to merge it to the core at some point when it is finished and polished. Features: Seamlessly download, update, install, uninstall or delete modules Live-Search (aka find as you type) for module names Live-Search (aka find as you type) for categories Browse new and unkown modules from the modules directory on modules.processwire.com Choose your favorite layout (cards, reduced cards, table) Modern UIKit design (therefore only works with AdminThemeUikit) Caches the module list from modules.processwire.com directory locally. What is Modules Manager 2? Why a new module manager? Some people including myself think that the actual module installation in ProcessWire could be improved in some places. Make it easy for ProcessWire beginners and power users Offer better discoverbility to find the right module Make it easier and faster for powerusers to manage modules A manager that list all official modules is a feature, that many other frameworks/CMS's like ModX, WordPress or PrestaShop have by default. What are the disadvantages of the actual core module interface? Installation of a module is not very user-friendly: You have to be aware where to get new modules, search for a module, copy or remember the module name or URL, go back to your ProcessWire installation, paste the module name(URL, click on "get module info" and finally install the module It only displays installed modules, not the ones that are available in the modules directory Uninstalling a module requires you to go to the module detail page, click a checkbox and then submit the change. After that you have to go back to the module overview page. It only displays installed modules, not the ones that are available in the modules directory, so it makes discovering modules hard BETA software Use this module at your own risk. I am not responsible for any damage or unexpected behaviour. Some things might not work fully, please see the TODO list for details. I need your feedback and help This module is still in development and I am happy to discuss with you and get some feedback. What do you like? What is missing? What could make the process even easier? Ask, suggest or provide pull requests. You can download the module at https://modules.processwire.com/modules/modules-manager2/ or from Github: https://github.com/jmartsch/processwire-modules-manager2
  21. 28 points
    --- Please use RockFinder3 ---
  22. 28 points
    Good Morning ProcessWIre Community, PW Review is a website that has a lofty goal of covering ProcessWire on a regular basis. That may seem like an impossible task, however I believe I'm up to the challenge. First, this is a strictly non-commercial endeavor and a project I believe in. This is not Wired Magazine or anything like that. I'm not a serious programmer or pretending to be one. My goal is to cover the modules (commercial and non-commercial) that may not get that much press or attention. I will also be covering modules that maybe you haven't heard about in awhile. There will also be screenshots, information and videos regarding the Commercial modules. I've been with this community since 2012 and have benefitted tremendously from ProcessWire. So this is my way of giving back, which is important to me. It's my hope that over time that what I'm doing myself will get some community participation. One person that I've had nothing but positive support from is Ryan Cramer. That's enough to keep me going at this for some time. That's it. Have a nice day and I hope you find something to like with PW Review. If not, please send me an email. I'm a great listener. Best Regards, Charles
  23. 27 points
    SnipWire - Snipcart integration for ProcessWire Snipcart is a powerful 3rd party, developer-first HTML/JavaScript shopping cart platform. SnipWire is the missing link between Snipcart and the content management framework ProcessWire. With SnipWire, you can quickly turn any ProcessWire site into a Snipcart online shop. The SnipWire plugin helps you to get your store up and running in no time. Detailed knowledge of the Snipcart system is not required. SnipWire is free and open source licensed under Mozilla Public License 2.0! A lot of work and effort has gone into development. It would be nice if you could donate an amount to support further development: Status update links (inside this thread) for SnipWire development 2020-04-06 -- SnipWire 0.8.6 (beta) released! Adds support for Snipcart subscriptions and also fixes some problems 2020-03-21 -- SnipWire 0.8.5 (beta) released! Improves SnipWires webhooks interface and provides some other fixes and additions 2020-03-03 -- SnipWire 0.8.4 (beta) released! Improves compatibility for Windows based Systems. 2020-03-01 -- SnipWire 0.8.3 (beta) released! The installation and uninstallation process has been heavily revised. 2020-02-08 -- SnipWire 0.8.2 (beta) released! Added a feature to change the cart and catalogue currency by GET, POST or SESSION param 2020-02-03 -- SnipWire 0.8.1 (beta) released! All custom classes moved into their own namespaces. 2020-02-01 -- SnipWire is now available via ProcessWire's module directory! 2020-01-30 -- SnipWire 0.8.0 (beta) first public release! (module just submitted to the PW modules directory) 2020-01-28 -- added Custom Order Fields feature (first SnipWire release version is near!) 2020-01-21 -- Snipcart v3 - when will the new cart system be implemented? 2020-01-19 -- integrated taxes provider finished (+ very flexible shipping taxes handling) 2020-01-14 -- new date range picker, discount editor, order notifiactions, order statuses, and more ... 2019-11-15 -- orders filter, order details, download + resend invoices, refunds 2019-10-18 -- list filters, REST API improvements, new docs platform, and more ... 2019-08-08 -- dashboard interface, currency selector, managing Orders, Customers and Products, Added a WireTabs, refinded caching behavior 2019-06-15 -- taxes provider, shop templates update, multiCURL implementation, and more ... 2019-06-02 -- FieldtypeSnipWireTaxSelector 2019-05-25 -- SnipWire will be free and open source Plugin Key Features Fast and simple store setup Full integration of the Snipcart dashboard into the ProcessWire backend (no need to leave the ProcessWire admin area) Browse and manage orders, customers, discounts, abandoned carts, and more Multi currency support Custom order and cart fields Process refunds and send customer notifications from within the ProcessWire backend Process Abandoned Carts + sending messages to customers from within the ProcessWire backend Complete Snipcart webhooks integration (all events are hookable via ProcessWire hooks) Integrated taxes provider (which is more flexible then Snipcart own provider) Useful Links SnipWire in PW modules directory SnipWire Docs (please note that the documentation is a work in progress) SnipWire @GitHub (feature requests and suggestions for improvement are welcome - I also accept pull requests) Snipcart Website ---- INITIAL POST FROM 2019-05-25 ----
  24. 27 points
    This week I was back to focusing on the core and got quite a lot done. A lot of GitHub issue reports were resolved, plus several minor tweaks and additions were made in 3.0.156 as well. But the biggest update was the addition of the $pages->parents() API, which is something that I think you’ll likely have zero use for (and why I’m not putting it into a blog post) but something that the core itself will use quite a bit, and is a really nice improvement for the system and its scalability. So if you don’t mind some technical reading, read on. Whenever you call a $page->find() method ($page, not $pages) or use a “has_parent=“ in a selector, ProcessWire joins in a special table for the purpose called pages_parents. It uses this table to keep track of family relationships that aren’t otherwise apparent. For instance, let’s say we have page “g” that lives at path /a/b/c/d/e/f/g/. Page “g” only knows that it has page “f” as its parent. It doesn’t know that page “e” is its grandparent unless or until page “f” is loaded. Once “f” is loaded, then “f” can reveal its parent “e”. It works the same for every relationship down to the root parent “a”. So the pages are like a linked list or blockchain of sorts, where only 1 relationship forward or backward is known per page. The “pages_parents” table fills in this gap, enabling PW to quickly identify these relationships without having to load all the pages in the family. This is particularly useful in performing find() operations that you want to limit to a branch started by a particular parent. It’s the reason why we have both $pages->find() that searches the entire site, and $page->find() that limits the search within the branch started by $page. I haven’t paid much attention to the code behind this pages_parents table because it generally just worked, needing little attention. But I came across a couple of cases where the data in the table wasn’t fully accurate with the page tree, without a clear reason why. Then I became aware of one large scale case from a PW user where it was a huge bottleneck. It involved a large site (250k+ pages) and a recursive clone operation that appeared to involve hundreds of pages. But that operation was taking an unreasonable 10 minutes, so something wasn’t right. It came down to something going on with the pages_parents table. Once I dove into trying to figure out what was going on, I realized that if I was to have any chance of keeping track of it, we needed a dedicated API for managing these relationships and the table that keeps track of them. So that’s what got a lot of attention this week. While still testing here, it does appear initially that the 10 minute clone time has gone down to a few seconds, and everything about this relationship management is now rewritten, optimized and significantly improved. It was a lot of work, but absolutely worth it for PW. Rebuilding the entire table from scratch now takes between 2-3 seconds on a site with 250k pages and 150k relationships. The new API can be accessed from $pages->parents(). This API is really useful to the work that I do here (maintaining the core) but I’ll be honest, it’s probably not useful to most others, so I won’t go into the details here, other than to say I’m happy with it. But if you are interested, there are methods finding all the parents in a site, or a particular branch, and methods for rebuilding the pages_parents table, among others. Maybe more will be added to it later that actually would be useful in the public API, but for now I’ll likely leave it out of our public API docs. The $sanitizer->selectorValue() method also got a full rewrite this week (actually, one the last few weeks). It’s now quite a bit more comprehensive and configurable (see the new method options). The previous version was just fine, and actually still remains — you can use it by specifying [ ‘version’ => 1 ] in the $options argument to the selectorValue() method. But the new version is coded better and covers more edge cases, plus provides a lot more configurability for the times when you need it.
  25. 27 points
    We’ve got several updates on the dev branch this week, but I want to finish one more of them before bumping the version to 3.0.150, so will likely do that next week. The biggest change this week is the addition of a new core class called FieldsTableTools. This will be used internally by the $fields API variable for manipulating field table schema in the database, and its methods are accessed from $fields->tableTools(); Though this is one you probably won't be using from the API unless developing Fieldtype modules, so if you just want to know what the benefits are, feel free to skip to the last two paragraphs. Initially these methods are primarily focused on managing unique indexes for fields, though will expand to manage other schema manipulations as well. An example of its utility is also included in this week’s commits—our email fields (FieldtypeEmail) now have the ability to enforce uniqueness at the DB level. If you edit an email field (Setup > Fields > email) and click on the Advanced tab, there’s now a checkbox there to enforce unique values, ensuring that a given email address cannot appear more than once (i.e. not appear on more than one page). The same ability will be added to text and integer fields (FieldtypeText and FieldtypeInteger) as well, but we’re starting with the email field because it’s needed for an update hopefully wrapping up next week: the optional ability to login to the admin with your email address. Having a unique index on a DB column is actually a pretty simple thing, but as it turns out, it takes a lot of code to support the ability in an existing installation. That’s because we have it as something you can toggle on and off (on that Advanced tab), and when you toggle ON a unique index, there can’t be any duplicate values in the existing data, or the index will fail to apply. So there’s a lot of supporting code in FieldsTableTools to do things like detect and warn about duplicate values, delete empty values before adding the index, identify when the index is present without querying the table, reporting error conditions in a manner that understandable and recoverable, as well as the actual schema manipulations that add or remove the index. I realize this sounds a bit technical (and that's partly why I'm not putting this in a more formal blog post), but I think most developers will at some point find it very useful in building sites and applications. Not only will it enable us to safely support login-by-email in the admin (coming next), but it’ll be useful in any situation where you need to prevent a value from repeating. Whether that is in preventing double bookings for a date, location, seat, etc., or preventing any kind of redundancy like post titles, author names, product titles, phone numbers, or codes (UPC, ISBN, ASINs, EIN, SSN, etc.), this feature can come in handy. And supporting it at the DB level is a lot more solid than supporting it at the code level. Right now it’s just supported in email fields, but all of the logic has been delegated to the newly added class so that we can easily support it in any other fields (with text and integer fields coming next). Following that, the $fields->tableTools(); will also be gaining methods for modifying other types of field schema. For instance, rather than just supporting the INT column type for integer fields, wouldn't it be nice to go to Setup > Fields > [some integer field] and select both unsigned and signed integers of different types: TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT, for any new or existing integer field? MySQL also offers a similar array of size variations for other types that would be useful in our text and textarea fields, among others. So you'll be continuing to see ProcessWire offer more options for existing FIeldtypes in future core versions, enabling you to more efficiently store and manage content in PW. But of course we'll do it in a way that keeps it simple, ensuring that you don't have to think about these things unless/until you want or need them.
  26. 27 points
    This week we’ve got version 3.0.147 out on the dev branch. Relative to version 3.0.146, most of the new commits (about 13 of them) are focused on resolving reports submitted at GitHub. I love refactoring existing code and adding optimizations and improvements to the core (and then writing about them in the blog). But right now I’m trying really hard not to! I’d like to have a new master version out before the new year, so the focus is on making sure the core is as absolutely stable as possible. Any time I refactor or add something new (or even sometimes when fixing something or another), there’s a chance of introducing new bugs, and it needs thorough testing on the dev branch, so right now the goal is that everything is thoroughly tested and stable before merging to the master branch. As a result, I’m trying to keep my hands off the core as much as possible, other than fixing obvious things that aren’t likely to introduce new code that needs testing. Please consider 3.0.147 release candidate 1 (RC1) for the next master. Thanks for all of your help and testing. Hopefully by (or before) 3.0.150, we’ll be ready for a merge to master. One way I try and take a break from modifying too much in the core before a master version release is to focus on other modules instead. That’s why last week I wrote about the new UserActivity module, and why next week I’ll be posting all the details for a new LoginRegisterPro module — one that I’ve been working on-and-off for more than a year, but have recently given it a lot of attention in getting it ready for release. I’ll save most of the details on LoginRegisterPro for next week, except to say that it provides an all-in-one solution for front-end login, account registration, profile editing and more. You might be wondering how that’s different from the LoginRegister module I built and released awhile back. That LoginRegister module was built for a very specific purpose and client, largely as a proof-of-concept. But there was a lot more interest in it than I ever expected, and several people suggested that there was a need that would be better served by the quality and support of a Pro module. The result is LoginRegisterPro, which is a full reimagining of that from the ground up. It does everything LoginRegister didn’t, in addition to everything it did. It goes much further in terms of security, reliability and customizability, and I look forward to telling you more about it. I may have it ready to release as soon as next week, but just wanted to make sure all the documentation was complete (and there is quite a lot of it so far). A couple other things I’m looking forward to working on here in the next month or so are the 2020 core roadmap and [finally] the new modules.processwire.com site. Thanks for reading and have a great weekend!
  27. 27 points
    This version on the dev branch contains 26 commits (relative to 3.0.142) and is focused primarily in resolving reported issues, and we managed to cover 18 of them in this version. Thanks for the reports and help in our GitHub issues repo. This version represents about 2 weeks of work, and ProcessWire Weekly #284 has good coverage of those that occurred last week. More details about this week's updates can be also be found in the dev branch commit log. There are also some other minor additions and improvements in 3.0.143 as well. My favorite are the improvements to our logs system. It now collapses identical log entries that occur near each other. That means a single recurring log entry (like an error message) won't repeat indefinitely in the log and take up a lot of space. Now it just adds a counter to one log entry and updates the timestamp, rather than duplicating the entire log entry... Much more efficient. When you view a log in Setup > Logs, it identifies these collapsed log entries for you. In addition, the output in the "errors" and "exceptions" logs now have improved readability, isolating error messages and filenames from stack traces. Lastly, the ajax navigation in Setup > Logs now shows logs in newest-to-oldest (modification date) rather than alphabetical, which I find a lot more useful. The log at the top of the list is always the one most recently updated. For core updates in coming weeks, I'm primarily focused on preparing the current dev branch to merge to the master branch, as it's been awhile since the last merge and the master branch is itching for a new version. Most of you reading this already run on the dev branch, but there are many out there that also stick to the master branch, and with all the new stuff on the dev branch, I'd like to get our master up-to-date with this as well. Thanks for reading, have a great weekend!
  28. 27 points
    This week we’ll take a look at a new version of FormBuilder that's on the way (with a screencast), as well as the latest version of the core: ProcessWire 3.0.140— https://processwire.com/blog/posts/pw-3.0.140-and-formbuilder-v40/
  29. 27 points
    Page Query Boss Build complex nested queries containing multiple fields and pages and return an array or JSON. This is useful to fetch data for SPA and PWA. You can use the Module to transform a ProcessWire Page or PageArray – even RepeaterMatrixPageArrays – into an array or JSON. Queries can be nested and contain closures as callback functions. Some field-types are transformed automatically, like Pageimages or MapMarker. Installation Via ProcessWire Backend It is recommended to install the Module via the ProcessWire admin "Modules" > "Site" > "Add New" > "Add Module from Directory" using the PageQueryBoss class name. Manually Download the files from Github or the ProcessWire repository: https://modules.processwire.com/modules/page-query-builder/ Copy all of the files for this module into /site/modules/PageQueryBoss/ Go to “Modules > Refresh” in your admin, and then click “install” for the this module. Module Methods There are two main methods: Return query as JSON $page->pageQueryJson($query); Return query as Array $page->pageQueryArray($query); Building the query The query can contain key and value pairs, or only keys. It can be nested and contain closures for dynamic values. To illustrate a short example: // simple query: $query = [ 'height', 'floors', ]; $pages->find('template=skyscraper')->pageQueryJson($query); Queries can be nested, contain page names, template names or contain functions and ProcessWire selectors: // simple query: $query = [ 'height', 'floors', 'images', // < some fileds contain default sub-queries to return data 'files' => [ // but you can also overrdide these defaults: 'filename' 'ext', 'url', ], // Assuming there are child pages with the architec template, or a // field name with a page relation to architects 'architect' => [ // sub-query 'name', 'email' ], // queries can contain closure functions that return dynamic content 'querytime' => function($parent){ return "Query for $parent->title was built ".time(); } ]; $pages->find('template=skyscraper')->pageQueryJson($query); Keys: A single fieldname; height or floors or architects The Module can handle the following fields: Strings, Dates, Integer… any default one-dimensional value Page references Pageimages Pagefiles PageArray MapMarker FieldtypeFunctional A template name; skyscraper or city Name of a child page (page.child.name=pagename); my-page-name A ProcessWire selector; template=building, floors>=25 A new name for the returned index passed by a # delimiter: // the field skyscraper will be renamed to "building": $query = ["skyscraper`#building`"] Key value pars: Any of the keys above (1-5) with an new nested sub-query array: $query = [ 'skyscraper' => [ 'height', 'floors' ], 'architect' => [ 'title', 'email' ], ] A named key and a closure function to process and return a query. The closure gets the parent object as argument: $query = [ 'architecs' => function($parent) { $architects = $parent->find('template=architect'); return $architects->arrayQuery(['name', 'email']); // or return $architects->explode('name, email'); } ] Real life example: $query = [ 'title', 'subtitle', // naming the key invitation 'template=Invitation, limit=1#invitation' => [ 'title', 'subtitle', 'body', ], // returns global speakers and local ones... 'speakers' => function($page){ $speakers = $page->speaker_relation; $speakers = $speakers->prepend(wire('pages')->find('template=Speaker, global=1, sort=-id')); // build a query of the speakers with return $speakers->arrayQuery([ 'title#name', // rename title field to name 'subtitle#ministry', // rename subtitle field to ministry 'links' => [ 'linklabel#label', // rename linklabel field to minlabelistry 'link' ], ]); }, 'Program' => [ // Child Pages with template=Program 'title', 'summary', 'start' => function($parent){ // calculate the startdate from timetables return $parent->children->first->date; }, 'end' => function($parent){ // calculate the endate from timetables return $parent->children->last->date; }, 'Timetable' => [ 'date', // date 'timetable#entry'=> [ 'time#start', // time 'time_until#end', // time 'subtitle#description', // entry title ], ], ], // ProcessWire selector, selecting children > name result "location" 'template=Location, limit=1#location' => [ 'title#city', // summary title field to city 'body', 'country', 'venue', 'summary#address', // rename summary field to address 'link#tickets', // rename ticket link 'map', // Mapmarker field, automatically transformed 'images', 'infos#categories' => [ // repeater matrix! > rename to categories 'title#name', // rename title field to name 'entries' => [ // nested repeater matrix! 'title', 'body' ] ], ], ]; if ($input->urlSegment1 === 'json') { header('Content-type: application/json'); echo $page->pageQueryJson($query); exit(); } Module default settings The modules settings are public. They can be directly modified, for example: $modules->get('PageQueryBoss')->debug = true; $modules->get('PageQueryBoss')->defaults = []; // reset all defaults Default queries for fields: Some field-types or templates come with default selectors, like Pageimages etc. These are the default queries: // Access and modify default queries: $modules->get('PageQueryBoss')->defaults['queries'] … public $defaults = [ 'queries' => [ 'Pageimages' => [ 'basename', 'url', 'httpUrl', 'description', 'ext', 'focus', ], 'Pagefiles' => [ 'basename', 'url', 'httpUrl', 'description', 'ext', 'filesize', 'filesizeStr', 'hash', ], 'MapMarker' => [ 'lat', 'lng', 'zoom', 'address', ], 'User' => [ 'name', 'email', ], ], ]; These defaults will only be used if there is no nested sub-query for the respective type. If you query a field with complex data and do not provide a sub-query, it will be transformed accordingly: $page->pageQueryArry(['images']); // returns something like this 'images' => [ 'basename', 'url', 'httpUrl', 'description', 'ext', 'focus'=> [ 'top', 'left', 'zoom', 'default', 'str', ] ]; You can always provide your own sub-query, so the defaults will not be used: $page->pageQueryArry([ 'images' => [ 'filename', 'description' ], ]); Overriding default queries: You can also override the defaults, for example $modules->get('PageQueryBoss')->defaults['queries']['Pageimages'] = [ 'basename', 'url', 'description', ]; Index of nested elements The index for nested elements can be adjusted. This is also done with defaults. There are 3 possibilities: Nested by name (default) Nested by ID Nested by numerical index Named index (default): This is the default setting. If you have a field that contains sub-items, the name will be the key in the results: // example $pagesByName = [ 'page-1-name' => [ 'title' => "Page one title", 'name' => 'page-1-name', ], 'page-2-name' => [ 'title' => "Page two title", 'name' => 'page-2-name', ] ] ID based index: If an object is listed in $defaults['index-id'] the id will be the key in the results. Currently, no items are listed as defaults for id-based index: // Set pages to get ID based index: $modules->get('PageQueryBoss')->defaults['index-id']['Page']; // Example return array: $pagesById = [ 123 => [ 'title' => "Page one title", 'name' => 123, ], 124 => [ 'title' => "Page two title", 'name' => 124, ] ] Number based index By default, a couple of fields are transformed automatically to contain numbered indexes: // objects or template names that should use numerical indexes for children instead of names $defaults['index-n'] => [ 'Pageimage', 'Pagefile', 'RepeaterMatrixPage', ]; // example $images = [ 0 => [ 'filename' => "image1.jpg", ], 1 => [ 'filename' => "image2.jpg", ] ] Tipp: When you remove the key 'Pageimage' from $defaults['index-n'], the index will again be name-based. Help-fill closures & tipps: These are few helpfill closure functions you might want to use or could help as a starting point for your own (let me know if you have your own): Get an overview of languages: $query = ['languages' => function($page){ $ar = []; $l=0; foreach (wire('languages') as $language) { // build the json url with segment 1 $ar[$l]['url']= $page->localHttpUrl($language).wire('input')->urlSegment1; $ar[$l]['name'] = $language->name == 'default' ? 'en' : $language->name; $ar[$l]['title'] = $language->getLanguageValue($language, 'title'); $ar[$l]['active'] = $language->id == wire('user')->language->id; $l++; } return $ar; }]; Get county info from ContinentsAndCountries Module Using the [ContinentsAndCountries Module](https://modules.processwire.com/modules/continents-and-countries/) you can extract iso code and names for countries: $query = ['country' => function($page){ $c = wire('modules')->get('ContinentsAndCountries')->findBy('countries', array('name', 'iso', 'code'),['code' =>$page->country]); return count($c) ? (array) $c[count($c)-1] : null; }]; Custom strings from a RepeaterTable for interface Using a RepeaterMatrix you can create template string for your frontend. This is usefull for buttons, labels etc. The following code uses a repeater with the name `strings` has a `key` and a `body` field, the returned array contains the `key` field as, you guess, keys and the `body` field as values: // build custom translations $query = ['strings' => function($page){ return array_column($page->get('strings')->each(['key', 'body']), 'body', 'key'); }]; Multilanguage with default language fallback Using the following setup you can handle multilanguage and return your default language if the requested language does not exist. The url is composed like so: `page/path/{language}/{content-type}` for example: `api/icf/zurich/conference/2019/de/json` // get contenttype and language (or default language if not exists) $lang = wire('languages')->get($input->urlSegment1); if(!$lang instanceof Nullpage){ $user->language = $lang; } else { $lang = $user->language; } // contenttype segment 2 or 1 if language not present $contenttype = $input->urlSegment2 ? $input->urlSegment2 : $input->urlSegment1; if ($contenttype === 'json') { header('Content-type: application/json'); echo $page->pageQueryJson($query); exit(); } Debug The module respects wire('config')->debug. It integrates with TracyDebug. You can override it like so: // turns on debug output no mather what: $modules->get('PageQueryBoss')->debug = true; Todos Make defaults configurable via Backend. How could that be done in style with the default queries? Module in alpha Stage: Subject to change This module is in alpha stage … Query behaviour (especially selecting child-templates, renaming, naming etc) could change
  30. 26 points
    Hey folks! Took a couple of late nights, but managed to turn this old gist of mine into a proper module. The name is SearchEngine, and currently it provides support for indexing page contents (into a hidden textarea field created automatically), and also includes a helper feature ("Finder") for querying said contents. No fancy features like stemming here yet, but something along those lines might be added later if it seems useful (and if I find a decent implementation to integrate). Though the API and selector engine make it really easy to create site search pages, I pretty much always end up duplicating the same features from site to site. Also – since it takes a bit of extra time – it's tempting to skip over some accessibility related things, and leave features like text highlighting out. Overall I think it makes sense to bundle all that into a module, which can then be reused over and over again 🙂 Note: markup generation is not yet built into the module, which is why the examples below use PageArray::render() method to produce a simple list of results. This will be added later on, as a part of the same module or a separate Markup module. There's also no fancy JS API or anything like that (yet). This is an early release, so be kind – I got the find feature working last night (or perhaps this morning), and some final tweaks and updates were made just an hour ago 😅 GitHub repository: https://github.com/teppokoivula/SearchEngine Modules directory: https://modules.processwire.com/modules/search-engine/ Demo: https://wireframe-framework.com/search/ Usage Install SearchEngine module. Note: the module will automatically create an index field install time, so be sure to define a custom field (via site config) before installation if you don't want it to be called "search_index". You can change the field name later as well, but you'll have to update the "index_field" option in site config or module settings (in Admin) after renaming it. Add the site search index field to templates you want to make searchable. Use selectors to query values in site search index. Note: you can use any operator for your selectors, you will likely find the '=' and '%=' operators most useful here. You can read more about selector operators from ProcessWire's documentation. Options By default the module will create a search index field called 'search_index' and store values from Page fields title, headline, summary, and body to said index field when a page is saved. You can modify this behaviour (field name and/or indexed page fields) either via the Module config screen in the PocessWire Admin, or by defining $config->SearchEngine array in your site config file or other applicable location: $config->SearchEngine = [ 'index_field' => 'search_index', 'indexed_fields' => [ 'title', 'headline', 'summary', 'body', ], 'prefixes' => [ 'link' => 'link:', ], 'find_args' => [ 'limit' => 25, 'sort' => 'sort', 'operator' => '%=', 'query_param' => null, 'selector_extra' => '', ], ]; You can access the search index field just like any other ProcessWire field with selectors: if ($q = $sanitizer->selectorValue($input->get->q)) { $results = $pages->find('search_index%=' . $query_string . ', limit=25'); echo $results->render(); echo $results->renderPager(); } Alternatively you can delegate the find operation to the SearchEngine module as well: $query = $modules->get('SearchEngine')->find($input->get->q); echo $query->resultsString; // alias for $query->results->render() echo $query->pager; // alias for $query->results->renderPager() Requirements ProcessWire >= 3.0.112 PHP >= 7.1.0 Note: later versions of the module may require Composer, or alternatively some additional features may require installing via Composer. This is still under consideration – so far there's nothing here that would really depend on it, but advanced features like stemming most likely would. Installing It's the usual thing: download or clone the SearchEngine directory into your /site/modules/ directory and install via Admin. Alternatively you can install SearchEngine with Composer by executing composer require teppokoivula/search-engine in your site directory.
  31. 26 points
    Happy Holidays! This latest master version of ProcessWire contains hundreds of new additions, fixes, optimizations and more. This post covers all the highlights— https://processwire.com/blog/posts/pw-3.0.123-master/
  32. 25 points
    Here’s a brief update on what’s new in the core since last week. Next week I’m going to compile a more complete overview of everything that’s in 3.0.154 (and more) and put it in a blog post. I wanted to do that today, but my kids have needed a lot of help with various things today (and this whole week actually) with all of this online school stuff and I’ve run out of time. We're a few weeks in and school is cancelled for the rest of the year due to the coronavirus (likely the same around the world). I'm still learning how to adapt to kids around all day and needing attention, but overall it's nice to have the family around more even if it is sometimes hard to get work done. So I’ll keep this sort of brief, and get into more details next week. Several updates were made to the core/LanguageFunctions.php (language functions) file, with biggest being the option to programmatically replace translation text (whether multi-language support is installed or not), useful for very easily updating core/module output to say exactly what you want, and without needing to install multi-language modules. No longer do you need to use various hooks to change text in one module or another. Also moved the __('text') configuration options to dedicated functions which makes it more clear to use, as well as much better for documentation purposes: wireLangEntityEncode(), wireLangTranslations(), wireLangReplacements(). You'll see these new functions in our docs by next week. More details and examples of these in action in next week’s blog post. The CKEditor version has been upgraded from 4.12.1 to 4.14.0. To see what’s changed, see the release notes for CKEditor 4.13.0, 4.13.1 and 4.14.0 here. There’s actually quite a lot here in terms of additions and fixes. Note especially the two security related fixes in 4.14.0 (though I think only the first may be applicable to us). While it looks like a rather unlikely combination of factors needs to come together, and with just the right person, it’s good to be aware of nevertheless. Of note is that these particular cases are entirely client side, before PW ever gets to see or filter the content, so this is something that only a CKEditor upgrade can fix. Updated the core Debug class to use PHP 7.3’s recommended hrtime (high resolution time) for debug timers, rather than microtome. This is only available in PHP 7.3 and newer. As far as I can tell it produces identical results to microtome (as far is our timers go) but the PHP documentation page indicates hrtime is what we should now be using, so that’s what we’re going with. I also did a little refactoring and minor improvements in the Debug class as well. Updated ProcessWire’s Inputfield rendering system so that you can customize markup by matching a field by name, and without hooks. This essentially takes part the Inputfield customization system developed for LoginRegisterPro and brings it into the core. This opens up a lot more customizability for those that want it. Various resolutions of GitHub issue reports, with more on the way. The above are just updates from the last week, but there’s plenty more in 3.0.154 as well. See ProcessWire Weekly #309 for details on Image and file field updates, new $database->columnExists() method and new Selectors::getOperators() method, and more. There are also the new expanded file and image properties, as discussed in #308 and the last blog post. Thanks for reading and I hope you all have a great weekend!
  33. 25 points
    ProcessWire 3.0.142 has a lot of updates but the biggest is the addition of custom fields support for file and image fields. In this post, we take a closer look and also outline all of the new features in the just-released FormBuilder v40— https://processwire.com/blog/posts/pw-3.0.142/
  34. 25 points
    A module created in response to the topic here: Page List Select Multiple Quickly Modifies PageListSelectMultiple to allow you to select multiple pages without the tree closing every time you select a page. The screencast says it all: https://github.com/Toutouwai/PageListSelectMultipleQuickly https://modules.processwire.com/modules/page-list-select-multiple-quickly/
  35. 25 points
    Another little admin helper module... Template Field Widths Adds a "Field widths" field to Edit Template that allows you to quickly set the widths of inputfields in the template. Why? When setting up a new template or trying out different field layouts I find it a bit slow and tedious to have to open each field individually in a modal just to set the width. This module speeds up the process. Installation Install the Template Field Widths module. Config options You can set the default presentation of the "Field widths" field to collapsed or open. Field widths entered into the Template Field Widths inputfield are only applied if the Edit Template form is submitted with the Template Field Widths inputfield in an opened state. "Collapsed" is the recommended setting if you think you might also use core inputs for setting field widths in a template context. You can choose Name or Label as the primary identifier shown for the field. The unchosen alternative will become the title attribute shown on hover. You can choose to show the original field width next to the template context field width. https://github.com/Toutouwai/TemplateFieldWidths https://modules.processwire.com/modules/template-field-widths/
  36. 25 points
    Like in recent weeks past, the primary focus this week in core development was working through the queue of older issue reports. Relative to 3.0.128, ProcessWire 3.0.129 contains 17 commits over 1 week, most of which are focused on resolving and closing out older issue reports. However, there have also been a few very useful additions too, and I’m going to cover them in a blog post next week. In terms of our issues repository, we are now down to 65 open issues and 777 closed (the closed number is a total over the life of this repo). If we subtract issues that are tagged as being fixed, not a bug or ready to close, we’re around 55 open issue reports (give or take a couple depending on when we check). Which is to say, there’s a lot of great progress here. And many of the remaining issues are minor things that might only affect one person, though still important nonetheless. Thanks to everyone that’s helping figure things out (such as Toutouwai, Matjazpotocnik, Netcarver and others), your help is greatly appreciated. Just now I also released a new version of ProMailer (v7) which accommodates many of the recent feature requests and fixes a few minor issues as well. There has been a lot of enthusiasm for ProMailer, pleasantly more than expected—thanks for your interest and support. Here’s the changelog for the latest version (v7) below. There is also more good stuff in the works for v8 as well. Changed subscribers list interface to use tabs. Added ability to remove all subscribers from a list. Added ability to remove filtered subscribers from a list (matching find query). Added ability to import subscribers from another list (creating a merged list). Added support for single, multi-select and checkbox custom fields. Added support for PW 3.0.129+ core WireMail blacklist (more details in next week’s blog post). Added several new options for custom fields (see new custom fields reference). Added documentation for conditional placeholders. Split the rather large ProcessProMailer.module into separate files/classes. Fix some display issues in AdminThemeDefault and AdminThemeReno. Various minor bug fixes and other minor tweaks, additions and improvements. Thanks for reading this quick update and hope that you have a great weekend.
  37. 25 points
    Relative to the last dev branch version (3.0.127) version 3.0.128 contains 40 commits, mostly specific to resolving older GitHub issue reports. If you are interested, here is the commit log: https://github.com/processwire/processwire/commits/dev — version 3.0.128 covers commits between March 2nd and today. We're down to about 77 remaining issue reports, mostly older stuff that didn't get covered in the past for one reason or another, but we're making good progress. Similar updates will be continuing next week, and I've also got several ProMailer updates coming out next week too. Hope you all have a great weekend!
  38. 25 points
    https://www.spiria.com After several sites made with ProcessWire, Spiria decided it was time to get rid of its cumbersome Drupal site. To be honest, ProcessWire is still difficult to sell to customers, because this CMS/CMF is not as well known as the most popular ones. The migration to ProcessWire therefore served several purposes: Eliminate the frustrations experienced with Drupal (especially with image management and some structural problems). Allow integrators to learn the CMS during quiet periods, when they are not needed on other projects. Promote the CMS by adopting it. The challenges were many, but by no means insolvent, thanks to the great versatility of this programming framework. Indeed, if ProcessWire can be considered as a CMS in its own right, it also offers all the advantages of a CMF (Content Management Framework). Unlike other solutions, the programmer is not forced to follow the proposed model and can integrate his ways of doing things. The blog The site includes a very active blog where visuals abound. It was essential to cache the various dynamic components. For example, in all sections of the blog, there is a list of recent articles, a list of "short technical news", another list from the same author, a classification by category. In short, these lists evolve independently. ProcessWire's cache system, including its ability to classify by namespace, has significantly improved loading speed. Cache file management has been placed in a "saved" hook in the useful "ready.php" file. Data migration Importing the blog data was complex because at the time the site was designed in Drupal, programmers had not been used the easily translatable "entities", so each article resided in two different "nodes" (pages). We would have liked to use the core ProcessWire import module, but it does not yet take into account multilingual fields. However, we have used this code as a basis for building our own import module. This is one of ProcessWire's great qualities, as a CMF, it is easy to use existing code to design your own solutions. Reproduce the layout The current layout of the site has been reproduced exactly as it serves the company's needs very well. ProcessWire has simplified the work in many ways. Apart from the blog, which is very structured, the other sections of the site are more free, especially the case study section ("Our Work"). The use of page reference fields has particularly helped developers. As everything is a page in ProcessWire, you can create a pseudo relational database within the site itself. The administrator user becomes more aware of the data hierarchy and has better control over the data. Programming architecture The separation between controllers and Twig visualization files facilitates the management of the multiple components of the site. We haven't really explored the "regions" of ProcessWire, because we prefer not to mix these aspects of programming. This greatly facilitates the timely arrival of programmers in our department, used to an MVC structure, because they have a better understanding of what does what. The Search Once again, we were able to simplify what had been done in Drupal. There are two types of searches on the site, the blog search and the more general search on page 404 ( https://www.spiria.com/potato). The Drupal site search was driven by an Apache Solr server in Drupal. We decided to rely on the ease of ProcessWire and the Typeahead library (for the blog), because we didn't need the power of Solr (or Elasticsearch) anyway. Work to improve performance still needs to be done in this area. We would have liked to have seen the excellent search tool offered on the administrative side available on the frontend. We have not yet had time to explore the possibility of harnessing this code from the core of ProcessWire. Our wish here is that the CMS designer, Ryan Cramer, sees this as an opportunity to offer an exciting new feature to his CMS! Powerful modules We have the excellent modules ProCache (static caching), ProFields (fields that greatly improve the functionality of existing fields) and ListerPro (data search and processing tool). As the site is installed on a nginx server, we have ruled out ProCache for the moment and we are satisfied with the use of the cache() function alone. The ProFields fields are a blessing just like ListerPro. This last module is very useful to correct, for example, import errors (we had more than 800 blog articles, some of which date back to 2013). We used a functional field to gather translations of terms that would normally have remained hard coded and difficult to access in the translation interface (an aspect to be improved in ProcessWire, in our opinion). By grouping translations in a single page, site administrators can easily change or correct terms. Language management What remains a very small irritant for us is the management of languages, which is fantastic in many ways. The fact that there is a default language is both a blessing and a problem. For example, in 2013, blog articles were not systematically translated. We experienced the same situation with a customer's site. If the article is only in English, no problem, we only have to not check French as an active language. However, if the article is only in French, we are still required to create the page in English and make tricks in the code, thanks in particular to a checkbox such as "Not present in English" to reproduce the behaviour naturally present for English (or any language deemed by default). Perhaps there is a more elegant solution here that we have not yet discovered. It's not much, but some clients don't see why there are two ways to do it here. In conclusion In any case, ProcessWire's great qualities continue to appeal to programmers, integrators, graphic designers, users and even our UI/UX expert. The solidity of the CMS/CMF, its functionalities all translated into objects/variables ($pages, $page, $config, $sanitizer, $input... the list is long) allows us to systematize our workflow, easily recover code and reduce production costs. Although it is dangerous to offer only a CMS solution to our customers (hammer syndrome that only sees nails), it is tempting to consider ProcessWire as the Swiss Army knife par excellence of Web programming. As mentioned above, the CMF is suitable for all situations, has very good security tools and its designer has successfully improved PHP methods to make programming very pleasant and intuitive. For us, migrating the company's website to this platform was the best tribute we could pay to its designer, @ryan.
  39. 25 points
    News Update - 10 October 2018 I know many of you are eagerly awaiting the next version of Padloper. I thought I'd give you a couple of updates regarding progress. First, I'd like to thank you for the feature requests and your support. As previously stated, it will not be possible to accommodate all requests and those that may be accommodated may have to wait till other releases. OK, to the update. The following have so far been achieved. FieldtypeProducts A new Fieldtype for storing products including their variants, if any. This allows for easy retrieval and storage of data and and API that makes it easy to filter, search, manipulate, update, etc product details. So..: $foo = $products->find("colour=red,quantity<10"); $bar = $product->first(); echo $bar->size; echo $bar->price; // etc Discounts We have a new discounts class that allows for 4 types of discounts each with generic and specific requirements. Percentage discount Fixed amount discount Free shipping discount Buy X Get Y discount In turn, as applicable, the discounts are subject to generic conditions including customer country,named customers, customers subscribing to your newsletter, global usage, customer usage limits, customers who abandoned carts, start/expiration dates, etc. There are also discount-specific conditions including whether to apply discount to entire order, specific products or specific categories/collections, minimum requirements (purchase amount or quantity of eligible products in cart), etc. Import/Export Products This class allows for importing products into your shop as CSV, JSON or arrays. It is 98% done. It will also allow for exporting products as CSV (and maybe in future, as JSON, if there is demand). MarkupPadloper This is WIP to eventually replace PadRender. This allows for retrieving products, product tags, product categories, etc, either as ready-to-render (i.e. includes the markup) vs retrieving the raw product details so one can use their own markup, anywhere, anyhow, to output products. Other A bit of work on customer notifications (including email templates) and FieldtypeOrders for orders plus some other stuff. I got a lot to do, so I better get cracking! 🙂 Thanks for reading.
  40. 25 points
    Like the last few weeks, most efforts this week focused on resolving issue reports at GitHub and preparing the master version. We are at a point where I think our dev branch is far better than our previous master (3.0.62), in every way, stability included. So there's no reason to delay further—3.0.96 is our new master version. This post covers all the details: https://processwire.com/blog/posts/pw-3.0.96-master/
  41. 24 points
    This week we’ll take a look at LoginRegisterPro — a new module that provides an all-in-one, self contained module for providing new user registration, secure logins, profile editing, and more. It does this all in a manner that is reliable, efficient, comprehensive and secure. As we continue preparing the ProcessWire core dev branch to become our new master, I've been trying to stay hands-off on new feature additions there as much as possible (till the new master is out), and instead focusing on finishing up modules I've had in development. Last time I told you about the UserActivity module, and this time we’ll look at LoginRegisterPro, which is another module dealing with users; though significantly larger in scale/scope. LoginRegisterPro is a module I've been working on for more than a year, and finally this month have it ready to share. While I don't have it available for download today I do expect to have a beta release as soon as early next week. Read this week’s post for more details— https://processwire.com/blog/posts/login-register-pro/
  42. 24 points
    Hi all, Introducing a new GDPR Cookie Management Banner module. https://github.com/adrianbj/CookieManagementBanner https://modules.processwire.com/modules/cookie-management-banner/ This module was sponsored by VentureWeb in Squamish, BC, Canada. I converted a Drupal module written by Oliver Walker from VentureWeb into what you see here. The Drupal module requires jQuery so at the moment, this module also requires jQuery. I will probably remove this sometime soon. This module certainly has similarities to MarkupCookieConsent but provides the user with the following features: The user can accept all cookies or they can choose to not accept tracking/marketing cookies. Module config options allow you to: define all text and button labels (multi-language support) manually increment the cookie policy version which forces the user to review their consent again select whether users can manage their cookies, or just accept all option to limit display of banner to users only in European Union (by IP address) position selection (top or bottom overlay, or content pushed down from the top) It comes with basic default styling which is easily overwritten by site CSS The module sets various values to the dataLayer array which works together with Google Tag Manager - please read through the code in /assets/js/CookieManagementBanner.js to get a better idea of how this works and what is made available for GTM. You can wrap your tracking/marketing cookie code in a check for the localstorage key of: pwcmbAllowCookies if(localStorage.getItem('pwcmbAllowCookies') == 'y') You can also provide a link on your site (probably in the footer) like this that will allow the user to show the banner even after they have saved their preferences / accepted. <a href="#cookies" class="js-pwcmb-notice-toggle">Manage Your Cookies</a> Would love to hear feedback from anyone who gives this a go.
  43. 24 points
    Today we have a new master version released, version 3.0.148! The last master version was 3.0.123, so there are 25 new versions worth of upgrades, fixes and optimizations in this new master version, relative to the previous. In this post we’ll take a closer look at what’s new, how to upgrade, and more— https://processwire.com/blog/posts/pw-3.0.148-master/
  44. 24 points
    Some of you might have followed the development of this module here: https://processwire.com/talk/topic/15524-previewdiscussion-rockdatatables/ . It is the successor of "RockDataTables" and requires RockFinder to get the data for the grid easily and efficiently. It uses the open source part of agGrid for grid rendering. WHY? ProcessWire is awesome for creating all kinds of custom backend applications, but where it is not so awesome in my opinion is when it comes to listing this data. Of course we have the built in page lister and we have ListerPro, but none of that solutions is capable of properly displaying large amounts of data, for example lists of revenues, aggregations, quick and easy sorts by the user, instant filter and those kind of features. RockGrid to the rescue 😉 Features/Highlights: 100k+ rows Instant (client side) filter, search, sort (different sort based on data type, eg "lower/greater than" for numbers, "contains" for strings) extendable via plugins (available plugins at the moment: fullscreen, csv export, reload, batch-processing of data, column sum/statistics, row selection) all the agGrid features (cell renderers, cell styling, pagination, column grouping etc) vanilla javascript, backend and frontend support (though not all plugins are working on the frontend yet and I don't plan to support it as long as I don't need it myself) Limitations: While there is an option to retrieve data via AJAX the actual processing of the grid (displaying, filtering, sorting) is done on the client side, meaning that you can get into troubles when handling really large datasets of several thousands of rows. agGrid should be one of the most performant grid options in the world (see the official example page with a 100k row example) and does a lot to prevent problems (such as virtual row rendering), but you should always have this limitation in mind as this is a major difference to the available lister options that do not have this limitation. Currently it only supports AdminThemeUikit and I don't plan to support any other admin theme. Download: https://gitlab.com/baumrock/FieldtypeRockGrid Installation: https://gitlab.com/baumrock/RockGrid/wikis/Installation Quikckstart: https://gitlab.com/baumrock/RockGrid/wikis/quickstart Further instructions: https://gitlab.com/baumrock/RockGrid/wikis/quickstart#further-instructions German Translation File: site--modules--fieldtyperockgrid--fieldtyperockgrid-module-php.json Changelog: https://gitlab.com/baumrock/FieldtypeRockGrid/raw/master/changelog.md Module status: alpha, License: MIT Note that every installation and uninstallation sends an anonymous google analytics event to my google analytics account. If you don't want that feel free to remove the appropriate lines of code before installation/uninstallation. Contribute: You can contribute to the development of this and other modules or just say thank you by testing, reporting issues and making PRs at gitlab liking this post buying me a drink: paypal.me/baumrock/5 liking my facebook page: facebook.com/baumrock hiring me for pw work: baumrock.com Support: Please note that this module might not be as easy and plug&play as many other modules. It needs a good understanding of agGrid (and JavaScript in general) and it likely needs some looks into the code to get all the options. Please understand that I can not provide free support for every request here in the forum. I try to answer all questions that might also help others or that might improve the module but for individual requests I offer paid support for 60€ per hour (excl vat). Use Cases / Examples: Colored grid cells, Icons, Links etc. The Grid also has a "batcher" feature built in that helps communicating with the server via AJAX and managing resource intensive tasks in batches: Filters, PW panel links and instant reload on panel close: You can combine the grid with a chart library like I did with the (outdated) RockDataTables module:
  45. 24 points
    This week I’m happy to report we now have WEBP support in ProcessWire thanks to a GitHub pull request from Horst Nogajski. This enables you to have highly optimized image output in PW and I think you’ll really like the difference it makes. Read on for all the details… https://processwire.com/blog/posts/webp-images-in-pw/
  46. 24 points
    This week is the Thanksgiving holidays here in the US and it’s one of those weeks where there’s no school for the kids, so it’s a little hard to get work done. I don’t have any major core updates to report this week, so I’m not going to bump the version number up today. However, look for a new dev branch version next week. We will also release a new master version before the end of the year… sometime within the next month. Before releasing the new master version, I’m primarily interested in resolving any issues present in the current dev branch that are not present on the current master branch. Meaning, issues that have arisen due to some recent change only on the dev branch (if there are any). So if you are aware of any issues experienced on the dev version that are not on the master, please let me know. Thanks for your help in testing. Even though it’s been a vacation week, I’ve been waking up early every morning to work on the new PW website. Lots of continuing progress, and I should have another update on that next week along with a new dev branch version of the core. Thanks for all the feedback from last week’s post. Among other things, I caught that folks don’t like the skyscrapers anymore (as a visual element), so I’ve taken them out and agree it’s better without them. I’ll have some updated screenshots next week. Off topic, but was so excited I had to tell someone. I got a computer upgrade this week after 4 or so years of working off the same laptop. A few keys on my laptop keyboard recently stopped working (letters in the word “ProcessWire” — I wore them out), so I’ve been using an external keyboard plugged in. That’s been working alright, but made it hard to see the screen since I can’t sit as close with an external keyboard in front of the laptop. It was getting a little tiresome to work on, the keyboard wasn't repairable without rebuilding the whole laptop (costly), and it was basically time for an upgrade, but computers are expensive and I was resigned to waiting another year. Over these Thanksgiving holidays I found out a family member had bought an iMac a year or so ago and didn’t like it, so they were going back to a PC. I said, “hey why don’t you sell that iMac to me?” We came to an agreement. Now I've got it here and am moving my development environment over to this newer computer, and have been working off it for a couple of days and loving every minute of it. It's going to help out a lot with developing ProcessWire.
  47. 24 points
    Thanks to all that have been helping us to wrap up issue reports on GitHub in preparation for the next master version of the ProcessWire core. Unless any major issues surface, most likely 3.0.95 (next week) will be the next master version. Like last week's version 3.0.93, this week's version 3.0.94 continues along the same path in clearing up new and existing issue reports, and fine tuning little details for the master branch. If you come across any new significant issues please submit them in the issues repository. Or if you opened an issue awhile ago and we haven't fixed it yet, please check that the issue is still applicable and reply to let us know. No blog post this week because I don't have anything else new or interesting to write about other than this. But I am definitely getting excited about having a new master version ready. There's no doubt, this is a really nice upgrade relative to the current master 3.0.62. Have a great weekend!
  48. 24 points
    This week we’re back with a new dev branch version that adds a new feature we think you’ll like: focus point image cropping. That’s also the “focus” of this blog post. This version also includes resolutions to numerous issue reports and more. https://processwire.com/blog/posts/pw-3.0.89/
  49. 23 points
    This week flew by too fast. I did some work on the core, but mostly had to focus on some end-of-the-month client work deadlines, in ProcessWire-powered projects. As a result, I don't have enough core updates to warrant a version bump on the dev branch this week, so putting a quick update here rather than a blog post. ProcessWire 3.0.112 should be ready by this time next week. One of my clients recently requested a URL field that intermittently verifies itself—to make sure that the URL is still returning a 200 success, and not a 404 error, or some other error code. Their site has thousands of external URLs (more than they can check manually), and they want some way to avoid showing links for URLs that are no longer working. I thought a self-healing URL field sounded like a cool idea, so put a little work into that this week, and will likely finish it up next week. The module is called FieldtypeVerifiedURL and it extends the regular FieldtypeURL field, except that in its configuration you can specify how often you want it to verify that the URL is still valid. It also performs the verification whenever the value changes. It uses WireHttp to obtain and store the response code with the field, whether a 2xx (success), 3xx (redirect) or 4xx (error) code. So if you wanted to, you could filter the pages with this URL field by response code (like to find all those returning 404s for instance). It can optionally save the <title> tag found at the URL for you as well. In our case, we will be configuring it to check that URLs are valid once a week, and this is something that it will do in the background automatically. When a URL is found to be returning an error code (like a 404), the output of the field can be optionally configured to return an empty value rather than the URL (when output formatting is on). I'm not anywhere near finished with this one, but if this sounds useful to you, stay tuned for more on this soon. Have a great weekend!
  50. 23 points
    Minimal Fieldset Adds a config option to Fieldset/FieldsetGroup/FieldsetPage to render the fieldset without label or padding in Page Edit. When a neighbouring field in the same row is taller than the fieldset the extra height is distributed evenly among rows within the fieldset. Requires ProcessWire v3 and AdminThemeUikit. Why? This module allows you to create layouts in Page Edit that would not be possible without it. It's useful when you want a layout that has two or more fields as rows that are themselves within a row in Page Edit. It's also useful when you have some fields that you want to add to a template as a group (i.e. via FieldsetGroup or FieldsetPage) but having a heading and visible wrapper for the fieldset in Page Edit would be redundant. Example: Installation Install the Minimal Fieldset module. Usage In the field settings for any Fieldset/FieldsetGroup/FieldsetPage, tick the "Remove label and padding for this fieldset" checkbox. https://github.com/Toutouwai/MinimalFieldset https://modules.processwire.com/modules/minimal-fieldset/
×
×
  • Create New...