Leaderboard
Popular Content
Showing content with the highest reputation on 07/26/2024 in all areas
-
As a default? Big NOPE from me. The super easy way and low barrier to enter the world of ProcessWire was one of the main reasons I gave it more than a quick look, did all the tutorials, read the docs, read the forum, ... and stayed. I tried a lot of CMSs back then and because ProcessWire had this "direct output"-way of achieving a lot without needing to know much about PHP or programming in general was the biggest PLUS ever. if/else/echo/foreach is almost everything you need to know to get up and running - and this quite far. Easier than anything. Easier than the Wordpress-loop, Silverstripe's way of doing things, or Drupal and Typo3. Such a delight and super fun to learn something new, a new CMS. Sorry for interrupting this great discussion.10 points
-
@ryan thank you for your reply on my last post. I have to think about everything that has been said, but I have to mention here that this might not be trivial for someone new to OOP where everything that he/she wants to do is add a hook this will only work if you have at least one instance of that pageclass loaded. So if there is no page loaded (or no page exists) yet with that template then hooks will not be added and therefore some important features might not work and you'll get unexpected results. I understand what you said about why you don't want to have them in the pageclass itself, but I still think PW could make it easier to guide/support the user (that might be totally new to OOP) in how or where to attach hooks that are "related to" (whatever that means) the pageclass. Similar to what we have with /site/ready.php and /site/init.php, which is really trivial. ? @FireWire fully agree!6 points
-
ProcessWire Improvement Suggestions I’m pleased to see ideas being gathered to improve ProcessWire, and as a loyal user and contributor since 2014, I'd like to share my list and thoughts on the matter. Over the past few years, there has been a lack of clarity on whether requests and ideas will be implemented, and if so, when. Requests and issues often remain open for years without updates. I'll address how this can be optimized. There is also no clear way to influence these decisions. Years ago, we introduced the idea that thumbs-ups in the Requests Repo should mark the importance of requests. However, there's still no way to know if any of these points will be implemented. My idea for the future is as follows: Increase Community Involvement and Establish a Fixed Release Cycle Optimize Integration of Requests It could be beneficial to review which GitHub issues have the most thumbs-ups within a set period (e.g., quarterly or biannually) and then fix or implement them. If there are too many features or if requests have the same number of thumbs-ups, a poll could be conducted in the forum to see what the community wants implemented first. Introduce New Status Labels for Requests Under consideration In Progress Completed Faster Closure of Issues When a request is integrated, it should be closed immediately rather than marked as “completed.” Often, the requester doesn’t provide feedback or forgets to close the issue (which has happened to me as well). If something doesn’t work, the issue can be reopened. Automatically Close Stale Issues There is a stale action for GitHub that automatically closes issues after a period of inactivity. The issue creator can reopen it by responding. Better Definition of ProcessWire’s Target Audience The target audience for ProcessWire is not clearly defined. This makes it difficult to determine which features are truly necessary. Developers will likely have different requirements compared to someone looking to create a website quickly and cheaply. Developers eventually hand over the website to a client, who then manages the content themselves. Non-developers struggle to know which modules exist to manage their website. The module installation process is cumbersome, which is why I developed the ModuleManager2 years ago (link). Despite user interest, it hasn’t been widely used. There was a discussion that module installation directly through ProcessWire was rejected for security reasons (though my module only uses core methods). Integrated module management, similar to systems like WordPress, Prestashop, or Shopware, would simplify module discovery, installation, and maintenance. Discovery Process The discovery process is beneficial for all users, including power users. Sometimes I can’t remember a module’s name, but with MM2, I can search for a term in the description and find the corresponding module. Security is a concern, but I believe it’s possible to implement this in a secure way. PHP 8 and Named Arguments Finally, PHP 8 and named arguments will greatly assist in module development. Easier Customization of the Admin Theme Custom Navigation It's cumbersome to change the navigation or create a completely custom one without creating a new admin theme. This has been mentioned before (insert link). This is usually only necessary when developing custom software with ProcessWire. It would be helpful to create menu items that link to modules or specific actions within those modules, or simply a URL path. Introduce a dark mode (toggle switch). A quick solution is with one line of CSS: nightowl, but an integrated dark mode would be better. Global Media Manager A global media manager is a great idea, especially for certain assets like logos or seals used across multiple pages. While it’s possible to create a page and field to source these images, it’s not user-friendly for newcomers. For instance, I have a client with 30 product pages that require seals to be updated annually. A central management point would simplify this process. I’ve implemented this for my client, but it’s challenging for those accustomed to systems like WordPress and conceptually difficult to grasp. Aligning with Conventions from Other Frameworks Environment Configuration A .env file to store database connections, httpHosts, etc., which are read by site/config.php and site/config-dev.php. The config-dev.php file should include config.php and allow properties to be modified/overridden. This is how I and others currently do it (insert reference). Automated Deployments and Module Updates Composer is a stable package manager for PHP and a convention widely used in the PHP community, making automated deployments and updates easier. Built-In SEO Built-in rudimentary SEO would be a significant plus for websites. During installation, users could choose between a website or custom software without a frontend. If they choose a website, either ProcessWire-Core-SEO or the SEOMaestro module could be selected for installation. Lack of Visibility on ProcessWire Adoption There is no clear overview of how widely ProcessWire is adopted, such as the number of installations. This lack of visibility can make it difficult to gauge the platform's popularity and growth. Absence of a Marketplace Ecosystem The absence of a marketplace ecosystem makes it uncertain for module developers like Bernhard or myself to determine whether and how much money can be made from developing modules for ProcessWire. Other systems like Kirby, Statamic, and WordPress have a store that can be accessed directly through the admin interface. These stores also include license management, making it easier for developers to monetize their work and for users to manage their purchases. Proposed Marketplace and Revenue Sharing One idea could be to introduce a marketplace for ProcessWire, where a portion of the revenue from sales is reinvested into the development of ProcessWire. However, this is not a necessity and should be a point of discussion, considering the controversies seen with Epic or the Apple Store.4 points
-
Hello! Mailchimp is a popular email marketing platform and one that is used more often than any alternative by my clients. After having to work with embedding HTML and creating generic Textarea fields to output to pages, I wanted to create a better experience and robust form management. Mailchimp for Formbuilder is a module that adds a new form processing Action to form configuration in FormBuilder. It's intended to be easy to use for both ProcessWire developers and end users while being very configurable. This module lets you do more in ProcessWire faster with great feature parity. Here are some module features: Create new FormBuilder forms that collect Mailchimp subscription signups Add Mailchimp subscription signup abilities to any existing FormBuilder form Each FormBuilder form is configured independently so you can create forms for specific Mailchimp needs Compatible with any type of field that can be configured in Mailchimp Manage Mailchimp settings right where you configure other FormBuilder form settings Stop pasting Mailchimp form embed codes and make subscribing to Mailchimp lists easy using your forms styled the way you want No need to create redirect pages for successful signups, let FormBuilder handle the form submission experiences Choose what actions to take, add new subscribers, update existing subscriber contact information, or unsubscribe existing contacts Logs error messages when encountered while communicating with Mailchimp, or form submission issues occur that prevent sending a subscription to Mailchimp Provides in-depth logging for each event during the subscription process while ProcessWire is in debug mode to help developers troubleshoot and/or understand what is happening behind the scenes. Mailchimp for FormBuilder aims to take advantage of the core features Mailchimp offers: Audiences (lists) - Collect subscriptions for any Audience in Mailchimp Audience Tags - Organize and segment your Mailchimp contacts with one or more tags Form Fields - Collect subscriber information using text, number, radio buttons, check boxes, drop downs, dates, addresses, website, and phone fields Interest Groups - Create Interest Group fields in Mailchimp to further organize your Contacts and create targeted campaigns Screenshots: Install the module and Mailchimp for FormBuilder, add your Mailchimp API key. Edit your form, choose your audience, save, and return to configure. In addition to configuration options, Mailchimp for FormBuilder includes robust high-level instructions under "How to configure..." that help less-technical end users manage their forms. Choose your audience, subscription action, and status. Choose whether to only accept new subscribers, add and update existing contacts, or unsubscribe. Pre-define whether a subscriber will receive HTML or plain text email, or choose a field to let people filling out your forms decide. Optionally mark subscribers as VIP, choose whether to provide Mailchimp the IP address at the time of signup. Choose from existing Audience Tags, or create new tags right in ProcessWire. Audience Tags created while editing one form makes available as an option to all forms. Choose which Mailchimp fields should receive form data, as many or as few as desired. If a field is set as required in Mailchimp, it will be required here too. Mailchimp only requires an email address for all subscribers by default. The Mailchimp fields you select appear below to choose the form field that should be associated with it. Notes appear below each field where helpful information is provided by Mailchimp to help you configure your form fields. If a field has multiple options in Mailchimp, such as dropdown/radio/checkbox fields, the values Mailchimp expects are noted so that you can ensure your fields submit the correct information. Date fields show the format that Mailchimp uses for that field, but Mailchimp for FormBuilder will automatically format your date fields to match what Mailchimp requires so no extra work required. Fields that are configured in Mailchimp as an Interest List show the value(s) your form field can submit. Collect information for complex fields such as addresses. Just choose the form field for each Mailchimp field. Required fields helps you make sure that your addresses will be accepted by Mailchimp. There is also an ability to choose a checkbox in your form that determines if a submission should be sent to Mailchimp. If a checkbox field is configured then a value is required to send your form data to Mailchimp, if it's left unchecked then the Mailchimp process is skipped entirely. This is a local field that is independently managed separately from Mailchimp. Known limitations: File upload fields can't be processed. While Mailchimp provides a file URL field that can be used in forms, the files uploaded via FormBuilder are not yet ready when this module parses submission data. Mailchimp has added GDPR settings but working with them via the API is a little more complex than expected. I'm not sure whether the GDPR features in Mailchimp are actually required for the EU, but I would like to eventually implement this to be feature-complete and more helpful for our European comrades. Considerations to keep in mind: This module makes every attempt to maintain parity between Mailchimp and ProcessWire configurations but there are reasonable limitations to be expected. Because data is being sent to a Mailchimp account from an external source (ProcessWire), it is not possible to automatically know if changes have been made in Mailchimp. Audience Tags are a good example. Tags may be created, edited, and deleted in Mailchimp but it will still accept any tags submitted due to how the API works. So if you have a form that tags subscriptions "Special Offers" but that tag is deleted or modified in Mailchimp, "Special Offers" will be re-created the next time a form is submitted. If a Mailchimp field is changed to required but the form hasn't been updated then subscriptions may be rejected. Mailchimp for FormBuilder fails silently and takes the route of logging errors rather than preventing FormBuilder from continuing to process the submission. This is to prevent data loss and interruptions for the end user as well as allow other form actions to still take place. It is recommended that forms always store submissions in the database as long as this FormBuilder processor is in use. This is an alpha release! I've built it for a project in-progress so it works as far as I've tested it. Please test thoroughly and share any bugs or issues here or by filing an issue on the Github repo. When it's had wider testing and thumbs up from users I'll submit it to the modules directory. Thanks! Download Mailchimp for FormBuilder from the Github repository here.4 points
-
@Jonathan Lahijani I'd need specific examples to respond to or questions to answer. This is a fully built out profile. I think some might expect that I would classify/objectify everything, but I don't do that unless there's a strong reason for doing so. I use classes when there's an OO reason for doing so, and rarely is "group of related functions" one of those reasons, unless for sharing and extending. Using custom page classes or OOP is not at all necessary for most installations. It's only when you get into building larger applications that you might benefit from these things. And even then, it's not technically necessary. One good reason to use custom Page classes is just to have a documented or enforceable type, with no need to have any code in the actual class: /** * @property string $title * @property float $price * @property PageArray|CategoryPage[] $categories * @property string $body * @property Pageimages $photos */ class ProductPage extends Page {} If you add something to the class, it might be to add an API for the type's content that reduces the redundant code you'd need when outputting it. class ProductPage extends Page { /** * Get featured photo for product * * @return Pageimage|null * */ public function featuredPhoto() { $photos = $this->photos; if($photos->count()) return $photos->first(); foreach($this->categories as $category) { $photo = $category->photos->first(); if($photo) break; } return $photo; } } I'd like that too. Maybe "buy" is a longer term goal, but shorter term I'd be interested in suggestions for how best to help promote others modules. @bernhard There's no need to use OOP in ProcessWire, especially for someone new to it. ProcessWire does all the work to make sure that by the time your template file is called, you are output ready. So it's only once you get to be more advanced that you might then start using hooks, and you might never use OOP. If someone wants to add a hook, the most reliable place for that is the /site/ready.php file, or in some file that you include from it (conditionally or otherwise), and that's what I'd recommend. ProcessWire wouldn't even load your ProductPage.php file if no instance was created. But even if it did, why would there be a need for any hooks related to page class "ProductPage" if no page of the type is ever loaded? Maybe I'm missing something. You already know I'm skeptical of hooks being added by Page objects, but now we're talking about hooks that aren't even related to the page class being within it? ? If there are, they still wouldn't be called unless something triggered PW to load the ProductPage.php file. And the primarily reason it would load the file is to create an instance of the class. That makes sense. For most I'd suggest this: $wire->addHook('Pages::saveReady(template=product)', function($e) { // ... }); Or this if you are using custom page classes, and want to capture ProductPage and any other types that inherit from it: $wire->addHook('Pages::saveReady(<ProductPage>)', function($e) { // ... }); If conditional for the requested $page, then wrap the call in an if() if($page->template->name === 'product') { $wire->addHook(...); } If you need to hook the same method for multiple types, it can be more efficient to capture them all with one hook. Maybe you want it to call a saveReady() method on any custom Page classes that have added it. Since you wanted hook type code in the Page class, here's how you could do it without having hooks going into the Page class: $pages->addHook('saveReady', function($e) { $page = $e->arguments(0); if(method_exists($page, 'saveReady') $page->saveReady(); }); Rather than more initialization methods, if you needed hook-related implementation in the custom Page class, the above is the sort of thing that I think would be better. At this point, it's only about being "ready to save THIS instance of the page" which I'd have no concerns about. I could even see the core supporting this so that you could just add a saveReady() or saved() method to the custom Page class, and neither you or the core would even need to use hooks. But back to hooks, if you don't want to load up your /site/ready.php with code, maybe just use ready.php as the gatekeeper and organize them how you want. If you only need hooks for the admin, maybe put them in /site/templates/admin.php. If you want to maintain groups of hooks dedicated one type or another, put them in another file that you include from your ready.php file: include('./hooks/product.php'); I understand you like to maintain these things in or alongside your Page class files. Your MyCustomPage.php class file is one that might be suitable because those hooks won't get added unless an instance of the class is created, or something does a class_exists('ProcessWire\ProductPage'). I think you did something like the following in an earlier example, and it's just fine because it's independent of any instance and doesn't add pointers into any specific instance, and will only ever get added once: class ProductPage extends Page {} $wire->addHook(...); Or maybe you want the hooks in a separate related but dedicated file. It would have the same benefits as the previous example, but isolated to a separate file: class ProductPage extends Page { public function wired() { require_once(__DIR__ . '/ProductPageHooks.php'); parent::wired(); } } Maybe you want to do it for all classes that extend BasePage.php. Or you could use a trait, but here's an example using inheritance: // site/classes/BasePage.php class BasePage extends Page { public function wired() { parent::wired(); $f = __DIR__ . '/' . $this->className() . 'Hooks.php'; if(file_exists($f)) require_once($f); } } // /site/classes/ProductPage.php class ProductPage extends BasePage {} The word "trivial" means "of little value or importance" and I wouldn't agree with that classification of these files. But I think you might (?) mean that it's really "basic/simple" (which is meaning I think of sometimes too), and that's actually the goal of it, so I would agree with that classification.4 points
-
While this isn't a suggestion for the core, since it came up I want to second this. There are many great modules that would benefit from this- for both those that are currently available, and just as importantly, modules that have yet to be built. I can say for myself that there are some things that I'd love to create but it's difficult to justify considering the effort to build, maintain, and improve it without the potential to recoup some of the real costs involved. Listing the benefits of an official shop would make this comment far too long. I'm a big fan of the official Pro modules and I don't build sites without them, same has become true for those offered by @bernhard. This would also really help newcomers adopt ProcessWire if the modules directory could become a platform to browse both paid and free modules. Decoupling the Pro module purchase experience from the forums would be really helpful and I would argue foster wider adoption. I see this as a long-term sustainability initiative for the ecosystem as a whole. Maybe this could tie into ProcessWire core (hear me out) Maybe this could be supported in ProcessWire itself where the module is downloaded in ProcessWire (as free modules are currently), and then keys that are purchased in the store can be entered where modules are managed in the admin itself. Reducing the effort and friction of adopting high quality modules for more projects and providing true integrated support. I would love to install Pro modules as easily as those in the directory. I would expect, and hope, to see a per-sale fee for commercial modules sold in an official shop to both make this endeavor sustainable and to see something go back to the ProcessWire project. By that I mean I would like to build modules that buy @ryan a beer, preferably multiple because that means things are going well. There have been some great suggestions here, but I do want to take a moment for some thanks to the constant improvements that I've seen. Even the smaller quality of life changes in new versions are entirely appreciated as we enjoy a better developer experience. Cheers! ?4 points
-
@wbmnfktr was just a minute faster, but I feel exactly the same way: I have to say I am using ProcessWire exactly because it doesn't force me into a direction and/or into a form of "best practice". But nevertheless I think there is already a lot of controller in the ProcessWire core. What you @szabesz want I think is a way to create your own controller manifested as a class and tightly integrated in the request lifecycle. But can't you already do that? That is the beauty of ProcessWire. You can alter anything I can think of with hooks. They will allow you to create a fully-fledged controller system if you want to. But again, I feel like ProcessWire handles most of the controller stuff one would ever need.3 points
-
Hi all. Reading through the discussion about page classes, I have to add my two cents. I feel like we are mixing concepts here. We are talking about OOP concepts where the request arises to extend page classes' capabilities to better allow for separation of concerns. Many OOP concepts stem from or are just a fancy form of the MVC pattern. I strongly believe ProcessWire follows such a form too. Whereas the core handles MC and it's API provides endpoints for the V in Model-View-Controller and hooks for extending and altering the C part. So to really allow for separation of concerns, page classes aren't the right place to start off. A page is just the representation of an entity, a line in the database. Instances of said class that is. And thus Page and page classes belong to the Model part of ProcessWire. And this is exactly where my motivation to side with @ryan and his general scepticism of page class init and ready methods comes from. So it makes sense to add virtual properties or basic relationships to the page class. But the model should never contain business logic which acts outside of the lifecycle of the entity. Having made my point so far, I think Ryan's second to add a new class file to act as a controller (by using the ProcessWire's hooks) makes a lot of sense. And exactly that is why I believe, ProcessWire already offers a very good way to enforce MVC patterns and true separation of concerns. It offers a good API without forcing everyone to use the same architectural patterns so many other systems do.3 points
-
Hi everyone ? I have just updated and streamlined my own local development experience. Most importantly, I used to have a custom Dockerfile which resulted in a custom image for every project I ran locally. This has now changed! There is now a GitHub template repository tailored to local development: https://github.com/poljpocket/processwire-docker. This has everything you need to start developing locally on Docker. Some of the features: The composition is set up so that the site folder is fully accessible on the host. You can use any site profile upon first installation. The actual install of ProcessWire is still manual though. I found that there is little benefit in automating this. You can export the database to commit it into your repo and can also import it after pulling changes from upstream. The comp uses my new image for ProcessWire which I just published to Docker Hub: https://hub.docker.com/r/poljpocket/processwire. It uses PHP8.2 via Apache and includes all the PHP extensions needed for ProcessWire. You can find the GitHub repo for it here: https://github.com/poljpocket/processwire-docker-image. There are images for the three most recent stable versions of ProcessWire (210, 227 and 229). Important: I didn't care about security and hardening of the image. It is really only meant for local development. Have fun with it! Any requests and reports are welcome ?, thank you.3 points
-
The cleanest way to do this currently is handling the request and preparing data inside /site/templates/home.php (controller) and then including a view from /site/templates/views/home.php. Using modules such as TemplateEngineFactory, this becomes the default. Prepare data in a PHP file, then render a Twig/Smarty/Latte view. It's certainly not as clean as having a proper controller class pattern available, that's for sure, but it's a pattern that works across projects of all sizes (at least in my experience).2 points
-
I don't think you need a hook. Just use /site/templates/admin.php, and narrow in from there. For instance, if you want to limit to logged in user then if($user->isLoggedin()) { ... } or if you want to exclude ajax requests then if($!$config->ajax) { ... } I'm not sure I fully understand the second scenario you mentioned. But I think you'd have to decide more specifically what this means: "first time user opens the admin while session is still valid from last time". For instance, maybe you want to correspond with a period of time, such as 10 minutes? $delay = 600; // i.e. 10 minutes (600 seconds); $thisTime = time(); $lastTime = $session->get('lastTime'); $session->set('lastTime', $thisTime); if(!$lastTime) { // this is the first request of the session } else if($thisTime - $lastTime > $delay) { // last request was MORE than 10 minutes ago } else { // last request was LESS than 10 minutes ago }2 points
-
@Jonathan Lahijani Preferably use require_once() or include_once(). But if you prefer autoloading, you could add this in your /site/init.php if you wanted to autoload any classes in /site/classes/ that ended with "PageHooks": $classLoader->addSuffix('PageHooks', $config->paths->classes); ProcessWire's class autoloader is more efficient than most, but if you already know a file exists and where it is, I prefer to require_once(). It's more efficient and more clear, nothing hunting for files behind the scenes. There's a reason why this file exists in ProcessWire, even though all of those classes could likely load without it. It makes the boot faster. Class autoloading is obviously necessary for many cases, especially if working with other libraries. But for a case like the one mentioned here, skip the autoloading unless you feel you need it.2 points
-
@ryanThank you very much for the code examples you provided for possible hook options related to PageClasses. Personally like the idea of including a page related hook file following the naming convention concept of PageClasses like PageNameHook.php. Will try some of those concepts soon in a real world project I am working on right now.2 points
-
Hi @Stefanowitsch What I did is to add a hook at Pages::saved which will save the content of the RPB field to a hidden field which then can be queried via regular selectors. Each block had a dedicated method createIndex() which was called in a loop: $blocks = $page->getFormatted(RockPageBuilder::field_blocks); $index = ''; foreach($blocks as $block) $index .= $block->createIndex(); $page->setAndSave('your_search_index_field', $index); The benefit here is that you can define custom markup for each block, for example a headline block could just return this for a search index: public function createIndex() { return "** {$this->title} **\n"; } Does that help?2 points
-
I think I might be thinking of RockPageBuilder: https://www.baumrock.com/en/processwire/modules/rockpagebuilder/docs/quickstart/2 points
-
@cwsoft These methods don't make sense in the core, unless they are to initialize each individual instance of a Page class. But Page classes (like all objects in PW) already have methods for that: __construct() and wired(). As I understand the methods requested here, they are independent of Page instance, so honestly don't belong in a core Page class, and are not something that I think the core should suggest. See what I wrote above for why. Though they are trivial to implement on your own with a static variable should you want it. I'd still advise against it, especially for hooks, but here's an example: class MyPage extends Page { static private $ready = false; public function wired() { parent::wired(); if(!self::$ready) { // your init code... self::$ready = true; } } }2 points
-
@bernhard Good questions and I'll answer according to the design of the core. These considerations are rigid when it comes to what the core does with these Page classes, but flexible outside of that. You are using Page classes in a way that gives them multiple roles. Whether that's good or not depends on your architectural point of view. But it sounds like you are happy with how it's working, and you've got a well defined strategy, and this is valuable. So none of this may useful for your case, so keep that in mind. That sounds okay to me. Why does it load an extra 10-20 pages? Or does that just depend on what pages are used in the request? As long as that magic page interface isn't increasing resource usage each individual Page object significantly, then it should scale just fine. It shouldn't be related to either. It should be independent of environment. A page is a type that aggregates content for a location in the tree. The problem with having front-end-only or admin-only stuff in a Page object is that it's code in the page that steps outside of its role and applies for one environment and not another. It can be seen as a type of bloat, turning a Page object into a jack of multiple trades. If you've got significant code that's just for one environment or another then the idea is that it's better to keep it separate from the Page. Perhaps delegated to a different class like my earlier example (or even a function outside of a class). But if it's just for a one-off case or something then I wouldn't bother. Take that getPageListLabel() method, that's something to represent the Page in the admin only, which is why it makes me uneasy. It's a tradeoff. It's a one-off case, so I think it's okay as long as we don't add more like it. Potentially the method might have front-end value in some cases too, so maybe that's another reason it's an okay compromise. But if we found ourselves starting to put a lot of admin-specific methods in Page classes then those would be better in a separate supporting class or function, or better yet, decouple it from the class entirely. That way it doesn't add code to the page class for something that goes outside its responsibility. Another point is that often code added for one environment or another will be the same between different page classes. To avoid repeating yourself, you'd have to repeat the same methods in multiple classes, or more likely add complexity with more levels of inheritance or traits to share that code. Moving that code to a dedicated class makes it more contextual, maintainable and extendable across multiple classes. There's that word "things" which seems like it might mean "everything" in this context. Here we're treating the Page like it's a Swiss Army knife for the type, rather than the type itself. It's like being the car and the carwash, the lawnmower and the grass, or not just the ball but the bat and glove too. That editForm() method looks like it's got the Page class now involved in manipulating forms in the admin. In that case Page is not just a type representing an aggregate of content, but also a form editor, adding application logic, giving the Page class multiple unrelated responsibilities. Some responsibilities which apply to all instances of the page and others which might only apply to one instance on occasion. If the Page must be the gatekeeper for multiple responsibilities, the idea is that it would be preferable that it delegates those responsibilities rather than implements them itself. That would enable it to provide that interface without expanding the internal role of the class. If you find benefits in using them differently then I'm not suggesting you change anything. Since you asked I have to give you an accurate answer of what Page classes are originally designed for and what I consider best practices around them. These are how the core considers them and doing likewise ensures things stay simple, efficient and scalable in the long term. But in PW flexibility is more important than rules and this is also true of Page classes. There's more than one way to do things well, I like your creativity and if you've found something that works well for your projects over time and scale then stick with it.2 points
-
Hey @ryan first of all let me thank you for ProcessWire in general and for all the work you put into it! Also thank you for mentioning me and my modules. Unfortunately I can second what @jploch said, that it's very hard to offer commercial modules in PW, but that's a topic for another post as this one has gotten very long already ? NOTE: Sorry, this post got very long, but I think it covers some important concepts and I think some of the concepts can really push PW forward on the web-application front. I think it's important to understand the details, so I ask you kindly to read carefully and try to understand the bigger picture ? In this post I'd ask for clarification about what you said about custom page classes attaching their own hooks: I think the phrase "everything necessary" might be worth considering here. A class ideally just has one responsibility. Page instances are there to provide an interface to one page's content and be swapped in and out of memory on demand. When there are things like hooks going into a Page, that changes the role completely. If you start doing this a lot on a large site then it may affect scalability. Maybe it's fine for one individual installation or another, however. I didn't want to believe that, because everything that I've built over the last few years relies heavily on the concept of "MagicPages" which is a feature of RockMigrations and which basically turns every custom page class into an autoload module where you can add hooks that are related to that pageclass. This concept makes maintainability of the whole project a lot easier imho. Before I invented that concept I had quite complex applications and they had hundreds of lines of code in /site/ready.php or /site/init.php; ---------- first some background, later the tests ------------------ ---------- the tests ------------------ ---------------- Very, very long story short: @ryan I'd appreciate if you could explain in more detail why you think it is bad to put - what I'd call - pageclass-related code into pageclasses? Also I'd like to invite you to re-think if it is really bad to have things like "getPageListLabel" in the pageclass. I think this is a great to have these methods and I really enjoy having "editForm($form)" as a shortcut for ProcessPageEdit::buildForm if($page->template == ...) and so on. At the very minimum I'd love to have an init() and a ready() method where we can add hooks as we need them. Thank you very much for reading. I'm sorry for the length, but I hope there was maybe something interesting in it. Please let me know if I did anything wrong with my tests or what I could do better. Thx. Long live ProcessWire ?2 points
-
With huge amounts of gratitude for everything you do to make PW as great as it is: I know this is not in the intended spirit of this thread, so apologies for that, but honestly what I would most like to see is fixing all of the current Github Issues before anything new is implemented. I personally still have 49 open issues, many of which require ugly hook workarounds, some result in things being broken for site editors, and others are inconsistencies in the API which continue to trip me up. I am honestly struggling to put energy into thinking of shiny new feature ideas with these things always impacting my workflow.2 points
-
Fridays are always the days when I'm full-time on ProcessWire. Other days I may be doing client work, or ProcessWire, just depending on the week. This week it's been mostly client work. And I just learned that I'll have to be out of the office tomorrow (Friday) for a family commitment. So I'm writing this weekly update today instead, and just sent out Teppo's great ProcessWire Weekly newsletter with ProMailer today (usually it gets sent Friday). Because of this change in schedule, I don't have much new to report just yet. Instead, I wanted to start talking a little about future plans, so here's a few ideas. I think we should get another main/master version out, perhaps by September. Following that, I thought we should focus on ProcessWire 3.1, or maybe it's time for version 4. What would be in this next major version of PW? For starters, we'll finally drop support for older PHP versions and start taking advantage of all that's been added new newer PHP versions (8+). This will involve lots of updates to the ProcessWire core code base, while remaining 100% API compatible with PW 3.x. I thought that would be a good starting point into our next major version at least. In addition, we'll likely be trimming some things out of the core and into separate non-core modules, such as FileCompiler, CKEditor, the two legacy admin themes, and a few rarely used Textformatter modules. Most likely we'll also have an overhaul of this website and some nice improvements to our primary (Uikit) admin theme to accompany the next major version as well. There will be plenty more too, but this is what I've been thinking about so far. Your feedback is welcome. Thanks for reading and have a great weekend!1 point
-
Output logic is a part of the view. When I build a site profile to share with others my primary goal is to make it as simple and easy-to-follow as possible. For most websites powered by ProcessWire the template files are the views, and that's where I think most should start too, as it's very simple. As needs grow, many will naturally isolate the views to reusable files separate from the template files when it makes sense (like that parts directory in the invoice profile). But I think it's good for PW to be less opinionated about that because people may be using different template engines, different output strategies (direct, delayed, markup regions), etc., or they may not even care about following an MVC pattern, even if PW naturally leads there. This pattern was around before we had web sites/applications, so the "view" part is not like it was when we were building desktop applications in the old days with Borland C++. With HTML we've got server side markup and the additional layers of client side CSS and JS. Not everyone always agrees about where to draw the lines and it can depend on the case. I don't think we should decide that for people and I think it's good to be flexible on on this part of it.1 point
-
I'm creating a star rating system for PW. I haven't found one. I would greatly appreciate your feedback. Star Rating Current Features: IP Checking: Prevents multiple votes from the same user. Displaying Stars and Rating Form: The star ratings are displayed on the pages with shortcode. Average Rating Calculation and Vote Counting: Calculates the average rating based on the votes. Known Bug: Currently the stars are not highlighted when a user hovers over them. Plans: Improved Styling: Enhance the visual appeal and user interface. AJAX Support and Feedback: Implement AJAX functionality to allow submiting ratings without page reload. Add a feature to provide users with immediate feedback after submitting their rating Structured Data Schema Support: The ratings are picked up by search engines for rich snippets, enhancing SEO and visibility. Cookie Checking: To further prevent multiple votes. Usage: The database table star_ratings is created during the installation. When you uninstall it drops the table. Add the following shortcode to the desired location within your template: <!--StarRatingForm--> StarRating.module.php1 point
-
I'd probably approach that with a hook on User::unpublished, perform the checks there whether the user is staff and referenced from a client account, and send a message (through PW's message system or even other means like a ticket system or email).1 point
-
In AdminDevModeColors, I hook onto AdminTheme::getExtraMarkup, but that's probably not much different from your approach.1 point
-
Since it came up in this question and I had some time to kill in front of my computer waiting for updates to finish which I had to verify, I got curios whether copy & paste from Word on Windows into a TinyMCE editor field could be made to insert the formatted text and keep the images. Surprisingly, with the help of rtf.js, this went pretty quickly. Ryan already built automatic upload functionality (called ImgUpload) into the TinyMCE field, so I only had to enable the option and select a target field. Even though pasting word processor generated HTML is and always has been a sin, I built a small module for it anyway. I called it (I know, it sounds a bit clunky, but it was the best I could come up with, I'm a backend guy): RtfPasterTinyMce Usage Download the contents of this repository and unpack into a folder in site/modules Open ProcessWre admin and select Modules -> Refresh Click "Install" for "Rtf Paster TinyMCE" Go to "Fields" and select your TinyMCE field where you want to paste office content including images Check "rtfpaster" in "Additional plugins" on the "Input" tab and save your field configuration Edit a page with that field and copy a passage that contains both text and images from MS Word into your TinyMCE field. You should see your images there. Advanced Go into InputfieldTinyMCE's module settings and enable "Image fields for ImgUpload" Edit your TinyMCE field and select an existing image field in the "Image fiels for ImgUpload" select on the Input tab Paste some text / images mixture from your word processor MS Word Tadaa! Your images are magically uploaded into the selected field. Since the RTF doesn't contain any information about the file name of the source image, your uploaded images will be named fieldname.png, fieldname-1.png, fieldname-2.png etc. Keep in mind that this is so far a proof-of-concept module and hasn't been tested with different scenarios and source applications yet. Don't use it in production unless you feel confident to fix any errors yourself! Edit: Only successfully tested with MS Word. Not working with LibreOffice's RTF.1 point
-
1 point
-
@ryan In my original reply to this post I mentioned making PW a bit stronger for web application development. After reading these replies, it seems that a lot of the more intricate techniques that would be desired for advanced use cases are already possible natively, but even those of us here that I would consider highly experienced with PW and OOP are still picking up a few crucial nuggets of information that go a long way in structuring a web application with PW (at least it seems that way). So to elaborate on what I stated originally, I think demonstrating how you would approach some of these advanced techniques natively in PW (showing that a feature request to make it "nicer" is not necessary / technically problematic) in a real working app would be very helpful. I believe you attempted this with the site-invoices profile and building it out further with more web-application-y type techniques would really be great.1 point
-
1 point
-
My main wish for ProcessWire 4 would be a generally more modern admin theme (e.g. with Ajax-Save unpoly/htmx style) and that at least fields that are also used in the frontend (FormBuilder) no longer have a jQuery dependency. On the subject of jQuery, it would also be great if the updates announced last year could also be activated for live pages in the next major release.1 point
-
Please no ? To elaborate, there are a couple of issues with this: Depending on how this is implemented, it could be a major turn-off for users like me, who have never (and likely will never) click that "download" link on the website, let alone use a configuration tool to get a download package. Most of the time I'm installing ProcessWire via Composer or by cloning it via Git, and obviously my wish would be that this process isn't made more complicated. On the other hand I've seen some users (beginners) kind of trip on things like "you'll have to install a module to get Repeaters working" or "you need to get a separate site profile". As such, I don't think this would necessarily be a good idea considering new users either. A configuration tool would likely be interesting mostly for advanced users, who know exactly what they want... and prefer to use a download link on a website to get it, which (I would assume) somewhat limits its usefulness. That being said, as long as I can still get a "viable" version of ProcessWire (most of what's currently in the core, and future additions as well, assuming that they are meaningful ones — which they undoubtedly will be!) without having to use a configuration tool, I of course don't mind if it is added as an additional option. If someone likes that kind of thing, then great, why not! Also if this would mean that non-essential core modules could be also installed one by one via Composer, that would be nice ? What I'm missing here is the context: is this about getting a smaller downloadable package? Is that still a thing, e.g. is it really a problem for many users? Serious question, because I really don't know. I care a lot about performance on websites, but have never considered the download size of a CMS I'm using; unless it's in gigabyte range or something crazy like that. Or is it about dropping support for some core features? I'm not getting that vibe from here either, but that would make more sense to me, though in that case it might be better to just drop them from the core and perhaps find new maintainers for the packages if possible ? Or is there some other benefit I'm missing?1 point
-
I lost 85% of our clients to WordPress due to page builders like Elementor. They aren't concerned with code clutter, page speed and SEO disadvantages. I would love some offerings in that direction, I am aware that this maybe will open Pandora's box. Some praise here for ProcessWire: ProcessWire is unbeatable for websites that almost work as applications. We coded the whole backend office management for our web design firm with ProcessWire including tons of SEO-, Data protection-monitoring- and wp-plugin-updates-montitoring crawlers and checkers: We kind of remote control WordPress from ProcessWire. Clients can log in and see everything they booked at a glance, and can order things directly from ProcessWire, and it is directly connected to the invoicing app. This is a unique system, 10 years of work in it and now makes the entire company manageable by a minimal team, unthinkable without ProcessWire. Thinks I would like in PW4 are things I am used to from WordPress, a full switch to utf8mb4, those needed GDPR utilities out of the box, modules can be "deactivated" leaving the settings intact, and "removed" to make troubleshooting modules compatibility issues much easier. Some image optimization capabilities would be great, the existing 3rd party modules do not meet our expectations yet. Also a good monitoring/curation of outdated/abandoned modules, with supplied warnings, would be great; there are a lot of those old modules, unfortunately.1 point
-
It's actually sort of on the list for the projects we work on together Ryan, just I think the client is talking to me about it rather than give you another chunk of work to think about. Might be worth us discussing it next week.1 point
-
I would like to see SEO support integrated into PW by default. I know that there is the SEO Maestro module, which is fabulous, but I think every CMS should have a good SEO support by default. So it would be great if a new tab will be added to the pages like this: In addition to this, there should be a new property inside the configuration file to disable/enable the tab globally in the way like this. $config->seo = false; // or true And in the settings of the page, there could be a checkbox to enable/disable the SEO tab per page. The content of the SEO tab could be as it is in the SEO Maestro module.1 point
-
Thank you for all of the feedback! Definitely want to build more e-commerce, but just not in the core. I'm intrigued by what Jonathan mentioned and want to learn more. I suspect it influence the roadmap quite a bit. Would enjoy building an asset manager but since my clients don't need it, I could only build it by self funding it. I don't have the ability to self fund it yet. Agree PW should continue to grow on the framework side in the next major version. I don't know in what ways specifically just yet (feedback welcome), but am stating my agreement. I think we've been on a good path in this regard so far and should keep going / go further. Don't agree that Page objects need more initialization methods, but let's duke it out. ? Agree we could use a new site profile, preferably a professionally designed one. Agree we'll definitely continue improving the admin theme and maybe even add another. Prefer to avoid features that blur the line between content and style or front-end and admin, though there can always be exceptions. The requests for Inputfield/InputfieldWrapper sounded good. Supporting more DB platforms is also on my wishlist, but not sure it can be done in the next year as there are some challenges there. Note: replaced original/longer post with summary/bullet points.1 point
-
Would be great to see .env support. I think this base change would level up ProcessWire and make it an increasingly viable application framework that fits into modern workflows. I think this would be a great idea. It would greatly help module development where modifying or appending behavior to existing elements is needed. I could see that having been useful when developing my Fluency module. I'll throw a thought in about multi-site capability after considering multi-tenancy for a Laravel project using a module. May be a nice feature but if there's a tradeoff for future features and development speed due to maintenance overhead, both for ProcessWire core and modules, it may not pencil out. I know it's not apples to apples, but creating two sites and a private API between them has worked for me in the past.1 point
-
My suggestion would be to add a native global media manager and native multidomain support Media Manager: - Global management of images (also SVG) and Documents (e.g. PDFs) with a decent UI, Preview-Thumbnails, the possibility to organize the assets in folders, etc. - A field to reference those assets, with a usable UI and the possibility to define starting folders, e.g. having a field which only allows to select from a folder with employee portraits, etc. - References should be managed automatically, so one can't delete an image which is still referenced anywhere - If an image is not referenced anywhere anymore, there should be a dialog which asks, if one wants to delete the asset OR there could be a cleanup feature to find and delete unused media items - and so much more ideas, but the global management and the reference field with visual image preview in a clear UI would be great Multidomain Support: - Manage multiple Websites with different domains within one ProcessWire installation, with optional multilanguage support - Every website has a root parent page in the page tree, where everything is defined: domain name, language, etc. - Internal links will be managed by ProcessWire, so you can link between the domains. ProcessWire would determine if the links have to be prefixed with the domain name automatically - The root parent pages will be fully abstracted away, e.g. their page names won't be applied to urls I think that we really would need a native implementation of those features. Unfortunately, I don't have the time or expertise to develop them myself and make a PR, but I would like to add them to the wish list. And if they would be implemented, I would be happy to contribute ideas, feedback and provide beta testing.1 point
-
Before I find time to add my very own wishlist let's not forget the PW requests repository1 point
-
It doesn't come up all the time for me (depends on the site) but often enough that I agree with others that re-using images on other pages is important. I rarely insert them into the editor - that's my problem. How could we have an image from a different page's single/multi-image field be used in another page's single/multi image field because that's how I would need to use that feature? Maybe next to the upload button have another button to select existing from another page (or media manager - I like that idea) and it's inserted into that field as a reference and can have it's own description, tags etc. Likely others have already talked about this a lot over the years whereas I've just ignored it and duplicated my images quite a few times ? I think though that this is where storing images in folders by page ID would maybe need to be replaced with something else to uncouple them from page IDs on disk, like maybe files/field id/ instead though granted that would be complicated for an existing site with thousands of images already on it. They'd also need to be grouped under the field ID as on a travel website /files/photos (as an example) could have 10k files or a lot more with variations under it easily. Not sure that's actually a problem though - feels like it might have been 10 years ago but maybe it's not now. If you wanted though you could have a subfolder per image ID for that field to store it and all variations neatly which somewhat alleviates the issue.1 point
-
Excited to see thoughts about starting work on ProcessWire 4. PHP 8+ bring so many improvements, would be nice to utilize them. My personal pain points and wishlist for ProcessWire: - a global media manager - more official integration of multi site / multi domain capabilities (in my case especially for the one database, multiple roots option) - admin theme improvements: - a permanently visible page tree to quickly jump between pages - more ways to customize it, depending on the applications needs. Like having a predefined place to add a "website select" for multi domain websites. - quick mockup, based on www.clickup.com. Clickup also has a "task bar" where you can put pages that you want to come back to. That's quite handy as well. - from a tech point, some things that could be nice to have, but most likely not feasible and against the philosophy of ProcessWire because it would most likely make the project more bloated: - better utilization of composer, e.g. having the ProcessWire core and admin package as separate composer packages, so a ProcessWire installation would just have a "site" and a "vendor" directory - PSR standards / framework ineropability where it makes sense - some automated tests, at least for the core api @Jonathan Lahijani+1. We're using it for application development and it works very well if there is not too much data involved (with 10,000,000+ pages you'll start to having to search for workarounds to keep things fast, in my experience). Would be nice to hear what would be your ideas for improvement. A more web-application like and customizable backend would be nice for us as well. In some projects we were able to hack and hide everything that was not needed. In other projects we build a custom admin panel. Then a way to render a form for a full template in the frontend would have come in handy several times already.1 point
-
I'd like to second this. It would be great if the new/improved admin theme was built with maximum customisability in mind. One use case is so that we can more easily offer a "mostly-frontend" user an admin experience that's radically different to what a superuser or site administrator gets in the uncustomised admin. Another admin customisation issue I've struck recently is when you want to customise markup for InputfieldWrapper. There's InputfieldWrapper::setMarkup() but this is marked as internal and isn't that practical to use because InputfieldWrapper::markup is static. That means any custom markup you set there persists for all InputfieldWrappers that are subsequently rendered, when what I want to do is customise markup for a specific instance of InputfieldWrapper. Edit: pull request When the admin theme is revisited it would be great to ask of each component that's rendered, "Is there an opportunity to make this rendering customisable?"1 point
-
I'd love to see an "officially supported and recommended (and even documented) way" of initializing custom page class objects, discussed and requested by us over the years: https://github.com/processwire/processwire-requests/issues/456 https://processwire.com/talk/topic/30138-page-classes-diving-into-one-of-processwires-best-features/?do=findComment&comment=242737 https://processwire.com/talk/topic/25342-custom-classes-for-page-objects-the-discussion/1 point
-
Generally speaking this is already possible. The syntax is: !your_field_name^=foo Paths are a special case though because these are only searchable when the PagePaths module is installed and that module doesn't support this kind of negation: But I don't think this actually matters because there is a dedicated selector option for when you want to find pages that do or do not have a particular ancestor, and that is "has_parent": https://processwire.com/docs/selectors/#finding2 So rather than needing anything like... ...you can instead do... has_parent!=/foo/|/bar/|/baz/1 point
-
Ok, found it out... In the init-function of my module, I call $this->modules->get('JqueryUI')->use('modal'); Then I simply add «pw-modal» as a class to my link to the field-editor and viola, it opens in a modal window... Link for a new Field looks like this: <a href="/processwire/setup/field/edit?id=new&fieldgroup_id=new&modal=1&process_template=1&name=myTestField" class="pw-modal addNewField">New Field</a>1 point