Jump to content

Recently Updated Topics

Showing topics posted in for the last 7 days.

This stream auto-updates

  1. Past hour
  2. @Juergen No worries! I am looking forward to it and happy to test, when it's ready. 🙂
  3. Maybe I'm missing something but isn't your selector returning another page then? If you uncheck the checkbox then you have pj_kub_published='' for that page, but you are selecting =1, so your page does not match and it will find another page having =1 and that obviously has a modified date in the past?
  4. Today
  5. Hi webguy, Unless your client wants to be able to entre their Google Tag ID themselves, no need to create a field for that. As markus-th said, just hard-code it in a partial template that is included on every page (the one that contains the <head> part of your pages).
  6. Yesterday
  7. @netcarver: Thanks for your quick reply ! I use Firefox as well (and I've just tried from another computer with Firefox as well) : same troubles… The in-cache pages are ok, but if you go one the Newsboard and then click on a pupil's name (to go the his or her profile page), it loads for ever until the error occurs… And if I try to log in, the same error triggers again (I suspect because after logging in in the front end, I redirect to that Newsboard which has quite a lot of content). To log in to the backend, I type the /admin url and use PW login form. But then again, it happens that I have to wait for the eoor, then clean cache and cookie and/or come back by hard typing the backend url. Regarding the modules : Croppable Image 3, Leaflet Map Marker, Front End Edit Box, Limit Repeater, Login Notifier, Clean Empty Page File Dirs, Pages2Pdf, Changelog, Database Backups, Hanna Code, Login History. I had a problem with Hanna Code while migrating and the table is absent in PhpMyAdmin. I haven't managed to solve this issue yet. Could the Session DB handler (which I use as well) be a cuprit ? (But I think it breaks things a little if I turn it off). Another weird thing I had to face while migrating : file permissions error. Even though I set my config.php to 775 and 664, my FileZilla indicated 770 on assets/ directory and kept telling me 'permission denied' when I tried to change that. I had to rename the assets/files/ and put that directory back to load all my assets files. I can see though that my pages seem to be written in assets/cache/pages so I guess the problem is solved on that side (?). It is really a brain-teaser (and I guess that's an understatement 🙂) to me ! And I can't see any errors in the logs files (when I manage to get to it through the backend)… When the site starts looping, I can see a 'lock unabled' (can't remember the exact line) error.
  8. Hey @Andi thx for your open eyes! I've just pushed a "fix" for this on the dev branch. The thing is that this JS markup is needed sometimes and therefore will be rendered as soon as RockFrontend has some variables set. This was the case for isDDEV and therefore you saw the output. I don't see anything bad with having that markup on my sites. If anyone has good reasons to remove it let me know. The idea is to have a central place to send settings from the backend to the frontend. Some of them are only necessary when logged in, but there might also be situations where a module wants to set something that the frontend consumes. For example the root url of the site, that is unfortunately not always "/" but could also be a subfolder like "/myproject". On the backend that's easy via $config->urls->root, but on the frontend there is no standard and so I added this global RockFrontend variable/object that can hold these kind of things. The order in which you call ->styles() or ->scripts() does not define the order of the output. This method defines it: private function injectAssets(string &$html): void { $assets = ''; foreach ($this->autoloadScripts as $script) $assets .= $script->render(); foreach ($this->autoloadStyles as $style) $assets .= $style->render(); $html = str_replace("</head>", "$assets</head>", $html); } That means scripts will always be rendered first, then styles. I can change that if anyone has good reasons, though I think it does not make a difference. The more important thing is that you can or probably should add "defer" to your scripts, which makes the script load at a later point when the dom is ready. With UIkit this can lead to problems though as it might cause FOUC, because uikit adds custom classes like "uk-grid" when using <div uk-grid> for example. If you are not using defer, then it will work without issues. If using defer, you'd had to add the class manually: <div class="uk-grid" uk-grid> I'm simply loading these 47.8kB upfront to make my life easier.
  9. Hi @poljpocket, sort (-iname ... ) does not work, because iname_* contain different criteria to sort the images. To have an impression of the site, here's the link: (The new sorting function is not yet implemented completely) http://www.malabu.de But ->reverse(); was the right way, it works! Thanks to you all Günter
  10. OMG. So easy. Although not quite self-explanatory… Thank you! 🙂
  11. @Gadgetto I am struggling with webhooks :-) In the docs it says: * All hookable event handler methods will return an array containing payload Snipcart sent to your endpoint. * In addition, the following class properties will be set: * * $this->payload (The payload Snipcart sent to your endpoint) * $this->responseStatus (The response status your endpoint sent to Snipcart) * $this->responseBody (The response body your endpoint sent to Snipcart) * * (Use the appropriate getter methods to receive these values!) * * How to use the hookable event handler methods (sample): * ~~~~~ * $webhooks->addHookAfter('handleOrderCompleted', function($event) { * $payload = $event->return; * //... your code here ... * }); * ~~~~~ * * PLEASE NOTE: those hooks will currently only work when placed in init.php or init() or ready() module methods! * I have setup a hook for order.completed in the init method of a custom autoload module public function init() { ... // SnipWire Webhooks $this->wire->webhooks->addHookAfter('handleOrderCompleted', $this, 'handleOrderCompleted'); } Issueing post requests to the endpoint returns an empty response body While in the docs it says: when I var_dump($event->object->getResponseBody()) in my handler method, it gives an empty string which explains why the response body is empty. How can I set responseBody from within my hook handler method? There is no setter for that and Webhooks::responseBody is private, so I have no way to set it in my handler. To solve this, I introduced a setter method to the Webhooks class /** * Setter for responseBody. * * @param string $responseBody * @return void * */ public function setResponseBody(string $responseBody) { $this->responseBody = $responseBody; } Now in my handler method I can do $event->object->setResponseBody('{"test": "test"}'); Which results in While I was at it, I also added a setter for responseStatus. Not sure if you still maintain this module, so I will add this to my fork just in case anyone still needs it.
  12. Last week
  13. OK, here's my slightly revised `router.php` script: <?php if (PHP_SAPI !== 'cli-server') { die('Expected cli-server'); } if (file_exists($_SERVER['DOCUMENT_ROOT'] . $_SERVER['SCRIPT_NAME'])) { return false; } $_SERVER['SCRIPT_NAME'] = '/index.php'; $_SERVER['SCRIPT_FILENAME'] = $_SERVER['DOCUMENT_ROOT'] . $_SERVER['SCRIPT_NAME']; require $_SERVER['SCRIPT_FILENAME']; The main change is that `$_SERVER['SCRIPT_FILENAME']` is now an absolute path. Not critical, but more correct.
  14. Ryan has always done this (I really don't know why), but the tag on GH is added for the previous master version when the next master version is released and made available from the PW site's download page.
  15. Me too! This is now default in all my installations for all the reasons you mention. But I feel this sort of update would be a PW4 thing?
  16. Hi @Christophe Unfortunately we don't have Code Intellisense or autocomplete in latte files at the moment 😞 See https://github.com/smuuf/vscode-latte-lang/issues/5 You are adding the method "listchildren()" to your ParentPagePage, nowhere else. That means you can all this method only on pages that have the template "parent-page". Why should it do that? You are calling a method of an object. If that does not exist it is expected to throw an error. You CAN do what you describe though. Sometimes it is useful and I'm doing that as well. You could add that method to your DefaultPage.php and there return an empty sting. That would make $page->listchildren() return "" by default, which means it does not throw an error. For some page types you can then implement a different logic: DefaultPage.php --> listchildren() { return ""; } FooPage.php extends DefaultPage --> listchildren() { return "foo!"; } BarPage.php extends DefaultPage --> listchildren() { return "BAR"; } // in any template echo $page->listchildren(); That it totally up to you. Same with regular ProcessWire templates. It's up to us devs how we organise things and everybody does it differently. I can only say what I came up with and what works great for all kings of projects (from very simple to very complex ones): layout.latte for main markup /site/templates/sections/... for all sections /site/templates/partials/... for all partials Details: layout.latte --> holds the html markup skeleton of the page, eg: <html> <head>...</head> <body> <header>...</header> <main>...</main> <footer>...</footer> </body> </html> Then all my template files are usually empty (like home.php, basic-page.php, foo.php, bar.php). Next, I divide my design into sections. A section is a portion of the page that goes from the very left to the very right and has an undefined height/content. You can then add those sections to your main markup file like this: <html> <head>...</head> <body> <header> {include "sections/topbar.latte"} {include "sections/navbar.latte"} </header> <main> {include "sections/breadcrumbs.latte"} {include "sections/content.latte"} {include "sections/content-footer.latte"} </main> <footer> {include "sections/footer.latte"} </footer> </body> </html> This is often all I need, because I build all the available sections in RockPageBuilder and then I can simply add them to the pages as I need them. But it works without RockPageBuilder as well. You then just need to code all your page layouts depending on the page template. If all those pages share the same breadcrumbs and content-footer it could look like this: <html> <head>...</head> <body> <header> {include "sections/topbar.latte"} {include "sections/navbar.latte"} </header> <main> {include "sections/breadcrumbs.latte"} {if $page->template == 'foo'} {include "sections/content-foo.latte"} {elseif $page->template == 'bar'} {include "sections/content-bar.latte"} {else} {include "sections/content.latte"} {/if} {include "sections/content-footer.latte"} </main> <footer> {include "sections/footer.latte"} </footer> </body> </html> You could also use a dynamic approach: <html> <head>...</head> <body> <header> {include "sections/topbar.latte"} {include "sections/navbar.latte"} </header> <main> {include "sections/breadcrumbs.latte"} {include "content/" . $page->template . ".latte"} {include "sections/content-footer.latte"} </main> <footer> {include "sections/footer.latte"} </footer> </body> </html> It's just regular PHP inside the latte tags, so you could also do is_file() checks etc: <html> <head>...</head> <body> <header> {include "sections/topbar.latte"} {include "sections/navbar.latte"} </header> <main> {include "sections/breadcrumbs.latte"} {var $file = "content/" . $page->template . ".latte"} {if is_file($file)}{include $file}{/if} {include "sections/content-footer.latte"} </main> <footer> {include "sections/footer.latte"} </footer> </body> </html> Obviously you'd need to create those files. Here I'm placing them into a new folder called "content", which would be /site/templates/content/foo.latte for example. Next, partials: If you have repeating markup inside your sections you can outsource them into the partials folder. For example let's say you want to show a blog overview page that shows all single blog items as cards. You'd have a section like "blog-overview.latte" like this: // blog-overview.latte <div uk-grid> <div n:foreach="$page->children() as $item"> <div class="uk-card"> <h3>{$item->title}</h3> <p>{$item->teaser()}</p> </div> </div> </div> This example is very simple and if you only use your cards here, then it's easier to leave them here. If you are using the exact same cards on two or three places then you can create partials for them: // blog-overview.latte <div uk-grid> {foreach $page->children() as $item} {include "partials/card.latte", item: $item} {/foreach} </div> // /site/templates/partials/card.latte <div> <div class="uk-card"> <h3>{$item->title}</h3> <p>{$item->teaser()}</p> </div> </div>
  17. If you truly want to make an admin theme from scratch like I'm doing, it's best to just take AdminThemeUikit, since that is the "official" and most supported theme and rip out UIkit and start replacing it with your own approach and just hack away at it. Keep in mind that ProcessWire makes heavy use of jQuery UI and a few other libraries so you'll have to play nicely with them unless you want to replace them too, but that takes it to another level. With Bootstrap, it's straight-forward enough given the similarities with UIkit, although this is turning out to be more work than I anticipated. But that was the point since I want it to force me into looking at how everything is interconnected. One idea for an admin theme is to do it with pure, modern CSS and as little JS as possible and as accessible as possible (good reason why here).
  18. is there a way to make the options multilingual?
  19. I have managed to save the charge id to the order. For this to work I needed to make captureOrder hookable. This is probably not the right way tough.. $wire->addHookAfter('PadloperProcessOrder::captureOrder', function(HookEvent $event) { $paymentIntent = $event->return; $orderId = $paymentIntent->metadata->reference_id; if ($paymentIntent && $paymentIntent->status === 'succeeded') { $chargeId = $paymentIntent->latest_charge; // Load the order page using the order ID and save the charge ID $orderPage = wire()->pages->get("template=padloper-order, id={$orderId}"); if ($orderPage->id) { $orderPage->of(false); $orderPage->set('stripe_charge_id', $chargeId); $orderPage->save(); } } });
  20. Thought this might be interesting for the UIkit/Tailwind users, maybe best of both worlds?? https://www.franken-ui.dev/docs/introduction
  21. Also another possibility - are you running Debian? If so, I find I have the same issue unless I add this to config.php /** * Enable Session Garbage Collection * Garbage Collection is disabled in Debian as default (probability set to zero) * Enable session garbage collection with a 1% chance of running on each session_start(); * Chance calculated as gc_probability/gc_divisor * Session path is defined inside wire/core/Session.php and points to site/assets/sessions * Thanks to this modification session now takes into account gc_maxlifetime set in config */ ini_set('session.gc_probability', 1); ini_set('session.gc_divisor', 100);
  22. Dear all, thank you for all submissions. We will be contacting all of you whitin this week. Please do not send any further applications. All best, Dino
  23. I don't know anything about the history of `strtr` in PHP, but my guess would be that the reason it has the ability to replace strings in the first place is simply an extension of its original purpose from single-byte characters to multi-byte. It just so happens that in PHP multi-byte characters are represented as strings… I don't know if that's right, but I've seen it in other languages, so it certainly seems plausible. And when you have that in your head using it to just replace arbitrary strings feels, you know, funny. 🙂
  24. Hi @Chris-PW I removed the javascript block for meta-shift-s and ctrl-s. After that, pressing ctrl-s in TinyMCE worked perfectly. Tested in Chrome/Windows11 and Firefox/Windows11, and via BrowserStack, also in Safari 17.3/MacOS Sonoma. Additionally, I removed the timeout in UIkit.notification(...) in QuickSave.js, because my pages have so many fields and languages that saving the page takes several seconds. And because the page is reloaded anyway, in my case it was better to simply leave the notification until the page reloads.
  25. I haven't dug too deeply into this yet, but is I saw there is supported integration with TextformatterVideoEmbed - I'm wondering if this could apply to either TextformatterOembed / FieldtypeOembed postprocessing as well, or if that requires more fine tuning because of how different providers may offer different embedded content. Perhaps all of these fall under external-media?
  1. Load more activity
×
×
  • Create New...