Jump to content


Popular Content

Showing content with the highest reputation since 01/21/2020 in all areas

  1. 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.
  2. 20 points
    ... and everything went silky-smooth. I finally got around to update a small portfolio site from PW 2.3 straight to latest dev. I spent roughly one hour, tested everything, and hey: no major hassles. I updated the few modules I used (and installed some new ones like Tracy or AoS), updated PHP as well, and that was more or less it. Imagine having such an un-touched WP, Typo3 or MODX site, and updating straight to the latest version... What a nightmare. That is - if they would actually still run that long 🙂 I actually expected it to go as smooth as it did, but I'm always surprised and in awe again when I do such a big update. Thank you ProcessWire.
  3. 17 points
    I'm currently building a Fieldtype/Inputfield for selecting date and time ranges (eg for events). There was quite some interest in this thread, so I thought I start a dedicated discussion... Background: I guess everybody of us knows the problem: You want to present events on your website and you start with a new template and a title and body field... For events you'll also need a date, so you add a datetime field called "eventdate". Maybe the event does not take place on a specific day but on multiple days, so you need a second field... Ok, you rename the first field to "date_from" and add a second field called "date_to". So far, so good. Then you want to list your events on the frontend. Simple thanks to the pw API, you might think. But you realize that it's not THAT simple... Which events take place on a specific day? What would the selector be? Yeah, it's not that complicated... it would be something like: $from = strtotime("2020-01-01"); $to = strtotime("2020-02-01"); $events = $pages->find("template=event, date_from<$to, date_to>$from"); Why? See this example, where the first vertical line represents the $to variable and the second is $from: The start of the event must be left of $to and the end must be right of $from 🙂 Ok, not that complicated... but wait... what if the date range of the event (or whatever) was not from 2020-01-18 to 2020-02-25 but from 18 TO 25 (backwards)? The selector would be wrong in that case. And did you realize the wrong operator in the selector? We used date_to>$from, which would mean that an event starting on 2020-01-01 would NOT be found! The correct selector would be >=$from. That's just an example of how many little problems can arise in those szenarios and you quickly realize that the more you get into it, the more complicated it gets... Next, you might want to have full day events. What to do? Adding a checkbox for that could be a solution, but at the latest now the problems really begin: If the checkbox is checked, the user should not input times, but only dates! That's not possible with the internal datetime field - or at least you would have to do quite some javascript coding. So you add 2 other fields: time_from and time_to. You configure your date fields to only hold the date portion of the timestamp and show the time inputfields only if the "fullday" checkbox is not checked. We now have 5 fields to handle a seemingly simple task of storing an event date. That's not only taking up a lot of space in the page editor, you'll also have to refactor all your selectors that you might already have had in place until now! Idea So the idea of this module is to make all that tedious task of adding fields, thinking about the correct selectors etc. obsolete and have one single field that takes care of it and makes it easy to query for events in a given timeframe. The GUI is Google-Calendar inspired (I'm acutally right now liking the detail that the second time input comes in front of the date input). I went ahead and just adopted that: Next steps I'm now starting to build the FINDING part of the module and I'm not sure what is the best way yet. Options I'm thinking of are: // timestamps $from = strtotime("2020-01-01"); $to = strtotime("2020-02-01")+1; // last second of january // option 1 $pages->find("template=event, eventdate.isInRange=$from|$to"); $pages->find("template=event, eventdate.isOnDay=$from"); $pages->find("template=event, eventdate.isInMonth=$from"); $pages->find("template=event, eventdate.isInYear=$from"); // option 2 $finder = $modules->get("RockDaterangeFinder"); $finder->findInRange("eventdate", $from, $to, "template=event"); $finder->findOnDay("eventdate", $from, "template=event"); ... I think option 1 is cleaner and easier to use and develop, so I'll continue with this option 🙂 Future As @gebeer already asked here I'm of course already thinking of how this could be extended to support recurring events (date ranges) in the future... I'm not sure how to do that yet, but I think it could make a lot of sense to build this feature into this module. I'm not sure if/how/when I can realease this module. I'm building it now for one project and want to see how it works first. Nevertheless I wanted to share the status with you to get some feedback and maybe also get your experiences in working with dates and times or maybe working with recurring events (or the abandoned recurme field). For recurring events the finding process would be a lot more complicated though, so there it might be better to use an approach similar to option 2 in the example above.
  4. 17 points
    Last Saturday we started getting hit with heavy traffic at the processwire.com support forums, and it soon became a full blown DDOS frenzy. This post describes all the fun, how we got it back under control, and what we learned along the way— https://processwire.com/blog/posts/driving-around-a-ddos-attack/
  5. 14 points
    This module is (yet another) way for implementing a cookie management solution. Of course there are several other possibilities: - https://processwire.com/talk/topic/22920-klaro-cookie-consent-manager/ - https://github.com/webmanufaktur/CookieManagementBanner - https://github.com/johannesdachsel/cookiemonster - https://www.oiljs.org/ - ... and so on ... In this module you can configure which kind of cookie categories you want to manage: You can also enable the support for respecting the Do-Not-Track (DNT) header to don't annoy users, who already decided for all their browsing experience. Currently there are four possible cookie groups: - Necessary (always enabled) - Statistics - Marketing - External Media All groups can be renamed, so feel free to use other cookie group names. I just haven't found a way to implement a "repeater like" field as configurable module field ... When you want to load specific scripts ( like Google Analytics, Google Maps, ...) only after the user's content to this specific category of cookies, just use the following script syntax: <script type="optin" data-type="text/javascript" data-category="statistics" data-src="/path/to/your/statistic/script.js"></script> <script type="optin" data-type="text/javascript" data-category="marketing" data-src="/path/to/your/mareketing/script.js"></script> <script type="optin" data-type="text/javascript" data-category="external_media" data-src="/path/to/your/external-media/script.js"></script> <script type="optin" data-type="text/javascript" data-category="marketing">console.log("Inline scripts are also working!");</script> The type has to be "optin" to get recognized by PrivacyWire, the data-attributes are giving hints, how the script shall be loaded, if the data-category is within the cookie consents of the user. These scripts are loaded asynchronously after the user made the decision. If you want to give the users the possibility to change their consent, you can use the following Textformatter: [[privacywire-choose-cookies]] It's planned to add also other Textformatters to opt-out of specific cookie groups or delete the whole consent cookie. You can also add a custom link to output the banner again with a link / button with following class: <a href="#" class="privacywire-show-options">Show Cookie Options</a> <button class="privacywire-show-options">Show Cookie Options</button> This module is still in development, but we already use it on several production websites. You find it here: https://github.com/blaueQuelle/privacywire/tree/master Download: https://github.com/blaueQuelle/privacywire/archive/master.zip I would love to hear your feedback 🙂 Edit: Updated URLs to master tree of git repo
  6. 13 points
    This is an update about how it's been running blog sites using ProcessWire. I hope it's OK for me to post in this category even though I've already showcased my sites awhile back. I thought it would be helpful for people to get a feel for what it's like to use ProcessWire on an ongoing basis for blogging. Often people talk about the development of a site, but it's not quite as often that we hear about the ongoing running of a PW site and how the PW API influences that, which is what I'll cover here. As background, we at The GrayFly Group own and run the blogs goodkidsclothes.com and flipfall.com. The development of these PW sites has been covered in a showcase thread for GoodKidsClothes and another for FlipFall. Here are some of the unique experiences I've had running these two sites. "Running" covers everything from coding and making modifications to the templates, to writing our articles, to interacting with ad partners or with others seeking us out for something related to one of those sites. So this is a different experience from agencies who develop for others; we develop for ourselves. As background, the main traffic to the websites comes from organic search results. Income from sites is from affiliate marketing and advertisements. GoodKidsClothes PW experience: "to think it is to do it." For GoodKidsClothes.com, one of the things we noticed was that if we could think it, we could do it, thanks to the easy-to-use PW API. The need for a change Here is a concrete example of what I mean: we noticed that many people would enter the site on an older article (e.g. via a search result). However, we continually put out a lot of time-sensitive information, e.g. a style guide, a piece of news relating to a change in a children's clothing company, etc. I didn't want people to miss out on this, yet many were, because after reading their entry page, they'd leave. They had no idea (unless they clicked on the link to home page) that there was another article that could be of value to them. All too often, by the time people learned about that new article via search results, they'd be too late for the news to be relevant - in fact, it wouldn't even be the newest article anymore by that point. The solution So, using the PW API, we modified the article template so that if someone was reading any article that was not the most recent article, then at the end of what they're reading, they'd see a small section highlighting the most recent article. Here is a screenshot: As you can see above, our newest article is highlighted immediately below the article they're reading, unless of course they are already reading the newest article. In the case shown above, the newest article (recipe-related) did not happen to be time-sensitive, but in most cases that article would be time-sensitive, so that's why we made this change. To make the change we simply used the PW API to query what the latest article was and store its identity in a variable - those sorts of queries we set up in _init.php. Then we modified the article template such that if the current page was not the latest article, to include the featured box that you see above. Another need for a change You'll also notice links in boxes above and below where the featured article box is. These are ads (they blend OK right?!) These ads brought another problem to our attention: we'd put the ads blocks on all articles equally. However, in the case of the most recent article, often the most recent article would usually have a time-sensitive offer or some other call to action e.g. signing up for our newsletter (well, not in the case of the recipe article above, but in most cases the latest article would have something we prefer the reader to do). We didn't then want our readers to get distracted by the ads and either leave the site, or click on an ad and click away from the site, instead of doing whatever the call to action is. The solution Again using the ProcessWire API, we modified the "article" template so that there was conditional logic on the ads: if the current page is not the latest article, include the ad code (otherwise no ads). This mean no ads were seen on the most recent article, allowing for less distractions to the reader on time-sensitive articles and more likelihood of them following through on the call to action. Conclusion for GoodKidsClothes We were able to make all these changes within minutes of thinking of them! In-house, without a ton of knowledge of programming, thanks to the awesome ProcessWire API. We actually made all those changes live, i.e. going in there and making changes to the code of the site as its running live. Yes, we had backups of the entire site and we always first save a copy of the template file under a different name (usually prefixing it with OLD_ ) before modifying the live version. This is how helpful ProcessWire is. We can make changes that benefit our site and make them in-house as we think of them. If this was done under some other CMS, we would be unable to make those changes without either a) hiring a developer or b) training up in whatever the other CMS is to make the changes in-house. Either way, it would take considerably more time to do anything. So, despite not having a formal programming background, we now have a very "nimble" site that we can adapt as needed to changes that we desire, within minutes of thinking of the change we need, with only needing to know a little PHP, html, and CSS, just the very basics, and looking up the PW API. FlipFall PW experience: "the answer is yes." In the case of FlipFall, there have been times when a potential ad partner asks a question like "can you put different ads on different categories?" or other things. Sometimes they are questions I ask myself of the website "Can we do A/B testing of different ads; i.e. show a certain ad block 50% of the time totally randomly and another ad block the other 50% of the time?" "How about ads from this company some of the time and a different company other times?" The answer is always "yes." Coming from other CMS's (that I used but did not program with) I used to brace myself a bit if I saw an email that asked "Can you....?" but now thanks to ProcessWire I don't have that bracing reaction any more. So long as I can think of a way to do it (and so far I always have, thanks to the PW API), I can say "Yes we can." More to the point, I can actually say "Yes, we can make those changes in-house within [whatever brief timeframe I think it will be]" instead of having to be vague about timeframes because of needing a developer. So I no longer worry about "Can you ...?" questions because the answer is yes. Overall conclusions ProcessWire is a superb CMS for those who own and run a site. The PW API makes it easy to make changes to the look and functionality of the site as needed. Such modifications wouldn't easily be possible on alternative CMS's that are heavily "theme-based".
  7. 13 points
    I hope that you all have had a great week! I’ve got several commits to the core on the dev branch this week, with both improvements and fixes. I’m going to save the version bump to 3.0.150 till likely next week, when there should be more to write about. In addition to working on and supporting the core and modules here, I’ve been collaborating with Pete (forum admin) on a client project in ProcessWire. It’s keeping us both pretty busy, but I really value and enjoy the opportunity to develop sites in ProcessWire—it’s always a nice change of pace to develop something using ProcessWire, in addition to developing it. And it’s also a real pleasure to collaborate with Pete, he does amazing work. While working on this project, I’m still very much focused on core and module updates, but emphasizing smaller core updates like fixing issues and making incremental improvements to existing parts of the core (like in this week’s commits). Once we finish the first phase of this project (mid February), then I’ll be focusing on some larger updates and additions (and the related blog posts). Thanks have a great weekend!
  8. 12 points
    I was tired of adding 6 different fields to an event-template just for storing the time range of the event... 😎
  9. 11 points
    This is a new module that provides a simple solution to clearing all your cache layers at once, and an extensible interface to perform various cache-related actions. The simple motivation behind this module was that I was tired of manually clearing caches in several places after deploying a change on a live site. The basic purpose of this module is a simple Clear all caches link in the Setup menu which clears out all caches, no matter where they hide. You can customize what exactly the module does through it's configuration menu: Expire or delete all cache entries in the database, or selectively clear caches by namespace ($cache API) Clear the the template render cache. Clear out specific folders inside your site's cache directory (/site/assets/cache) Refresh version strings for static assets to bust client-side browser caches (this requires some setup, see the full documentation for details). This is the basic function of the module. However, you can also add different cache management action through the API and execute them through the module's interface. For this advanced usage, the module provides: An interface to see all available cache actions and execute them. A system log and logging output on the module page to see verify what the module is doing. A CacheControlTools class with utility functions to clear out different caches. An API to add cache actions, execute them programmatically and even modify the default action. Permission management, allowing you granular control over which user roles can execute which actions. The complete documentation can be found in the module's README. Beta release Note that I consider this a Beta release. Since the module is relatively aggressive in deleting some caches, I would advise you to install in on a test environment before using it on a live site. Let me know if you're getting any errors, have trouble using the module or if you have suggestions for improvement! In particular, can someone let me know if this module causes any problems with the ProCache module? I don't own or use it, so I can't check. As far as I can tell, ProCache uses a folder inside the cache directory to cache static pages, so my module should be able to clear the ProCache site cache as well, I'd appreciate it if someone can test that for me. Future plans If there is some interest in this, I plan to expand this to a more general cache management solution. I particular, I would like to add additional cache actions. Some ideas that came to mind: Warming up the template render cache for publicly accessible pages. Removing all active user sessions. Let me know if you have more suggestions! Links https://github.com/MoritzLost/ProcessCacheControl ProcessCacheControl in the Module directory
  10. 11 points
    In an ongoing effort to provide a sort of case study, and more info about this, I'll post random screens and info about the various features of this site. (1) Custom Dashboards The site uses a custom module that supports multiple dashboards. Any given dashboard is configurable and access controlled also. This is the main dashboard: (2) The admin editor pages take advantage of some great modules, namely RuntimeMarkup @kongondo, PageFieldInfo @Robin S, Field Descriptions Extended and more, There is also a new module not released yet called Admin Comments, which for this project got a lot of use. When dealing with a large and complex data collection as was the case with this project, the editors benefited from the ability to have the data auto-analyzed on each work so the "auto flags" field helped with that. The comments also allowed editors to post information, ideas and comments right into the page editor. The AdminComments module also provides the option for any posted comment to be emailed to the other team members (selectable), and the notification email (which is customizable) allows the recipient to click directly to the editor for that page. This saved incalculable hours of work, and enhanced communication during the project, across this large data set.
  11. 9 points
    Hi guys, I was very excited for this module, but my life took a huge direction change and I no longer have the time to invest in module development. I am gonna leave the files here. You guys can take it and run. Maybe there might be something useful here. Maybe not. I still think it's a good idea to do drag and drop modal building in PW. So hopefully one day something like that can come to light. I love this community and I love ProcessWire. Live long and prosper. - Joshua Designme 2.zip
  12. 9 points
    Inputfield Selector Select ID Uses the Page List Select inputfield for user-friendly input of page IDs into Inputfield Selector. Overview This module adds a feature to Inputfield Selector, which is most commonly seen in Lister (Find) and Lister Pro. When adding a filter row for "Parent", "Has parent/ancestor" or "ID" the user is expected to enter a page ID to match against. But this is not as user-friendly as it could be because the user may be able to identify the desired page by its title or location in the tree but not know its ID. This is particularly the case for site editors who may not even understand the concept of a page ID. So this module adds a thunderbolt icon to relevant rows in Inputfield Selector. When the icon is clicked a Page List Select inputfield opens in a modal window, allowing the user to visually select a page from the tree. When the modal is closed with "OK" the ID of the selected page is inserted into the filter row. Tip After a page selection has been made in the modal window the "OK" button will automatically receive focus so if you prefer you can close the modal by hitting the Enter key rather than mousing to the OK button. Installation Install the Inputfield Selector Select ID module. https://github.com/Toutouwai/InputfieldSelectorSelectID https://modules.processwire.com/modules/inputfield-selector-select-id/
  13. 8 points
    Heya! Just wanted to drop a quick note here regarding this point 😊 I get why you feel that this is a problem and "an ivory-tower approach to things", but it's worth keeping in mind that with all design decision you'll get some benefits, but also some drawbacks. In systems where there's no "true" tree structure (some CMS products have gone this route) this would likely be an easy thing, but since ProcessWire is indeed hierarchical, it's going to need a bit more work. At the same time the structure in ProcessWire is predictable, efficient, and works great when a site consists of a variety of different content types. I've worked with other types of systems as well (including WP), and would choose PW's hierarchy any day over any of the alternatives. Regarding "switching the root", I've run into something similar once, and that's after being around PW for almost a decade and having built, maintained, and rebuilt quite a few ProcessWire sites in that time. What you're asking for may seem like a simple thing, but it's really not (given our context), and it's also quite a rare request — if it wasn't, it'd probably make sense to give it more consideration at core level 🙂 To give you a bit of context, this is roughly the same as a Linux user stating that "I just need to switch the system root, it's an easy thing right?". Well, you can do that as well, but it's really not an easy thing, and may in fact be very destructive (unless you know exactly what you're doing). Again, design decisions; you may disagree with them, but the fact that this issue rarely comes up tells me that this particular design decision was likely a good one. Just my five cents 🤷‍♂️
  14. 8 points
    I worked hard on the module the last days, and rewrote much of the core logic and added some more features. I wanted to record a screencast yesterday, but my recording software ignored my mic. So I show you some annotated screenshots instead. Since then, many things changed again. Right now I am working on downloading and installing a module via a URL, and also making a transition to modal dialogs instead of panels, if applicable. I moved the whole button logic from the PHP script to a vue component. So I am flexible how to display the buttons, and I can reuse them in the cards and in the table layout: I added a reduced card layout, which moves the description of a module into the "more information" accordion: Updated TODOs with much more features to come. I will work on the module in the next 2 days and hope to make so much progress, that I can finally release the first version on github.
  15. 8 points
    We've been expieriencing high load for some reason for the past 12+ hours though not sure where it's coming from as yet. As a result the site has been slow/showing error messages. The site and forums are up for now but please bear with us whilst we investigate.
  16. 8 points
    UPDATE 2020-01-30 SnipWire 0.8.0 (beta) first public release! It is done! After almost 1 year of hard work and a lot of help from the usual suspects I just released the first public version! Please note that this is still a beta so please test, test, test before you use this plugin in a real project. The module can be loaded via PW modules directory (just submitted - in review I think) or directly via GitHub. More infos will be added soon ...
  17. 8 points
    @Jens Martsch - dotnetic, @rjgamer, @teppo, @szabesz, @erikvanberkum, @dragan, @Lutz, @eydun, @psy, @horst, @cstevensjr, @tpr Just tagging in those who have reacted/responded to this topic in order to bring your attention to the notice above. Please don't uninstall but update to v0.2.1 or greater ASAP. Again, my apologies for the error. The intention was to have the module clean up after itself on uninstall but it's just too risky.
  18. 7 points
    Even though not officialy supported by PW3 I've used this module in the past successfully: https://processwire.com/talk/topic/711-release-schedulepages/
  19. 7 points
    Greetings, I think you hit right at the point here. If people come to ProcessWire seeking a plugin-dependent, template-based system, they will have problems with it. (Of course, it's also not quite right to compare ProcessWire to Laravel, but that's at least a closer comparison). Over the past few years, I've treated ProcessWire like a Framework that includes built-in admin enhancements. My clients actually really like the default admin interface for most of their sites -- including those who came from WP. Now, comparing ProcessWire to SquareSpace (or any of the other "site builders") is ridiculous, and anyone who makes that comparison is revealing their ignorance. With all that, I'll still say what I've said for years: ProcessWire should be openly discussed as a hybrid framework/CMS. That way would reduce misunderstandings like that of this reviewer. Matthew
  20. 6 points
    module is also now in the modules directory at https://modules.processwire.com/modules/modules-manager2/ Still pending
  21. 6 points
    You can't, without running into major headaches, change the root page (i.e. "Home"). What you can do is create a copy and move all children with the exception of the system fields (admin, trash, 404) under the new home. Then you can adapt the Home page to your liking (i.e. switch template, edit contents, whatever). Here's a small script that automates that task. This hasn't been tested extensively, so I don't advise to run this on a production system, only on a copy (or at the very least make a test run on a copy and then make sure you have a full, working database backup at hand). You can copy this code into a script (e.g. as "clonehome.php") in your PW installation root and run it from the command line. <?php namespace ProcessWire; if(PHP_SAPI != 'cli') exit; include('index.php'); error_reporting(E_ALL); ini_set("display_errors", true); /* ************************************************************** * CONFIGURATION FOR CLONING * *************************************************************/ $adminUser = "admin"; // PW Backend User $childrenToLeave = [ $config->adminRootPageID, $config->trashPageID, $config->http404PageID = 27 ]; /* ************************************************************** * END OF CONFIGURATION * *************************************************************/ $session->forceLogin($users->get($adminUser)); $home = $pages->get($config->rootPageID); echo "Cloning Home" . PHP_EOL; $newOldHome = clone $home; $newOldHome->setQuietly('_cloning', $home); $newOldHome->addStatus(Page::statusSystemOverride); $newOldHome->removeStatus(Page::statusSystem); $newOldHome->removeStatus(Page::statusSystemID); $newOldHome->id = 0; $newOldHome->setIsNew(true); $newOldHome->parent_id = $home->id; $newOldHome->of(false); $newOldHome->set('numChildren', 0); $newOldHome->removeStatus(Page::statusSystemOverride); $pages->save($newOldHome, ["quiet" => true]); echo "Home page cloned, new id is {$newOldHome->id}." . PHP_EOL; $childrenToLeave[] = $newOldHome->id; echo "Moving children:" . PHP_EOL; // Now move all children, with the exclusion of admin tree and special pages (404, Trash) // as configured in $childrenToLeave foreach($pages->find("parent=$home, include=all") as $child) { if(in_array($child->id, $childrenToLeave)) continue; echo "- {$child->name}..."; $child->of(true); $child->parent = $newOldHome; $child->save(); $child->of(true); echo "[X] Done" . PHP_EOL; } echo "FINISHED. All children moved." . PHP_EOL;
  22. 6 points
    I have found this library quite useful in the past. If you are going to support recurring dates, please take a look at the inputfield interface for recurme (it works quite nicely), but please make sure if you implement momentjs for any part of that process be sure to use the timezone version of it. I also think the ability to output recurring dates using RRULE (https://icalendar.org/iCalendar-RFC-5545/3-8-5-3-recurrence-rule.html) please be sure not to follow the broken format used by Recurme. I would recommend a full read of the recurme support thread as it raises lots of issues which should help you to avoid them in this module 🙂
  23. 6 points
    For 90% of these kinds of cases I do it like @Jens Martsch - dotnetic suggested, and in the template of the page (event, news item, etc) I have: // Throw 404 if item is future-dated if(!$user->isLoggedin() && $page->getUnformatted('date_1') > time()) throw new Wire404Exception(); But on a complex site where the pages might be queried from many selectors in many different places then unpublishing is the way to go.
  24. 6 points
    There might come many posts in the near future, sorry for that. I'll use this thread to let you follow and to have some kind of notes for writing docs when I release the module... It's also easier to quote and link to a specific post than to a section of one long post. The field now has 2 settings for hiding the checkboxes for toggline the fullday and has-end setting. This means you can use this field as a replacement for the datetime field and use the custom selector options shown above (range.onDay/inMonth/inYear).
  25. 6 points
    You go away for a minute and this is what happens...😀 TL;DR From Device-centric to App-centric development: ambient computing Dart and Flutter ranked #1 and #2 for fastest-growing language and open source project respectively over the last twelve months - GitHub’s 2019 State of the Octoverse report. Flutter is now one of the ten most starred software repos on GitHub. Flutter described as “the fastest-growing skill among software engineers”. LinkedIn, 2019. Flutter for web is in beta. Flutter for desktop is in alpha for mac-OS. You can edit Flutter code, run it and view the rendered UI online in DartPad. Adobe XD, Supernova, etc: flutter plugins. Full announcement here. Videos here (Flutter Interact 2019).
  26. 6 points
    I can't properly compare Svelte vs. Vue as I've zero experience from Svelte (and not a whole lot from Vue either), but regarding this question: it depends a lot on how complex stuff you're planning to build. I'm still using jQuery — or just vanilla JS, since native features have mostly caught up with jQuery by now — for stuff I can do almost completely with plain HTML and CSS (with a PHP backend), while for "complex" front-end stuff where a lot of data is processed, sorted, filtered, displayed (possibly in different ways), etc. I would definitely go with Vue. From what I have heard, the most common argument for Vue (vs. Svelte) seems to be that the Vue community is much more mature, and you'll find a lot more ready-made stuff for it. And, of course, more people with the same issues (which, as a relative newcomer to the JS scene myself, I've found really useful). This is all very opinionated, but the way I see it, jQuery is great if you just want to sprinkle HTML with some added-on behaviour, while for bigger stuff it actually tends to get more complex than if you'd chosen a full-blown front-end frameworks in the first place. So again, it depends on what you're actually building 🙂 If you do decide to go with Vue, for admin UI's in particular you might want to check out https://vuetifyjs.com. With Vuetify you'll have to sacrifice some freedom in terms of UI design, but once you get up to speed with it, it's pretty amazing — in many cases seemingly complex stuff gets done in a matter of minutes 😅👌
  27. 6 points
    Hi @adrian, I didn't know that module existed, it's not in the directory, is it? Because I looked if something like this already existed and didn't find anything. Might've saved me some trouble 😅 That said, I had a quick look, here's what I found in comparing both modules: ClearCacheAdmin exposes more options through the setup page, so there are available to everyone, whereas ProcessCacheControl has it's options in the module configuration, so they are only available to the developer. ClearCacheAdmin has multiple links (and multiple options) on the process page, giving the user more fine control, whereas ProcessCacheControl goes for a simpler interface and bundles all those actions into one (configurable) action with a single button. ProcessCacheControl can delete $cache entries without an expiry date, which ClearCacheAdmin doesn't as far as I can tell. ProcessCacheControl also lets you configure caches to be deleted by namespace, whereas ClearCacheAdmin offers each cache entry to be deleted individually (I think this has mostly to do with the module being a bit older, I believe $cache didn't have all those options back then). The largest difference is my concept of "cache actions", which ClearCacheAdmin doesn't have. I'm not sure how useful that will actually be yet. I think if I can expand on the actions available by default, it will be pretty handy. With ProcessCacheControl, you can add custom cache actions / profiles through the API, that may be useful depending on the use case. Adding to that, ProcessCacheControl has permission checks on a per-action basis. ProcessCacheControl can be modified and executed through the API. In particular, you can modify the default action and execute any action programmatically.
  28. 6 points
    I wanted to write a bit of an update since this project was so well received last year. The Architekturführer has now been online for about nine months, and we have been getting mostly positive feedback. Thankfully, I was able to resolve all issues with Google's indexing of the page. The site's SEO is actually pretty solid now, being one of the first results when searching for "Architekturführer" (at least from within Cologne). We have also added some new content and restructured some pages. The homepage, for example, now features only selected projects. An iconic new entry that everyone who's been to Cologne in recent years will recognize is the Rheinboulevard Deutz. There's also an entirely new section for architecture-themed walks (Spaziergänge) that you can take in different areas of the city. If you come to visit for a day, make sure to check those out 🙂 Finally, we got some traffic through word of mouth and a couple of architecture news sites, the visitor numbers are steadily rising each month. The only thing I find a bit lacking is that the number of PWA installations are very low. It seems the whole PWA concept has not really come through yet, or maybe it's just not that much of an added benefit compard to the normal site. I'm interested to see how PWAs will fare against native apps in the future, once they become more widely adopted.
  29. 6 points
    Heya! Just released Wireframe 0.9.0. Here's the changelog for this version: ### Added - New EventListenerTrait. Currently used by Components only. Adds support for listening to and emitting events. - Support for Renderer modules for adding templating engine support for view files, component view files, etc. - New Page methods Page::viewTemplate(), Page::getViewTemplate(), and Page::setViewTemplate(). - New method Component::getData() for manually defining the data passed to the component view. ### Changed - Controller::init() and Controller::ready() are now hookable methods. - Component::setView() and Component::getView() are now final methods, preventing accidental overrides. - Layout file is no longer necessary; if it's missing, the page can be rendered using just a view file. The component system is a bit more mature now, and there are a couple of new features: Component::on('event-name', callable $callback) can be used to listen to events emitted by a Component instance, and in a Component class events can be emitted with $this->emit('event-name', array $args). This is mostly just syntactic sugar on top of the hook system, but it seemed fun and potentially useful, so... 😅 The Component base class extends WireData, so by default what gets sent to the component view when a component is rendered is the internal $data array. Since 0.9.0 it's possible to alter this behaviour by implementing getData() method which returns the data that the component should expose to its view. Another "big" update is support for renderers. These are add-on modules that add support for different rendering / templating engines to Wireframe, and the first example is the Wireframe Renderer Twig module. I haven't really used a templating engine in a while so it's possible that I've missed something important, but in my limited tests the Twig engine seemed to work quite well right out of the box. I'll likely add a separate module for Latte at some point, just to make sure that the logic works for other engines as well 🙂 By the way, it looks like I forgot to post here about Wireframe 0.8.0. It was released last month, and here's the related changelog entry: ### Added - Support for Components, along with a new static factory method Wireframe::component($component_name, $args). - Support for rendering pages that have not been "routed" to Wireframe using the altFilename template setting. - New static getter/factory/utility method Wireframe::page($source, $args). - New static utility method Wireframe::isInitialized(). ### Changed - Wireframe::$initialized is now a static property. This was a necessary change so that Wireframe::isInitialized() could be implemented effectively. On a related note I'm considering tagging the next release as 1.0.0. We've been using Wireframe on production sites for a while now, and I can't recall any truly breaking changes so far, so I think it's already quite stable 🙂
  30. 6 points
    I'll join the "bliss train" have also updated sites running for years on old versions with no issues, I hope this thread gets mentioned in the ProcessWire weekly haha, people really need to know it's possible to live without waiting for your the site to break.
  31. 6 points
    Same here, i've been repeatedly graced with effortless and smooth upgrades countless times... such a godsend!
  32. 6 points
    Hi, With the complete deprecation of Instagram's API coming soon, I've been trying to get a replacement module developed to use the Instagram Basic Display API. I've got a proof-of-concept in place: https://github.com/chriswthomson/InstagramBasicDisplayApi At the moment, this module is very much alpha and shouldn't be used in production, but may assist you in getting your Facebook App tested if you are looking to use this API in future. Getting your Facebook App verified is another thing. I've not got to this stage yet, but having a verified Business Manager account attached should hopefully help once I do get to this stage. I hope to make this module a full implementation of this API, which also assists in leading the dev through the App setup process, however this is still a while off. We have used the soon to be deprecated InstagramFeed module on a number of large sites though, so we'll be hoping to get this up and running before March. Stay tuned, Chris
  33. 6 points
    "You can't fix 'stupid'" is an old saying. Sure PW is not for everyone and as the guy said, "Great for developers (I assume), pretty bad for everyone else". What got up my nose was he presents himself as a web developer/designer/guru and his own site is technically bad. Done well, PW is great for everyone. I suspect where he got lost was "assuming" that PW was a load the app, apply a FE theme, bung in a few plugins, squeeze your content to fit the theme and away you go. The thing I love most about PW is the exact opposite. I have complete freedom to build my sites, backend, frontend & user-friendliness
  34. 5 points
    Hi Bernhard, Being able to enter and display Events (or the like) is such a valuable tool for many websites. I am thrilled you have started this project. I cannot over emphasize @adrian's comment on all fronts. A few things that are very helpful in displaying recurring events is the ability to only display the event once. Ie. if you have a recurring event from March 10-15th. You may not want the event to display 6 times if you are viewing the Event list page on March 10th. The recurme module does do quite a few things right, unfortunately it wasn't quite there. Two features standout: 1. The user interface to create recurring dates which also has the ability to remove select dates. Ie. A range from March 10-15, but you can then exclude any date in the range. This avoids a second (essentially duplicate) event needing to be created. 2. Displaying recurring events can be quite a challenge, especially when there is a long list of dates. Recurme used a calendar display for this, which could really display a lot of recurring dates in a small space. Rather than displaying a long list dates in text format. I will send you a pm with some live examples we have built to date and how we display events. Perhaps this will help highlight some of the challenges you may be facing or how people may use your module. This will be such a great addition to the Processwire ecosystem!
  35. 5 points
    To be fair publishing (or un-publishing) pages at set time vs. just listing pages based on a datetime field are two different use cases. In some cases the distinction may not matter, but in others it will — i.e. when something really shouldn't be viewable before a predefined date/time 🙂
  36. 5 points
    @nabo What's your use-case? From a security point of view it's not a good idea to allow everything. Surely you have an idea what kind of file-types will be used? I found another forum thread where basically the same question was asked, and the gist of it was: No, you can't. Leaving the allowed extension config list empty makes it unusable, and just entering a wildcard * won't work either. @ryan takes security matters very seriously, and personally, I wouldn't want to have such a "everything goes" option built-in the core, too. If you have to, for some reason, import data from another system, and create / populate fields via API (batch actions), you can temporarily allow each file extension that comes your way, and then switch back to a "normal" default set after save. But I guess you were asking about using the GUI options.
  37. 5 points
    I think this already looks quite promising 🙂 $selectors = [ "template=event", "template=event, range.inRange=2020-01-01;2021-01-01", "template=event, range.inRange=2020-01-01;2020-02-01", "template=event, range.inRange=2020-02-01;2020-03-01", "template=event, range.inRange=2020-04-01;2020-05-01", ]; foreach($selectors as $selector) { $out = ''; $nl = ''; foreach($pages->find($selector) as $p) { $out .= $nl.$p->getFormatted('range'); $nl = "\n"; } d($out, $selector); } This now also works with backwards ranges (eg 19.3.2020 to 10.2.2020) because I store a separate START and END timestamp in the database: I've also implemented onDay, inMonth, inYear selectors: $selectors = [ "template=event", "template=event, range.onDay=2020-04-15", "template=event, range.inMonth=2020-03", "template=event, range.inYear=2021", ]; This also works using timestamps: $stamp = strtotime("2020-04-15"); $selectors = [ "template=event", "template=event, range.onDay=$stamp", "template=event, range.inMonth=$stamp", "template=event, range.inYear=$stamp", ]; Even sorting works out of the box - PW is once more impressive 🙂
  38. 5 points
    Opened an issue for this here: https://github.com/processwire/processwire-issues/issues/1083. It's great that http to https redirects are finally in place (assuming that this was intentional), but it appears that it's going to be an issue for the core.
  39. 5 points
    I believe the directory itself is the issue, it is "broken" at the moment. Broken because it forwards HTTP to HTTPS and this causes the check to fail, because the non-HTTPS url is hardcoded in the config file. Edit: So this is happening on all sites since yesterday. I tracked down the issue to the non-SSL service URL in the wire/config.php file. You can fix it by changing the $config->moduelServiceURL in your site/config.php like this: $config->moduleServiceURL = 'https://modules.processwire.com/export-json/';
  40. 5 points
    You want to write that line: $mobile_menu = $homepage->children; in one of a few different ways, e.g.: $mobile_menu->add($homepage->children); // or, though no need to create a new PageArray beforehand in this case: $mobile_menu = $homepage->children->makeCopy(); to avoid any caching issues and avoid changing "builtin" PageArrays. If you directly assign $homepage->children, $mobile_menu points to the already loaded instance of the children PageArray of $homepage and your new, empty PageArray gets discarded. Repeated calls to $pages->get(1) are cached and return the page object already in memory. I can only guess since you didn't post that part of the code, but it looks like you may have inadvertently manipulated $homepage->children when you built your main navigation. Make sure to use add() or makeCopy() in that part too.
  41. 5 points
    Here's a small new module that adds a "Manage tags" button to the template list, just like the field list already has. Easily add, remove and change tags for your templates. https://github.com/BitPoet/TemplateTagsEditList
  42. 5 points
    I just submitted my first module to the PW modules directory. The module is a full featured e-commerce module but I couldn't find a corresponding category there. May I suggest that a responsible person add a new category "e-commerce" (or something similar)?
  43. 5 points
    ...or you can use this small module that (with a lot of nicked code from ProcessField) adds the functionality to the Template list: https://github.com/BitPoet/TemplateTagsEditList Best try it out on a copy of the site though, I haven't tested it much yet. Anyway...have fun 😉 (I'm soon going to use this a lot myself to clean up a few really complex sites...)
  44. 5 points
    One thing to remember with Processwire is that while the default behaviour, and that of most built in fieldtypes is to use one table per field, like with most things, Processwire is incredibly flexible, so if you have a use case where a single table with multiple fields will be a more efficient way to store and access data, Processwire supports that too through custom field types, and indeed their are some built in fieldtypes that actually do work this way, such as map markers. Profields also includes a table fieldtype which as it sounds, is a database table with multiple fields. It takes a bit of work to write a module to provide a custom fieldtype but there are examples in the modules directory such as fieldtype Events which is specifically intended as an example of how to make a fieldtype that corresponds to multiple database fields. https://modules.processwire.com/modules/fieldtype-events/ In answer to the question, "Is the Processwire database structure scalable", I'd say that's entirely up to the developer, as you can really choose whatever database structure you like, just it takes a bit more work if you want to store multiple fields per table, and usually the built-in fieldtypes and default behaviour works fine. Where I have noticed there can be a little bit of a performance hit is doing a large import from CSV where each field from the CSV file results in a separate insert operation to a different table, whereas with a traditional database table with multiple fields would result in just a single insert operation per record, and potentially fewer indexes to update as well. If you're doing single page additions via the backend, via user interaction, Processwire is plenty fast enough, and there are performance gains to be had at the read level if you don't need to read every single field from a page every time it's accessed in front end templates, eg building a menu, you probably only want title and url, so reading the entire page content as well is unnecessary overhead, but if the content is in a separate table, and you don't access it, you don't have that overhead. There are always performance tradeoffs, but I think Processwire has struck a good balance. A default that works well for most people, but the means to do things differently if you really need to.
  45. 5 points
    During a recent maintenance routine we found that our website's database (1,700+ pages) had thousands of instances of unnecessary, garbage code that had come with copied text from Word. Passages with margins expressed in points, cms and inches, and some that were wrapped in upwards of 7 spans were among the most easily identified crimes. Purging all of this dropped our database size by over 4%. A few of the code examples above nuke all inline styles, which will impact some important out-of-the-box functionality for PW3 and CkEditor (depending on your use); specifically with many of the options with tables and lists, such as setting a column width or changing the bullet styles within a nested list. To work around that, I made some changes to Ryan's code to target specific tags and to eliminate spans (which you can only add via Source view without pasting them in). $wire->addHookAfter('InputfieldCKEditor::processInput', function($event) { $inputfield = $event->object; $value = $inputfield->attr('value'); if(strpos($value, 'style=') === false) return; $count = 0; $qty = 0; // Optional remove spans $value = preg_replace('/<span.*?>/i', '', $value, -1, $qty); $value = preg_replace('/<\/span.*?>/i', '', $value, -1); $count = $count + $qty; // Remove inline styles from specified tags $tags = array('p','h2','h3','h4','li'); foreach ($tags as $tag){ $value = preg_replace('/(<'.$tag.'[^>]*) style=("[^"]+"|\'[^\']+\')([^>]*>)/i', '$1$3', $value, -1, $qty); $count = $count + $qty; } if(!$count) return; $inputfield->attr('value', $value); $inputfield->trackChange('value'); $inputfield->warning("Stripped $count style attribute(s) from field $inputfield->name"); });
  46. 5 points
    I understand why you are asking for this feature. You're not the first one. But it's not as obvious as it seems. The 'title' field is not the same as all other built-in fields. You can't modify the behavior of the built-in fields per template basis. Which means they all behave the same no matter what template the page has. That's why we have a generic type 'Page' that has all the built-in fields. No matter what template the page we can confidently serve those fields for every page. The 'title' field's behavior could change depending on the template. I understand that it is almost never the case, but semantically it is. For example, you can set different access settings for 'title' field depending on the template. You make it that user can view the 'title' on one template and not on the other. You can change the description of the field for each template and it will appear in the GraphQL documentation. You can also make 'title' field 'not required' for one template and 'required' for others. So, including 'title' field into the Page type will break the semantics. I understand that 'title' field is almost always treated as a built-in field but I just can't overcome this feeling that it is the 'wrong' way to do it. I would like do it only the 'right' way. And the right way brings us to your second question. If we implement it properly and add the ability to get the values of the template fields for generic Page types, then 'title' field should also be solved. For this we will be adding interfaces. It will allow you to get template fields for Page types by providing a template. It will look something like this. { city{ list{ children{ # <== let's say children are the pages with template skyscraper and architect list{ id name ... on SkyscraperPage { # <== you basically say: "for skyscraper pages give me these fields" title images{ url width height } } ... on ArchitectPage { # <== "and for architect pages give me these fields" born email resume{ url filesize } } } } } } } this way you can fetch values for all template fields on Page types. This will work with everything that returns a Page type. Including 'child', 'children', 'parent', 'parents' and Page Reference fields too. And the best part is, it will be semantically correct! 😄
  47. 5 points
    Another thing I love about PW is the friendly, supportive forum. I certainly don't want to be accused of trolling the guy. He put his opinion out there based on his experiences, as is his right. Should he venture here though, I'd be more than happy to help him with his PW site
  48. 5 points
    I don't agree 🙂 If a reviewer has no useful knowledge of a system he is reviewing (he states: "I assume"), then he should not do the review in the first place, so "You can't fix 'stupid'" is a proper way to put it in a few words, even though it is a bit offensive, sure, but he deserves it in this case, and we are writing in the Pub section... I'd also like to point out that such a statement by the reviewer is dumb. He might also say that "Laravel is great for developers (I assume), pretty bad for everyone else.", for example. Reading his complete review, he clearly has no idea what he is talking about. PW's admin – by default – is for developers, so why comparing it to WP's and Squarespace's admin, which are for bloggers and such by default? Apples to oranges? I am also a person who did not want to spend the time on exploring ProcessWire for the first time I installed it. At that time I was jumping on the WP bandwagon and thought: so many options to explore, I have no time to explore a yet another system. Later on, I realized what a piece of you-know-what WP's internals are, so I gave ProcessWire another chance, never regretting it, of course🙂
  49. 5 points
    I don't think it's fair to blame him for his opinion. I think there are some valid points in it. He clearly has a non-tech marketing background and I can imagine that some kind of problems get a huge challenge with ProcessWire that are simply some clicks on other platforms. We know the pro's and con's, but if you don't have the technical background I can really understand that you get frustrated with ProcessWire. Not everybody has the time or will to learn things "from scratch". The headline states that he assumes PW is great for developers, pretty bad for everyone else. While I don't agree 100% on that, the point that PW aims on developers is true. I'd maybe add that it is also great for clients. But that's not always the case, to be honest: I think we all have had situations where we've stored data (settings, lists of countries and so on) somewhere in the page tree, because that's the way to do it in PW... But that's not the way someone coming from other platforms would assume it to be. I guess they'd be looking for it somewhere in the menu, in some listings or whatsoever... I've also needed @gebeer convincing me that it is a great platform. But I enjoy all the technical challenges, so that'll most likely be a totally different experience than someone who he calls "business users" might have 🙂
  50. 5 points
    UPDATE 2020-01-19 This is a follow-up to my last post! The question was asked when v3 of the cart system will be implemented in SnipWire. The following features are still missing in Snipcart v3: Digital goods Google Analytics integration Inventory management Deferred payments Multi-currency Recurring subscriptions with Stripe Authorize.net support Some of the listed features are required by SnipWire as they are essential and would require a lot of code rewrites to exclude them. So SnipWire will be changed to use v3 of the cart system when the following features are available in Snipcart: Inventory management Deferred payments Multi-currency
  • Create New...