Leaderboard
Popular Content
Showing content with the highest reputation on 08/05/2025 in Posts
-
RockGatekeeper A lightweight ProcessWire module that provides simple password protection for your website using a configurable gatekeeper password. Overview RockGatekeeper adds a basic authentication layer to your ProcessWire site. When enabled, it blocks access to all pages for guest users unless they provide the correct password via URL parameter. Features Minimal footprint: Only runs when gatekeeper is configured Session-based: Once authenticated, users stay logged in for the session IP tracking: Remembers the IP address of authenticated users Clean URLs: Automatically removes the password parameter from URLs after authentication CLI safe: Won't interfere with command-line operations Installation Copy the RockGatekeeper folder to your site/modules/ directory Install the module in ProcessWire admin Configure the gatekeeper password in your site config Configuration Add the gatekeeper password to your site configuration: // In site/config.php $config->gatekeeper = 'your-secret-password'; Usage Basic Authentication To access the protected site, users need to append the password as a URL parameter: https://yoursite.com/?gatekeeper=your-secret-password After successful authentication, users will be redirected to the same page without the password parameter, and they'll have access to the entire site for the duration of their session. Download & Docs: baumrock.com/RockGatekeeper1 point
-
Hi everyone, Trying to simply find pages where the modified date is greater than the created date. I would think this should work: $pages->find("modified>created"); but no luck. Thanks for any suggestions.1 point
-
Needed the exact same thing today and came up with this solution that allows using regular page selectors: public function getSheetToCreatePdf(): SheetPage|NullPage { // make sure to only find pages that have been modified since creation wire()->addHookAfter("PageFinder::getQuery", function (HookEvent $event) { $query = $event->return; $query->where("pages.modified > pages.created"); $event->removeHook(null); }); // find the oldest page that has no PDF and make sure to flush the cache return wire()->pages->getFresh([ 'template' => 'sheet', 'pdf.count' => 0, 'has_parent' => '/papers', 'sort' => 'id', ]); } This is called from an endless reactPHP loop that automatically creates PDFs when new pages are modified 🙂1 point
-
1 point
-
Hy @poljpocket thx for your questions I'm not using the functions API myself either. I never use pages() in my module, for example, I'm always using wire()->pages->... which will work with $config->useFunctionsAPI = false; Sure. For me this is not an issue and I thought it would not be an issue for anybody else, because I didn't consider a staging site being visible to others on the same network being critical in any way. But you are right, it might not be the most secure approach, so I have added a config setting for this which is disabled by default. So the default will be to only allow access for the session and allow the IP only when the checkbox is checked. I added this because when I tested my site on staging with my mobile phone and got a signup confirmation via mail and clicked the activation link my phone opened that link in some other browser and therefore I got "access denied". Sure it would be possible to copy the link and open it in the same browser that is already authenticated, but explain that to clients that you sent the staging link for testing... 😉1 point
-
A thought about the SVG: unless your client would like to change it every now and then, just include it directly in the php template...1 point
-
What I often do in such situations is to add this via hook: $wire->addHookMethod('Block::shouldRender', function($event) { $event->return = true; }); Then you have a shouldRender() method for all blocks that returns true by default and you can implement custom logic for each block that needs it. But I'm wondering... Maybe it would be a better idea to implement a DefaultBlock class that everybody can implement that RPB picks up and uses to extend every block on? You could then place your shouldRender() there and you could place anything else there as well. I'm a bit concerned about adding shouldRender() as it's really simple for your situation but if in the core I'm quite sure I'll get support requests why shouldRender() does not account for helper methods like getBlockNum() or isEvenType() etc... What do you think? I think having a DefaultBlock class would be nice and should help in your situation as well?1 point
-
Hi @Dillon if this is the kind of thing you're looking for https://www.waitandcie.com/ sorry everything is in french but it doesn't change the way it works... first i get the pages like this <?php namespace ProcessWire; $zipages = $pages->find('parent=1, sort=sort'); ?><!DOCTYPE html> and then <nav aria-expanded="false" inert> <a href="#" role="button" class="close_nav" id="close_nav" aria-controls="nav" aria-expanded="true" title="fermer le menu"><img src="/site/assets/img/couverts.svg" alt="fermer le menu" aria-labelledby="fermer le menu" style="width: 40px;" /></a> <ul id="navul"> <li><a href="/"><span data-content="Accueil"><img src="/site/assets/img/back.svg" alt="retour à l'accueil" aria-labelledby="retour à l'accueil" style="width: 50px; margin-inline: auto;" /></span></a></li> <?php foreach($zipages as $zp): ?> <li><a href="<?= $zp->url; ?>" class="navlink<?= $page->id == $zp->id ? ' selected': ''; ?>"><span data-content="<?= $zp->title; ?>"><?= $zp->title; ?></span></a></li> <?php endforeach; ?> </ul> </nav> and of course, alittle lower <a href="#" role="button" class="open_nav" id="open_nav" aria-controls="nav" aria-expanded="false" title="ouvrir le menu"><img src="/site/assets/img/hamburger_wh.svg" alt="ouvrir le menu" aria-labelledby="ouvrir à l'accueil" style="width: 50px;" /></a> done... everything elese is about css and js (toggle the inert and aria expanded attributes, my little fun with the menu items and so on but, as you can see, there are svg files here and there, when they are used all over the website UI i often create an img folder in the assets one to store svg icons (hamburger/map markers and so on) in case it helps a little have a nice day1 point
-
@ryan I know you asked in the blog post about whether this should be in the core or not and there have only been two replies on the post and not much discussion aside from that (unless I missed a thread somewhere), I think it should go in the core. Like you said you only realise you need it when something goes wrong and recently a staff member lost an hour's work to some scenario or other. I've also done it myself from time to time but keep forgetting this module is here. In my opinion, if it's low overhead it should be in the core and turned on by default. If we're uncomfortable with the idea of modules being installed by default, perhaps the installer should make suggestions after installation - like "suggested modules for different types of site". Anything article/blog related should then suggest this module. I do forget certain modules exist too, like this one has existed for 2 years and I forgot. It would be lovely if the Modules part of the PW admin could be overhauled to easier find things from the directory by category or some sort of search like WP/Craft etc does it. Not saying their implementation is perfect but feels like it would take a little hassle out of it by making things searchable and 1-click installable from the PW admin. I'm sure others have discussed that in the past so maybe also a way to suggest features and vote for things too? The forum software can handle polls easily but I'm getting off topic now.1 point
-
No, it does prevent a bunch of downstream hooks from firing, but specifically it doesn't include Pages::save and Pages::saveField (and I think it should include those methods). And to avoid confusion it would be good if the documentation explained exactly which hookable methods are affected by the noHooks option when it used in any of Page:save(), Pages::save() and Pages::saveField(). I've opened a GitHub issue so that Ryan is more likely to notice the problem and our discussion of it: https://github.com/processwire/processwire-issues/issues/14051 point
-
I also hate empty paragraphs so gave this a try. Works well for me. This is an interesting one. There is a setting, but it doesn't work as intended. With the help of Tracy Debugger I did a bit of investigating as to why but haven't got to the bottom of it yet. The line intended to replace empty paragraphs in InputfieldCKEditor is this: $value = str_replace(array('<p><br /></p>', '<p> </p>', '<p></p>', '<p> </p>'), '', $value); But it doesn't match the empty paragraphs because $value has already passed through HTML Purifier where gets replaced with some mystery space character. So neither 'nbsp;' nor ' ' match the space character between the paragraph tags. I haven't been able to work out what this space character is because it's rendered like a normal space in the variable dump. --- Update: the mystery character is a UTF-8 encoded non-breaking space character. So the code above should instead be: $value = str_replace(array('<p><br /></p>', '<p> </p>', "<p>\xc2\xa0</p>", '<p></p>', '<p> </p>'), '', $value); Double quotes are needed around the string with the UTF-8 non-breaking space. I'll submit a pull request for this fix.1 point