-
Posts
6,670 -
Joined
-
Last visited
-
Days Won
366
Everything posted by bernhard
-
Hey @LMD I can not reproduce the issue. This is what I did: created a new ddev project installed RockShell (to quickly install pw via commandline) installed pw (current dev, blank profile) clicked "install" for all modules (bottom - up) Enabled product variations and it correctly showed the warning: But I have improved that so that it shows the checkbox only if RockGrid is installed: Once RockGrid was installed i checked the box and got this (success, no errors): This is what I get when I view Setup > RockGrid: To add the Variations GUI to your products do this (I'll add this to the docs later): Add fields "rockcommerce_net" and "rockcommerce_variations" to your product template Then edit one of your products and you should see something like this: Then click on "+ new variation" at the top left corner of your variations repeater item: Save that and maybe reload the page to see the variations in the grid. Then you can select variations as mentioned above: Each variation has a price. You can either use "0" as base price and enter the variation price for each variation (eg, 10€ / 20€ / 30€) or sometimes you might want to set a total price. To save you or your clients from the hassle of calculating all price differences there is the "total" column that you can use and RockCommerce will calculate the difference for you: I can't recommend DDEV enough. I've been using Laragon for several years, but trust me, DDEV is so much better so it's really worth trying it out. Installation might be a little harder than with Laragon, but once installed DDEV just runs and runs and it has so many great features that Laragon does not have. And last but not least it makes it easier for me to help you with any issues because we have the same environment. Let me know how it goes.
-
Oh and if you need a quote for the website, this might be a starting point:
-
this was my prompt for the AI (source = me) This is the output of the AI that I got from my prompt. 🙂 I think I used claude 3.5 sonnet but I'm not 100% sure.
-
Hey @LMD thx for your question and of course thx for your purchase 🙂 Great! 🙂 Yeah sorry for that! But I'm always around to help as good as I can 🙂 If prices only change based on shoe size it does not sound complex 🙂 If prices change depending on colour and shoe size than it's a different story 🙈 Adding variations from the backend should be straightforward! You click on "new variation" in the shop tab of your product and get something like this: Then you hit save and you get back to the shop tab. There you can filter all existing variations, so you can type "size" and get this: Then you enter the prices for each size and - important - select all variations that should be displayed on the frontend: To select/deselect variations you have two options: Select all or select a single item. When clicking on the "variation" column you select all, when clicking on the "option" column you can select individual rows: The selected variations should then show up on your frontend: Does that help? Not sure where exactly you are struggling 😉
-
No, spot on! Thx that was very helpful 🙂
-
Hey @teppo and @psy thx for your answers! Looks like I was not precise enough with my question. The import part is not the question - I've imported 1000+ pages for this project already from the old website using RockShell and a custom script. With RockShell it's super easy to create reusable scripts (as you have correctly mentioned as important need @teppo) and it's super easy to watch what's happening and to abort in case anything unwanted happens (just hit CTRL+C). The question is more related to e-commerce and different vendors providing different data. What we got was a total mess. From CSV with thousands of entries in one huge table to excel files with related keys like an excel copy of a relational database. Think of it as a mysql dump of a ProcessWire installation... but without ProcessWire transforming it into something useful and understandable 😅 My guess is that the only way is to understand the data we get from the vendors and then try to transform it into the data format that RockCommerce needs. Sounds like a pain. But manually adding 15k products does not sound better either 😄 So I also thought about scraping the data from their websites... but I'm not sure if that was any easier than reading their messy CSVs... Anybody has some experience with that? Also happy with "no idea/not easy/not possible" answers to help me back what I told my client ^^ PS: A RockShell command to import from CSV is as simple as that if anybody has a similar need: <?php namespace Site; use ProcessWire\Page; use RockShell\Command; use function ProcessWire\wire; class ImportProducts extends Command { public function handle() { while ($row = wire()->files->getCSV('/path/to/data.csv')) { // create page and save it $p = new Page(); // ... echo "Saved page {$p->path}"; } return self::SUCCESS; } } You can then run that command via "rockshell import:products" and watch it do its work 🙂 So the ProcessWire part is easy.......
-
Want to share the name of the extension? 🙂
-
For me ProcessWire combines the best of two worlds: The world of CMS/Blogging Platforms like WordPress and the world of Frameworks like Laravel or Symfony. I think edit: I had to let AI write my brain-dump in a more professional way and I could not have said it better: My quick and dirty prompt (don't blame me for grammar etc 😉 ) I know we can debate about AI in general but I think it is very interesting to get this "birds eye view" of aggregated data as it somewhat shows the current information that lies around the web at the moment: I also think that ProcessWire is a perfect alternative for systems like Typo3 and I bet that there are many many developers out there that would be super happy if they knew that ProcessWire existed! See this showcase for example. I think this says a lot! More people need to know about ProcessWire, especially the folks that are not using (or do not want to use) WordPress. All the people that expect building a website to be a "click-click install this plugin that plugin" experience are not our target audience. But all the people looking for alternatives and being unhappy with typo3/drupal/etc. are! ProcessWire lacks a good page building concept. Don't want to say more about that as it would fill a whole other topic 🙂 Many need a second look. Me 10 years ago included! At first sight I totally underestimated the power and beauty of this system. I hope the new website can help to change that 🙂 https://w3techs.com/technologies/details/cm-typo3 High traffic site? Loads of content? Why is nobody thinking of ProcessWire in that case? And here is what AI thinks about Typo3 vs. PW: Really excited to see the new design and website 🤩 Good luck and all the best 🚀 Thx for building and sharing such a great masterpiece with us!
- 18 replies
-
- 12
-
-
Hey @FireWire great thank you! My project is taking shape and we will start adding content soon, so it's a bit annoying if the translation service breaks our site snippets 🙂 Great to know that you can reproduce and a fix is coming 🙂 All the best for your event!
- 315 replies
-
- 1
-
-
- translation
- language
-
(and 1 more)
Tagged with:
-
This might be helpful:
-
Hey @FireWire thx again for sharing your block thumbnails! I have just made it a lot easier to explore/find/use them and added this field to the module config screen where you can just click on the icon and it will copy the name to the clipboard that you can then just paste into your "thumb" property of the block's info method 😎
-
Today a client asked if they can have a page where they can upload internal documents that are only visible to logged in users... I thought the easiest solution is to make the page unpublished and make sure nobody can publish it. This is done with a checkbox that is only visible to superusers and when checked, the page always adds the unpublished state on saveready: <?php // in init() of the Site.module.php wire()->addHookAfter('Pages::saveReady', $this, 'lockPage'); // the hook protected function lockPage(HookEvent $event): void { $p = $event->arguments(0); $locked = $p->getFormatted(RockMigrationsConstants::field_lock); if (!$locked) return; $p->addStatus(Page::statusUnpublished); } And another hook to remove the publish button (which is why I found this thread and thought it might make sense to share this solution): <?php // init() of Site.module.php wire()->addHookAfter('ProcessPageEdit::buildForm', $this, 'hidePublishButton'); // the hook protected function hidePublishButton(HookEvent $event): void { $p = $event->process->getPage(); $locked = $p->getFormatted(RockMigrationsConstants::field_lock); if (!$locked) return; $form = $event->return; $button = $form->getChildByName('submit_publish'); $form->remove($button); } This will also remove the copy of the publish button 🙂
-
Move fields from "Settings" tab to "Content" tab in the Page Editor?
bernhard replied to JMartin's topic in General Support
Needed this today. This is what I used: <?php // on init of a module wire()->addHookAfter('ProcessPageEdit::buildForm', $this, 'moveStatusFieldAndHideSettings'); // the hook method protected function moveStatusFieldAndHideSettings(HookEvent $event): void { // do not change the UI for superusers if (wire()->user->isSuperuser()) return; /** @var ProcessPageEdit $process */ $process = $event->process; $p = $process->getPage(); // check for page template if (!$p->matches('template=basic-page')) return; // get status field /** @var InputfieldWrapper $form */ $form = $event->return; $statusField = $form->get('status'); // add field to content tab $tab = $form ->find("id=ProcessPageEditContent") ->first(); if (!$tab) return; $tab->add($statusField); // remove settings tab both from form and from UI $tab = $form ->find("id=ProcessPageEditSettings") ->first(); if (!$tab) return; $form->remove($tab); $process->removeTab('ProcessPageEditSettings'); } -
Hey @FireWire any news on this? Can you reproduce the bug? Let me know if I can help with anything!
- 315 replies
-
- translation
- language
-
(and 1 more)
Tagged with:
-
A very quick and easy solution would be to add css like this to your admin.less file: li.Inputfield_tmp2 input { margin-top: 30px; } Before: After: You need to adjust the field names in your css though.
- 2 replies
-
- 2
-
-
- multilanguage tabs
- multilanguage
-
(and 1 more)
Tagged with:
-
Thx for sharing! In case you don't know or anybody is interested in alternatives: RockDevTools is free and provides asset merge/minify plus live reload:
-
There we are: https://ddev.readthedocs.io/en/latest/users/quickstart/#processwire-zip-file 💖
-
I'm not sure, but I don't think it supports redirects for subtrees. But you could easily solve that by adding an url hook to /{year}/{page} That hook will not fire for /2025/... as this page exists, and for all other years you can make it look for the page at /oldyears/$year/$page and redirect to that page if it exists.
-
Ah, thx! That's what I was missing 🙂 It returns only view links which I don't want either. Thx for the clarification 🙂
-
Thx @adrian that already helps! I missed that comment! This one is interesting. This is not the case for me! I'm also hooking Page::editable and Page::addable and the live search returns non-editable pages as well...
-
Hey @adrian I had a look into your modules code to see how you restrict search results in the PW backend. I need this for a multisite module I'm building. I took your hook: wire()->addHookAfter('ProcessPageSearch::executeFor', $this, 'hookSearchResults'); ...but wondered why it did not trigger my callback. First I thought the bd() call in the callback might not be working, but turned out the callback was never triggered. So I added a hook recorder and got a log like this: ProcessWire\FieldtypeModule::formatValue ProcessWire\FieldtypeModule::formatValue ProcessWire\ProcessController::execute ProcessWire\FieldsArray::changed ProcessWire\FieldsArray::changed ProcessWire\FieldsArray::changed --- ProcessWire\ProcessPageSearchLive::execute ProcessWire\ProcessPageSearchLive::getDefaultPageSearchFields --- ProcessWire\FieldtypeModule::formatValue ProcessWire\Pages::find ProcessWire\PageFinder::find ProcessWire\PageFinder::getQuery Which made me aware of "ProcessPageSearchLive". I then changed my hook to hook into ProcessPageSearchLive and boom, everything worked as expected. Now I'm wondering why your module only hooks into ProcessPageSearch. Does that even work? Or am I missing something? Thx!
-
Oh, I was always using + instead of = and it worked as well. Not sure where I picked that up. Yes, manually entering it saves it. But the issue is that when you translate a string and the returned translation is the same (eg Telefon (DE) --> Telefon (CZ)) then fluency will fill the input with "Telefon" which will then be lost on save and the field will be marked as "blank". I think it would be good if it turned "Telefon" into "=" on save. But I think that the core should take care of this! What do you think? PS: No hurry.
- 315 replies
-
- 1
-
-
- translation
- language
-
(and 1 more)
Tagged with:
-
Ever felt like your ProcessWire emails look like they're stuck in 1999? You know the drill - sending emails is super easy with WireMail: $m = new WireMail(); $m->from('foo@bar.com'); $m->to('xxx@yyy.com'); $m->subject('Hello there!'); $m->bodyHTML('<h1>This is great!</h1><p>I am an ugly mail...</p>'); $m->send(); But let's be honest - they look about as pretty as a website built with Microsoft FrontPage! 😅 🪄 Enter the Mail Pimp Hook! Drop this magical hook into your /site/ready.php (or even better Site.module.php), and watch your emails transform from ugly ducklings into beautiful swans: <?php $wire->addHookBefore('WireMail::send', function(HookEvent $event) { // double check that we got a wiremail instance // this also tells the IDE what $mail is (to get IntelliSense) $mail = $event->object; if (!$mail instanceof WireMail) return; // get current mail body $html = $mail->get('bodyHTML'); if (!$html) return; // get email layout markup $layoutFile = wire()->config->paths->templates . 'mails/default.html'; if (!is_file($layoutFile)) return; // replace ##content## with actual mail content $html = str_replace( '##content##', $html, wire()->files->render($layoutFile) ); // write new body to mail $mail->bodyHTML($html); }); The HTML Just create a beautiful MJML template at /site/templates/mails/default.mjml, put ##content## where your email content should go, convert it to HTML and BOOM! 💥 Every email gets automatically wrapped in your gorgeous template. No more CSS wrestling matches, no more "Why does this look different in Outlook?" headaches. Just pure email beauty, automagically! ✨ Now your clients will think you spent days crafting those emails, when in reality, you're sipping coffee while your hook does all the heavy lifting. Work smarter, not harder! 🚀 #ProcessWire #EmailMagic #NoMoreUglyEmails PS: This is the MJML template that I used: <mjml> <mj-head> <mj-attributes> <mj-all font-family="Tahoma" /> <mj-text line-height="140%" /> </mj-attributes> </mj-head> <mj-body background-color="#efefef"> <mj-section background-color="#ffffff" background-repeat="repeat" padding-bottom="30px" padding-top="30px" text-align="center" > <mj-column> <mj-image align="center" padding="25px" src="xxx" target="_blank" width="200px" alt="Logo" ></mj-image> <mj-text>##content##</mj-text> </mj-column> </mj-section> <mj-section> <mj-column> <mj-text font-size="10px" color="#a0a0a0" align="center" > powered by <a href="https://www.baumrock.com/" style="color: #158f66" >baumrock.com</a > </mj-text> </mj-column> </mj-section> </mj-body> </mjml> VSCode has an extension to get a live preview and export MJML to HTML: And here are some other free templates: https://mjml.io/templates I use https://www.base64-image.de/ to add the logo to my mail template as src="data:image/jpeg;base64,/9j/4QAWRXhpZgAATU0AKgAAAA..." to avoid headaches with image paths, remote assets blocking etc.
- 14 replies
-
- 21
-
-