Jump to content

bernhard

Members
  • Posts

    6,676
  • Joined

  • Last visited

  • Days Won

    367

Everything posted by bernhard

  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" ?
      • 9
      • Like
  2. 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 ??
  3. Ahhh! Thx, now it makes sense: Unfortunately it's not possible to define the sort order 100% by adding styles in styles()->add(...); The reason is that if you mix file types (css + less) like you are doing that the sort order might get lost because .less-files need to be parsed before the final css can be injected into the final markup. RockFrontend injects the scripts via hook after the page has been rendered. It injects it right before the </head> tag. The reason for this is that when using reusable components that you want to move from one project to another then I want to have the ability to inject styles and scripts right from within my component. For example a "slider.latte" component would have the ability to add this at the top: {do $rockfrontend->scripts()->add('/foo/bar/slider.js')} That would tell RockFrontend to add the slider.js file on every page where the slider is rendered. If we didn't have that feature we'd always have to make sure that whenever we render the slider.latte we also add the slider.js in the main layout file (_main.php in older versions or layout.latte in newer ones). That's the background. Now the solution ? You don't have to use RockFrontend's asset tools. If they help, use them, if they don't, don't. Or mix them as you need! So just use them for parsing all less files and just add the oswald.css manually in your <head>. That will make sure it gets loaded before other styles injected by RockFrontend.
  4. Hey @protro congrats that's a great site!! Really beautiful design and absolutely awesome to also see the code and it looks great as well ? When I read the readme I was confused about how you structured the site (with sections folder inside the layouts folder), but that readme is not showing what you actually did ? --- In custom.less you have this Could you please elaborate on that? --- Also you are using css variables, which I'd also like to see in UIkit and I was thinking about creating a less file with hooks and overrides that provides that in a reusable way. What do you think? --- In ready.php you have this: // webp image support if($page->template != 'admin') { $wire->addHookAfter('Pageimage::url', function($event) { static $n = 0; if(++$n === 1) $event->return = $event->object->webp()->url(); $n--; }); } I'm not sure I understand what this is doing? First I thought it's a clever feature to always request webp on the frontend! But what is the $n for? Isn't it always resetting itself to 0 and on the next call it will again be incremented and if(1 === 1) will again return the webp? --- And I have a special request via PM ?
  5. Thank you guys ? Client feedback from yesterday: Thank you ProcessWire! ?
  6. Yeah that might be more elegant in some situations. Actually you don't even need to put it in a hidden div, you can put it in your markup in a latte comment for example. So those classes will not end up being rendered in your sites markup, but still tailwind will catch them for the final css. I prefer to place markup related things in markup files (*.latte) as for example when working on a "text" block for RockPageBuilder then I want it to contain all necessary markup for that block. So when moving that block into a new project it will still work and I will not have to mess with the tailwind config... But workflows and preferences are different ?
  7. RockForms is based on the great Nette Forms Component and adds a little ProcessWire magic here and there to make working with forms a breeze. It will render forms directly into the markup of your website (no iframes!), which makes it a perfect companion for tools like HTMX or Alpine.js ❤️ Download & Docs: baumrock.com/RockForms
  8. Tailwind only adds those classes to the final CSS that it finds in your content files. If you add classes in ckeditor tailwind doesn't know about them and likely will not add them to the final CSS. An easy fix is to add those classes somewhere in your markup (eg on a hidden div) so that tailwind adds it to the CSS and whenever an editor applies the class it will properly render
  9. same here ? True! I'm using that + RockPdf to generate monthly reports for my clients. The DB is something around 800MB and generating the reports is terribly inefficient, but it works and I think it looks nice and creates value ? Maybe it would have been better to create a simple API inside the container. But it was the simplest solution back then and I think they just want to monitor and don't need to create any reports anyhow ?
  10. New docs about the RockPageBuilder API that makes it easy to import content from old websites and convert it to RockPageBuilder blocks ? https://www.baumrock.com/en/processwire/modules/rockpagebuilder/docs/api/
  11. I'm using uptime kuma for monitoring my websites and it looks like it can do what you want: Oh, and I'm using https://www.statuscake.com/ to monitor my monitor ? So as uptime kuma is self hosted and needs some time to setup you'd maybe better of with statuscake which offers 10 monitors for free. I just checked and you can use GET and POST
  12. Hey @iank thx a lot for your message and sorry @Klenkes for the delay. I have been working on a solution for this but I totally misunderstood what you were saying ? I thought you are talking about temporary blocks, not orphaned blocks! But at least I've made progress with the other problem as well ? I'll look into that tomorrow, thx!
  13. @hellomoto you have to install ProcessWire and make sure it works before you can load it as a boostrapped app.
  14. It has been a great meeting yesterday ? We are working on something... ?
  15. No worries, giving feedback is already much appreciated and helps a lot ?
  16. @netcarver could you please mark the topic as [solved] ? Thx! ?
  17. Hi @Klenkes I've found the issue! Please download v5.3.1 ? FYI: The change event was triggered by the widgets field (or whenever more than one RPB field were present on one page in the backend). Could you please mark the topic as solved? ?
  18. HA! It's ProCache's markup minification! First test with ProCache on (html minification for guests): Second test with ProCache off: I'll post that into the ProCache forum! Thx for your help guys!
  19. Interesting, I think it might have also been the bold icon when I saw that behaviour, but I can't reproduce at the moment.
  20. What do you mean? Thx for the clarification. Well... I don't know how that should be possible then? It sounds like a very specific use case and you could always hook into Pages::saveReady and Pages::saved to achieve what you need. I don't think that I can come up with a common solution for that specific use case that would be helpful for many.
  21. Thx @Noboru your hint with the iphone is interesting. First I thought it might need some time to get the DNS records working properly, but still it's not working for me on my 2 android phones. @Stefanowitsch just sent me the link and it's working for him as well on his iphone. Can anybody check on android please? ? And does anybody have an idea what could be the issue? As mentioned other links do work on my phones...
  22. This is a really nice update for RockFrontend available on the DEV branch! You need a sitemap for your website? All you have to do is this in /site/ready.php: rockfrontend()->sitemap(); Really, that's all! Here are the docs with info about customisation and how it works: https://github.com/baumrock/RockFrontend/tree/dev/docs/seo#sitemapxml SEO is not my expertise, so I'd appreciate input from the community in how to make SEO tools in RockFrontend even better! Maybe I can even merge input until I push everything on the main branch in April ? There are also some quick-checks on the settings page to not forget the basics:
  23. Ok great, let's do 22.3. @ 11:00 GMT+1 (Vienna) @ meet.baumrock.com (also no download or registration) Yes, the meeting will be in German!
  24. I'll have to check out this weird change template issue! Thx.
×
×
  • Create New...