Jump to content

bernhard

Members
  • Posts

    6,662
  • Joined

  • Last visited

  • Days Won

    366

Everything posted by bernhard

  1. Hey @zx80 great to have a new module author ? congrats! FYI: You can also just copy and paste the link to the ZIP file into the "install from url" field then you don't have to rename anything. I see that you inject both the JS and the CSS file in the site's head. I wonder what you or others think about that approach to inject such small files into the site. I think since HTTP2 it should not matter but tools like pingdom speedtest still show the "number of requests" as KPI. Personally I'd prefer splitting things into multiple files and then just including them over complicated build tools. And I'm already doing it similarly with RockFrontend. But I'd be interested what others think or if anybody has some good resources to read.
  2. Am I the only one thinking that the core way sucks?
  3. It sounds like you are looking for sharing code/functionality across multiple instances. That's what ProcessWire modules are for. ? You put the logic in one module and all instances can use it. It's really just a few lines of code. Much simpler than in many other frameworks: https://processwire.com/docs/modules/development/
  4. 2023 Update ? RockMigrations (must-have for all projects for automated deployments and because it installs several other modules for me with one click) TracyDebugger (for obvious reasons) RockFrontend (for zero-setup livereload, asset management and auto-minify, automatic less parsing and last but not least: LATTE ? ) RockShell (to grab data from staging or production via "php rockshell db-pull" which will then download user-uploaded files via RockMigrations filesOnDemand feature) ProCache ? Not a module, but also a must-have: Custom Page Classes
  5. @Cybermano It should be quite easy to ignore cloned pages in your hook: $wire->addHookAfter('Pages::saved', function ($event) { $page = $event->arguments(0); if ($page->_cloning) return; bd($page); }); Use tracy debugger to inspect the saved page objects and you can see if there are any helpful properties (like _added for example).
  6. +1 I've had the same discussion with a tailwind fan some time ago... IMHO he was reinventing the wheel over and over again. Every slider on every project was built differently (with AlpineJS which is one popular answer to your question). Every modal was built differently. Need tooltips? "npm install something" ? Or even worse built on his own again and not thinking about edge cases like tooltips moving to a different position when the hovered element is on the edge of the screen where there is not enough space for the tooltip ... Whenever I had to fix something on the frontend it was terrible. Just adding a class to an element? Nope... No luck without prior doing "npm run watch" and usually seeing many mysterious warnings in yellow and red... Fix some issue with a slider? Understand all the custom logic that was built with AlpineJS and directly written to the DOM. To be fair I'm not the best frontend dev on earth, so some problems might have been beginner things, but still these things are definitely drawbacks of that approach. One day he showed understanding and said, "Ok, you are right, let's build components that we can reuse. What components do we need?" I told him to have a look at the UIkit docs ? ? On the other hand a framework has some overhead of course. And like @teppo said the components can be hard to customise or maybe they even don't work in a way you want to. I guess it's about priorities and there is no right or wrong. Though the customisation part is 90% a bad argument imho because in UIkit you have plenty of options to customise every component but you have the benefit that you have proper docs, so every team member can quickly understand how everything works and you have a common ground to build on. Maybe UIkit is a little more like WordPress and Tailwind is a little more like ProcessWire. On the one side you take something that does a lot out of the box and then you adopt things (which is usually faster but less custom) and on the other side you start from scratch and build just what you need. And those mentioned frameworks try to find a spot in between I guess. Offer a quickstart but still being as flexible and efficient as Tailwind.
  7. Hey @Cybermano what exactly are you trying to do? If you only want to make the clone unpublished you can add this line before $copy->save(): $copy->addStatus(Page::statusUnpublished); I've some questions and suggestions for improvements on your code (assuming that the only difference to my old post is that the cloned page should be unpublished): Why do you set $page to unpublished during clone and then restore the previous state? That's 2x unnecessary page saves. You are using setAndSave for name + title, but you save() the $copy later anyhow. That means you produce 3 save operations instead of one. Just use $copy->set('name', ...) and same for title and changes will be stored on save() You are using setStatus(). It should be fine but I think it's better to use addStatus() in general unless you really want to force a single status. For example pages can have a "corrupted" status and that will be removed on setStatus() but will be kept when using addStatus() - please anybody correct me if I'm wrong ?
  8. Adding translations to modules sucks. That's why I built RockLanguage: https://processwire.com/talk/topic/27199-rocklanguage-a-new-way-to-ship-processwire-modules-with-translation-files-%3F/ The idea is that the module author is responsible for the translations and that it's as simple as possible to translate everything and keep everything up to date. I have not used it for a while though and it never got any traction in the community, but I still think it is the best way to do it. The official way is by far too tedious. There are so many necessary steps for just translating a single string. And if something changes you have to do everything over and over again. Terrible. RockLanguage automates all that for you. If you find that anything does not work any more let me know and I'll fix it timely. If you want to help on developing the concept further let me know!
  9. Maybe you need to set your field_pass table to ascii_general_ci ? At least this is what it shows for me. Maybe that's messing things up?
  10. You don't need composer for RockForms. But if you are building some intranet-like app as @dotnetic mentioned the most efficient way is to stay in the PW backend. To understand the backend better you can read my blog post here: https://processwire.com/talk/topic/17709-how-to-create-custom-admin-pages-aka-processmodules-yes-its-that-simple/ But creating a complex app with lots of calculations is not an easy task - so if composer is out of your league I'm not sure if it's a good idea to take over such a project. Maybe it's better to build on an existing solution as @Jim Bailie mentioned. But that's of course your decision ? Just wanted to mention that you can achieve anything you want with PW and with the PW backend, but it's definitely more complex than using composer. And your comment about PW needing a page title does not sound like you know a lot about hooks or the inner workings of PW. It's of course your decision, just be aware that if you price it with a flat rate then you might end up with a lot more work than you'd expect ?
  11. I've built a commercial module RockForms that can be of huge help here. It uses https://doc.nette.org/en/forms which is the only library on earth that I know where you define all rules from within PHP and get the same exact validation rules also on the client side for live validation. You have tons of options regarding validation and you can even create nested validation rules: https://doc.nette.org/en/forms/validation The drawback of using Nette Forms is that it makes it very hard to customise the created markup of your forms to your needs. That's where RockForms jumps in. Also it integrates everything very well with PW and creates pages from submitted forms, provides hookable methods to do custom stuff at custom events and handles redirects to prevent double form submissions etc.; Basically it handles all the tedious things for you that you'd have to think of upfront or that you have to fix later if you didn't think of them ? A simple form could look like this: // create form with a unique name $form = new RockForm("demo"); // field setup $form ->addText("forename", "Enter your first name") ->setRequired("We need your first name to show it!"); $form ->addText("surname", "Enter your given name"); $form ->addSubmit("submit", "Submit your name"); // render output if ($form->showSuccess($values)) { $name = $values->forename; if($values->surname) $name .= " " . $values->surname; echo "<strong>Thank you for submitting the form, $name!</strong>"; } else { echo $form->render(); } Or for more complex forms you can define everything in OOP style. Extensive docs are in the works and provide live examples that you can play around with: https://www.baumrock.com/modules/rockforms/docs/ Compared to FormBuilder the module does not (yet) have a UI to build forms. That's done in code, but it seems that this is what you want anyhow?! Single Site License will be 49€ - if you are interested write me a PM ?
  12. Hey! A client wanted me to update their website to make it show dates in the form "1. - 3. Jän. 2023" instead of "1. Jän. 2023 - 3. Jän. 2023" It's a small change but not so easy to solve, especially if you want to make it locale aware etc... So I've created "HumanDates" library which is not a PW module but a standalone PHP class so that everybody can easily use it even outside of the PW universe: https://github.com/baumrock/HumanDates Usage is simple and the library can be used as a strftime replacement: // manual download require_once "/path/to/HumanDates.php"; // using composer // composer require baumrock/humandates require_once "/path/to/composer/autoload.php"; // create HumanDates instance $dates = new HumanDates(); echo $dates->format("2023-01-01"); // 1. Jan 2023 echo $dates->range("2023-01-01", "2023-01-03"); // 1. - 3. Jan 2023 If it is useful to you please let me know by giving it a star on github ? https://github.com/baumrock/HumanDates/stargazers PS: It will be available in RockFrontend in the next release simply by calling $rockfrontend->humandates() ?
  13. This sounds weird. I don't know enough about character encoding of databases if that could also be the reason for such a behaviour though. What could result in something like this is if a hardcoded password is set somewhere before ready.php - This would explain why it works as long as the line is present in ready.php but as soon as you remove it it does not work any more. Can you log in as admin, then create a new superuser in the backend and then check if the login for that user works persistently?
  14. $users->get("name=admin")->setAndSave('pass', 'yoursupersecretpassword'); If you put that in ready.php and visit your site once (load any page), then you still can not login? Have you also tried logging in from an incognito window? Maybe some cookies are messing things up?
  15. Hey @AndZyk thx for the update! Have you seen https://github.com/TomS-/UIKit-TailwindCSS/blob/master/postcss.config.js ? I think you can use Toms regex. So the interesting part for me would be how we could add that to RockFrontend? I'd much more prefer a PHP way to do it similar to the LESS parser. But I did not find a solution on my research. Yeah that's why I did not add it to my workflow until now. But if it were really plug-and-play it would be nice, maybe..
  16. Well it should be possible, there is https://github.com/TomS-/UIKit-TailwindCSS/blob/master/postcss.config.js but I'm looking for an easy way ? Something that I could maybe plug into RockFrontend
  17. Please don't ? We have a new way of doing that, because ->getUnformatted() also gets temporary items, which is likely not what you want. This is how to do it in recent versions: $page->get("images.first") --> I've searched hard but did not find the blog post about it ? Anyone?
  18. This is something I'd wish to have for UIkit as well. How did you do that in bootstrap?
  19. Nice, thx! Never needed it indeed ? Added to my alias ?
  20. Another reason for using an alias to create your ddev projects: I just realised that the timezone in my project was not correct so $page->modified times where 2hours off. Simple to fix: ddev config --timezone=Europe/Vienna To not forget it for the next project here's my current alias: alias ddc='ddev config --php-version "8.1" --database "mariadb:10.6" --webserver-type "apache-fpm" --timezone=Europe/Vienna'
  21. Just hit the same issue and fixing it was very easy thx once more to DDEV: ddev config --timezone=Europe/Vienna ?
  22. It's already fixed on the dev branch, I asked for help in the nette forum, thx ?
  23. I've just pushed v 3.1.0 which fixes some issues with the new asset loading implementation. I've also renamed the default asset name to "main" from "head" as @snck pointed out that "head" could be misleading as someone could think autoload styles named "head" will end up in the html <head> and styles named "body" will end up in the <body> tag. This is not the case. Autoload assets always land in the <head> as you can easily add the defer attribute! If you don't want that, you can do this wherever you want in your markup: <p>some markup</p> <?php echo $rockfrontend->scripts('yourbodyscripts')->add(...)->render() ?> </body> </html>
  24. Ok a client wanted me to do some gdpr imrovements so I added this to my Site.module.php ? public function init() { ... $this->wire->addHookAfter('LazyCron::everyDay', $this, 'gdpr'); } public function gdpr() { // delete old rockforms logs $logs = $this->wire->pages->find([ 'template' => RockFormsLogPage::tpl, ['created', '<', time() - RockMigrations::oneMonth], 'include' => 'all', // also trashed pages! ]); foreach ($logs as $log) $log->delete(); // delete old processwire logs $this->wire->log->pruneAll(30); } So RockMigrations just got an update to support time constants: // time constants (seconds) // see https://i.imgur.com/vfTasHa.png const oneMinute = 60; const oneHour = self::oneMinute * 60; const oneDay = self::oneHour * 24; const oneWeek = self::oneDay * 7; const oneMonth = self::oneDay * 30; const oneYear = self::oneDay * 365; And I also found there is $wire->log->pruneAll($days) which is also handy ? Again PW has all the tools to make very custom needs possible with just a few simple lines of code!
  25. The PW backend is extremely customisable all over both from the design and from functionality. For the design you can simply modify /site/templates/admin.less (https://processwire.com/blog/posts/pw-3.0.179/) or use AdminStyleRock (https://processwire.com/talk/topic/25668-adminstylerock-easily-style-your-processwire-backend-with-two-simple-settings/). So you can very easily adopt spacings, fonts, font-sizes etc. For functionality you can use hooks or custom admin pages aka process modules (https://processwire.com/blog/posts/building-custom-admin-pages-with-process-modules/).
×
×
  • Create New...