Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 03/30/2024 in all areas

  1. Ok, sorry, clickbait πŸ˜„ Hooks are great! But sometimes, there are even better solutions: I'm cleaning up RockForms to finally release it πŸ™‚ I have some pages that are only for storing data (like form entries and such), so I don't want them to be editable, not even for superusers, as I control them solely via code in my module. -- Solution 1 -- With a regular hook that would look like this: <?php // site/ready.php $wire->addHookAfter("Page::editable", function($event) { $page = $event->object; if($page instanceof \RockForms\Root) $event->return = false; }); That's quite nice, but this approach has some drawbacks: First, sooner or later you might end up with hook-hell in ready.php; That's not ideal and really hard to debug on more complex projects. Second, as we are defining the hook with a callback in a non-OOP style these hooks get a LOT harder to debug! Have a look at tracy's debug panel: The second highlighted hook is the one coming from ready.php and it does not show any helpful information whereas the first one does show clearly that the hook is attached in RockForms\Root in the method "hookUneditEntries" (it should be hookUneditRoot, but I made a mistake when copy-pasting, sorry πŸ™‚ ). -- Solution 2 -- So the next best solution IMHO is using custom page classes! Then you get OOP style and a lot better structure for your project with really very little effort! Just create a file in /site/classes and that's it. Now to attach hooks directly in custom page classes you have to do one additional step. You can watch my video about this if you are interested. If not, head over to solution number 3 which is even simpler πŸ™‚ This solution might look something like this: <?php namespace RockForms; use ProcessWire\HookEvent; use ProcessWire\Page; use RockMigrations\MagicPage; use function ProcessWire\wire; class Root extends Page { use MagicPage; public function init() { wire()->addHookAfter("Page::editable", $this, "hookUneditRoot"); } protected function hookUneditRoot(HookEvent $event): void { $page = $event->object; if (!$page instanceof self) return; $event->return = false; } } This might look like a lot more code, but it's a lot better in the long run in my opinion as things that are related solely to the root page are inside the Root.php file of my module/project. -- Solution 3 -- But then I remembered: As our "Root"-page is a custom page class and PW checks if the page is editable or not by calling $page->editable() we can simply override this method like so: <?php namespace RockForms; use ProcessWire\Page; class Root extends Page { public function editable() { return false; } } You don't even need to make it a "MagicPage" because you don't need an init() method to attach any hooks. Now it's only very little additional code compared to a hook in ready.php but with a lot cleaner setup 😎 It's not a new invention, but I thought I'd share it nevertheless. Maybe it's helpful for some and maybe it's a good reminder for others, that even hooks are sometimes "overkill" πŸ˜„
    5 points
  2. This week we have a new core version on the dev branch. Relative to the previous dev branch version, the new 3.0.237 version has 33 commits containing 20 issue fixes, 6 feature requests, and more. See the core updates section of ProcessWire Weekly 511, 512, 514 and 515 for more details. It's been about a month and a half since 3.0.236, which is a little longer than usual between version numbers, but that's largely because if the new Invoices site profile (see blog post). I'm off work tomorrow (Friday), so writing the usual weekly post a day early. As always, thanks for reading and I hope you have a great weekend!
    2 points
  3. Have you ever had to revive an old project for whatever reason? Was it a pain to get it up and running, because you switched to a totally new laptop in the meantime? I had this situation today and it was no problem at all thx to DDEV 😎 --> got an error that DDEV can't boot up the project because the path changed from /my/old/laptop/projectX to /my/new/laptop/projectX But it also showed the solution: And then again: --> Browser popped up, table xy not found - well yes, obviously I don't have the database on my new laptop! Boom, everything works! With a quite old project with a quite outdated version of PHP πŸ˜ŽπŸš€
    1 point
  4. @protro I'm not familiar with rockfrontend. As you can see in a browser console your final code loads several files (uikit.min.js, uikit-icons.min.js, main.js, main.css) before loading your oswald.css file with the @font-face rules. The browser reads your oswald.css file and then sends a request to download webfonts. So two things delay the webfont download. The order of your js and css files and also the chaining via the font-face rule inside a css file. Most of the time it helps just to change the order and to set the css file at the first place. And as I said before the fastest way would be to inline those @font-face rules. If inlining does not help also, you could also give the browser a hint to preload webfonts like this: <link rel="preload" href="/site/templates/styles/whereever_your_fonts_are/webfont.woff2" as="font" type="font/woff2"> <!-- or for crossorigin <link rel="preload" href="https://www.domain.com/webfont.woff2" as="font" type="font/woff2" crossorigin> -->
    1 point
  5. The invoices application site profile that I uploaded last week now has a companion blog post: https://processwire.com/blog/posts/invoices-site-profile/ Thanks for reading and have a great weekend!
    1 point
  6. Thank you for the site profile and especially the blog post and extensive comments throughout the code. It's extremely helpful for overall architecture examples, which is something hard to find by just reading documentation or searching forum, because recommended practices have changed over the years. Especially love learning how you do things in the admin side for customizing the page edit screens, etc.
    1 point
Γ—
Γ—
  • Create New...