-
Posts
1,489 -
Joined
-
Last visited
-
Days Won
43
Everything posted by gebeer
-
[SOLVED] Trigger modules refresh in deployment hook
gebeer replied to gebeer's topic in RockMigrations
Good to know. Thanks for the heads up. -
Hi @bernhard we are experiencing a problem with the path to the icons folder in RockIcons. After running deployments the path changes and icons cannot be displayed anymore in the frontend because RockIcons is looking for them in a wrong path. I suspect that the full absolute path to the icons folder is stored and used in the RockIcons module. Now when we run a deployment, the actual folder where the icons lived before does not exist anymore because it is replaced by a new one for the new deployment. That new folder is symlinked to the "current" folder. But somehow the old folder path is still in the system. After a modules refresh, the path is updated and icons are displayed again. That is why I opened But I think it would be a cleaner solution to fix this in RockIcons.
-
Hi @bernhard can we trigger a modules refresh with https://www.baumrock.com/en/processwire/modules/rockmigrations/docs/deployments/#hooks ? How would I call wire()->modules->refresh correctly in a $deploy->after hook?
-
[SOLVED] API for get or find blocks by type or class
gebeer replied to gebeer's topic in RockPageBuilder
Done -
Correct way of handling favicon + fix for favicon detection
gebeer replied to gebeer's topic in RockFrontend
Thank you for clarifying :-) -
Hi @bernhard, The current Rockfrontend Docs talk about a favicon field that gets added if RockMigrations is installed (https://www.baumrock.com/en/processwire/modules/rockfrontend/docs/seo/#favicon-and-og-image) In the code, I do not find any migration that installs that field. In the module code at https://github.com/baumrock/RockFrontend/blob/2c1570656bd0152f9927f03144d334eff5c8d4de/RockFrontend.module.php#L3346 it says Use [realfavicongenerator](https://realfavicongenerator.net/) to add a favicon to your site. Are the current docs this still valid? Since I don't have the favicon field despite RockMigrations being installed when I installed RockFrontend, I assume that functionality does not exist anymore? Could you please clarify. Thank you. Also In module settings, I get But there currently is no favicon.ico file in the root. If I change the check in https://github.com/baumrock/RockFrontend/blob/2c1570656bd0152f9927f03144d334eff5c8d4de/RockFrontend.module.php#L3335 to $hasFavicon = $http->status( $this->wire->pages->get(1)->httpUrl() . "favicon.ico" ) === 200; the detection works.
-
Thank you for joining. I agree, RockCommerce looks promising and gives developers lots of freedom on how to implement things. Just the way PW devs love it :-)
-
Thank you for updating the actions in both scripts!
-
The one I had linked to which is the official github checkout action is not deprecated https://github.com/actions/checkout and in active development. Could you provide the link to the deprecated version? EDIT: Ah, I see https://github.com/baumrock/RockMigrations/blob/main/.github/workflows/auto-release.yml uses the actions/checkout@v4 :-) So in our local main.yaml we need to use jobs: deploy-to-production: uses: baumrock/RockMigrations/.github/workflows/auto-release.yaml@main // instead of deploy.yaml Could you please confirm?
-
I think you need to update to action/checkout@v4. Looking at their changelog https://github.com/actions/checkout/blob/main/CHANGELOG.md they updated to Node 20 in v.4.0.0. That should take care of the problem. Alternatively, if you, for some reason, must stay on v3, you can set an env var FORCE_JAVASCRIPT_ACTIONS_TO_NODE20=true But I would try to avoid that because of https://github.blog/changelog/2024-03-07-github-actions-all-actions-will-run-on-node20-instead-of-node16-by-default/#removal-of-operating-system-support-for-non-node20-os-versions Hope that helps :-)
-
Hi @bernhard we just ran into some error with the deployment script: The following actions use a deprecated Node.js version and will be forced to run on node20: actions/checkout@v3. For more info: https://github.blog/changelog/2024-03-07-github-actions-all-actions-will-run-on-node20-instead-of-node16-by-default/ Seems related to the action in use: uses: actions/checkout@v3
-
Hi @bernhard, I just installed RockSettings for the first time on PW 3.0.210. The project is still using CKEditor. So I got warnings for the TinyMCE fields that got installed through the RockSettings migration. So I need to override those. I'm doing this in site/migrate.php /** @var RockMigrations $rm */ $rm = $this->wire->modules->get('RockMigrations'); $rm->watch(__FILE__, 0); // note priority set to 0 to execute before /site/modules/RockSettings/pageClasses/SettingsPage.php which has priority 1 $rm->migrate([ 'fields' => [], 'templates' => [ 'rocksettings' => [ 'fields' => [ 'title' => [ 'collapsed' => 4, ], 'rocksettings_contact' => [ 'collapsed' => Inputfield::collapsedNo, 'inputfieldClass' => 'InputfieldCKEditor', ], ... The migration takes no effect, because /site/modules/RockSettings/pageClasses/SettingsPage.php has priority 1 and site/migrate always has 9999, no matter what I set in the watch call. So the RockSettings migration always overrides my mygration in site/migrate.php Here's the CLI output with $rm->watch(__FILE__, 0); ddev exec php site/modules/RockMigrations/migrate.php Refresh modules ##### SORTED WATCHLIST ##### Array ( [#9999] => Array ( [0] => /var/www/html/site/migrate.php ) [#1] => Array ( [0] => /var/www/html/site/modules/RockSettings/pageClasses/SettingsPage.php ) ) ### Migrate items with priority #9999 ### Watchfile: /site/migrate.php Load /var/www/html/site/migrate.php ### Migrate items with priority #1 ### Watchfile: /site/modules/RockSettings/pageClasses/SettingsPage.php => RockSettings\SettingsPage::migrate() --- Trigger RockMigrations::migrationsDone This specific to site/migrate.php After moving my migrations to site/modules/Site.module.php, the priority is recognized ddev exec php site/modules/RockMigrations/migrate.php Refresh modules ##### SORTED WATCHLIST ##### Array ( [#1] => Array ( [0] => /var/www/html/site/modules/RockSettings/pageClasses/SettingsPage.php [1] => /var/www/html/site/modules/Site/Site.module.php ) ) ### Migrate items with priority #1 ### Watchfile: /site/modules/RockSettings/pageClasses/SettingsPage.php => RockSettings\SettingsPage::migrate() Watchfile: /site/modules/Site/Site.module.php ----- Migrate Module Site ----- Migrate Site --- Trigger RockMigrations::migrationsDone Also after moving the migrations to Site::migrateSettingsPage like mentioned in the docs. BTW the docs are currently not linked on https://www.baumrock.com/en/processwire/modules/rocksettings But even if tmy migration is run after the RockSettingsPage one, the 'inputfieldClass' => 'InputfieldCKEditor', takes no effect. If I set it manually via GUI, it gets reset to InputfieldTinyMCE after next migration. This is because inputfieldClass can't be overriden in template context. Before installing the TinyMCE fields in your RockSettingsPage, you could check if the module is available. If not, use InputfieldCKEditor. That would be great. I have sent you the adjusted site/modules/RockSettings/pageClasses/SettingsPage.php
- 1 reply
-
- 1
-
[SOLVED] API for get or find blocks by type or class
gebeer replied to gebeer's topic in RockPageBuilder
Great hint, thank you. My logic for getting the block now looks like /** @var FieldData $blocks */ $blocks = $page->rockpagebuilder_blocks; /** @var Block $contactformBlock */ $contactformBlock = $blocks->get('type=ContactForm, _mxhidden=0'); This gets only non-hidden blocks which is perfect for my use case. -
Indeed, I do. And I'd be very interested to try your module
-
[SOLVED] API for get or find blocks by type or class
gebeer replied to gebeer's topic in RockPageBuilder
Yes, that is correct. I would like to handle this through the block's status, if possible. Since Block inherits from Page that should be possible? Something like $contactformBlock = $blocks->get('type=ContactForm, status!=unpublished'); But: When I hide the block, I get $contactForm->status = 1 When I unhide it, I get same status 1. Looking at the RockPageBuilderBlocks pages in the page tree, they don't seem to have a regular Page status So status in Blocks seems to be handled differently from Page status. Is there already a selector that we could use for finding only unhidden blocks? -
[SOLVED] API for get or find blocks by type or class
gebeer replied to gebeer's topic in RockPageBuilder
Great! Thank you for the quick addition. Very much appreciated. I have a SPA where I have URL hashes to jump to different section on the site like /#kontakt In the info() method for each block I added a property id. For the ContactForm block the id is "kontakt" Now I have link buttons in other blocks that should point to /#kontakt I could have hard coded that. But I wanted to get the block by class name to get the id, just in case it changes one day So in my template that holds the blocks I had this $blocks = $page->rockpagebuilder_blocks; $contactformBlock = $blocks->get('id=1195'); // add the hash to the page object to make it available further down the call stack in all block views $page->contactHash = $contactformBlock ? '#' . $contactformBlock->getInfo('id') : '#kontakt'; ?> <main id="content" sortable> <?= $rockpagebuilder->render(true) ?> </main> With your update I can do $blocks->get('type=ContactForm') which is much safer in my opinion. In case the block gets deleted and recreated, the id would change. -
Hi there, $page->rockpagebuilder_blocks is of type RockPageBuilder\FieldData which extends PageArray and and can be searched like PageArray by id, title etc. Is there a way to get/find blocks by there block type (class name)? Maybe I overlooked something, but couldn't find anything in the docs. I tried things like $page->rockpagebuilder_blocks->get('type|pageClass=Contact'); Would be a neat feature :-)
-
Thank you for this module. Love it. A few weeks ago I accidentally found this gem although it was not listed on your website. IMO this is the slickest color picker in the PW ecosystem, if you only need predefined colors (which is mostly the case in my projects). Very easy to setup and the editors love it, too. This will be new standard in my tool belt for new projects.
-
Nvidia GPU in particular often causes problems. But their drivers have become much better. @kongondo since you chose Ubuntu, you might want to consider giving https://pop.system76.com/ a try. Their releases are quite stable and GPU support is great. Some of the high profile coders on YT use it. I tried it years ago and even back then it was a pleasant experience.
-
Sad to hear about your bad experience with upgrading. Not that I don't want to help. But for these kinds of scenarios I found Claude or ChatGPT very helpful in many cases. Everyone's setup is different. You can go and debug with the help of AI, describing your specific scenario. Since you have a tty (Ctrl+Alt+F3) you can log on and use journalctl and dmesg to find the cause of the problem. The AI will tell you the right commands to find the errors (hopefully). I wish you success!
-
PDFs are created in multiple languages, so that is why :-) I looked at the implementation of the saveToField() method to figure out the exact behaviour.
-
Introduction Automated PDF production is a quite common task for ProcessWire developers. PW does not offer core tools for that. There are some external modules that we can utilize. In this showcase I would like to share my considerations for the tool of choice and my experiences working with it. The task at hand PDF production for product pages on an existing ProcessWire installation acniti.com is a Japan based company that specializes in nanotechnology solutions for gases in water. They have developed technologies to create nanobubbles in water, which can change the properties of water and improve dissolved gas levels through super saturation. Their founder and CEO has chosen ProcessWire for his website and has developed the site himself. He tasked me to add functionality for creation of downloadable PDFs from available product data. The client was forwarded to me from Bernhard because of time constraints on his side. I really appreciate that. The core requirements in detail: Produce separate PDF files for multiple languages, including LTR languages Design a template: cover page, images page, content pages, specs pages Cache PDFs Minimal impact on existing template code Tool choice: RockPdf module I had done some PDF generation before, using mPDF library directly. While there are other options available for ProcessWire (Pages2PDF, MakePDF) I decided to use Bernhard's RockPdf module since it seems the most feature rich and well maintained one. It is also based on the quite popular mPDF library. Reasons for choosing RockPdf Auto-reloading of PDFs in concert with RockFrontend This can save a lot of time (and strain on the F5 key), since the PDF is automatically reloaded every time a code change is made. All it requires to achieve that is one line of code: $pdf->save(__DIR__ . "/tmp/{$filename}.pdf", preview: true); Easy font loading I needed to load different fonts depending on the content language. Here is, how I did that RockPdf CSS utility classes They really came in handy, since they are specifically targeted at mPDF, using pt units. I could easily set some base colors with $pdf->setLessVars([ 'col-muted' => '#dddddd', 'col-primary' => '#0b54a2', ]); The utility classes that I mostly used are those for widths, margins and paddings. They are quite handy for setting up the layout of the PDF. Easy file saving to PW field For caching the created PDFs I utilized a RockPdf convenience method to save the files to a field on the product page $pagefile = $pdf->saveToField( page: $page, field: self::PDF_FIELD, filename: $filename, append: true, ); Implementation Modular approach for minimal impact on existing code I created two modules: Main module ProductPdf: non-autoload, holds all logic/templates for generating PDFs and required markup (download button) Module ProductPdfHooks: autoload, hooks: Page(template=product)::render displays PDF for download Pages::saved(template=product|product-type) creates PDFs in all languages and saves them to field for caching Re-usage of existing template logic There was quite a lot of logic (some of it rather complex) already available in the project that I wanted to utilize. Mainly for specs table creation. I had to do some minimal refactoring of original code. Then I was able to include that logic into my module without having to duplicate it. Benefits of this approach: Minimal impact on existing code Easier to maintain Challenges Limitations of mPDF library mPDF is not good at modern CSS features. It is quite limited in terms of CSS support. I had to do some workarounds to make it work with the layout I needed. Different approach to styling Although RockPdf's utility classes helped a lot, I still had to do some inline styling. Display of complex tables Display of tables in particular was a pain point since mPDF does a lot of automatic adjustments to column widths and distribution that I needed to disable in order to get the desired results: // Ensures that tables retain their original proportions $mpdf->keep_table_proportions = true; // And adding autosize="1" attribute to tables. Page headers, footers, margins and page breaks The RockPdf module docs have some great examples for setting up headers and footers, margins and page breaks. I used those to set up the layout of the PDF without having to read too much into the mPDF docs. Minimal impact on exisiting code base This was overcome by the modular approach I described earlier and it worked out really nice. The only addition to the original product template file for rendering the download button, was calling a static method from my module: <?= ProductPdf::renderDownloadbutton($page) ?> That button requests the page URL with a query parameter. The display of the PDF for download is handled through a Page::render hook PHP DOM manipulation of existing markup necessary Since I reused existing logic for constructing specs tables, I needed to add some inline styles and change some URLs on the fly. I used native PHP DOMDocument for that. There is a feature in the RockFrontend module that offers DOM manipulation tools with a nice API. I would have loved to use those but at the the time of working on this project, I just was not aware of their existence. The result Product pages on acniti.com now have a download button that allows the user to download the PDF of the product page in their language. See it live here The PDF is loaded from the cache field on the page, which is updated every time a product is edited and saved. If no cache file exists, the PDF is created on-the-fly and cached for future use. It is presented to the user in a new browser tab for viewing and downloading. The PDFs feature a clean layout / design which corresponds to the acniti branding. Cover page: Content pages: Specs table: Feedback from the client The client has a lot of experience with ProcessWire which one can see from looking at their website at acniti.com. He gave me great feedback on the project: Erik van Berkum, acniti LLC Lessons Learned and conclusion PDF creation in PHP is still not an easy task. The most popular library, mPDF, has some restrictions related to CSS that can make it tedious to work with. Especially when it comes to more complex layouts and tables. Using the RockPdf module for the task was a great choice. Its API is very well designed, offers a lot of conveniences and is well documented. Bernhard responded quickly to my questions and provided great support. In conclusion, the ProcessWire ecosystem offers great tooling for PDF creation that makes life for developers more enjoyable :-) Future considerations Would I use this approach again? Well, that depends mainly on the requirements. For this task the chosen tooling worked very well and I am happy with my choice. But for more complex layouts/designs that require modern CSS features, I would prefer rendering PDFs through Chromium browser using puppeteer or a self-hosted gotenberg service.
- 5 replies
-
- 12
-
Not so sure about that. But the GH repo on the extension page links to tailwndlabs. EDIT: Actually I would not trust that extension since they are clearly not linking to their own GH repo and therefore pretending to come from tailwindlabs.
- 242 replies
-
- 1
-
- visual studio code
- vsc
-
(and 2 more)
Tagged with: