-
Posts
159 -
Joined
-
Last visited
-
Days Won
6
Everything posted by poljpocket
-
Hi all. Reading through the discussion about page classes, I have to add my two cents. I feel like we are mixing concepts here. We are talking about OOP concepts where the request arises to extend page classes' capabilities to better allow for separation of concerns. Many OOP concepts stem from or are just a fancy form of the MVC pattern. I strongly believe ProcessWire follows such a form too. Whereas the core handles MC and it's API provides endpoints for the V in Model-View-Controller and hooks for extending and altering the C part. So to really allow for separation of concerns, page classes aren't the right place to start off. A page is just the representation of an entity, a line in the database. Instances of said class that is. And thus Page and page classes belong to the Model part of ProcessWire. And this is exactly where my motivation to side with @ryan and his general scepticism of page class init and ready methods comes from. So it makes sense to add virtual properties or basic relationships to the page class. But the model should never contain business logic which acts outside of the lifecycle of the entity. Having made my point so far, I think Ryan's second to add a new class file to act as a controller (by using the ProcessWire's hooks) makes a lot of sense. And exactly that is why I believe, ProcessWire already offers a very good way to enforce MVC patterns and true separation of concerns. It offers a good API without forcing everyone to use the same architectural patterns so many other systems do.
- 127 replies
-
- 10
-
Hi everyone ? I have just updated and streamlined my own local development experience. Most importantly, I used to have a custom Dockerfile which resulted in a custom image for every project I ran locally. This has now changed! There is now a GitHub template repository tailored to local development: https://github.com/poljpocket/processwire-docker. This has everything you need to start developing locally on Docker. Some of the features: The composition is set up so that the site folder is fully accessible on the host. You can use any site profile upon first installation. The actual install of ProcessWire is still manual though. I found that there is little benefit in automating this. You can export the database to commit it into your repo and can also import it after pulling changes from upstream. The comp uses my new image for ProcessWire which I just published to Docker Hub: https://hub.docker.com/r/poljpocket/processwire. It uses PHP8.2 via Apache and includes all the PHP extensions needed for ProcessWire. You can find the GitHub repo for it here: https://github.com/poljpocket/processwire-docker-image. There are images for the three most recent stable versions of ProcessWire (210, 227 and 229). Important: I didn't care about security and hardening of the image. It is really only meant for local development. Have fun with it! Any requests and reports are welcome ?, thank you.
-
[SOLVED] $page->render can't render the current page twice
poljpocket replied to nurkka's topic in General Support
Another idea is to use ProcessWire's caching API and accomplish the JSON completely without the filesystem: use URL endpoints and cache the results until a page is saved. Ryan has used exactly your situation as an example of the (at the time) new feature "URL hooks". You can find that here: https://processwire.com/blog/posts/pw-3.0.173/#outputting-json-data-about-any-page-when-the-last-part-of-the-url-is-json. It is very easy to use a cached result in these hooks. You can find the API here: https://processwire.com/api/ref/wire-cache/. You can then use the Page::saved hook to clear the cache for a page's JSON. -
[SOLVED] LazyCron possible on every page load, or other technique?
poljpocket replied to nurkka's topic in General Support
Why unfortunately? You are not blocking any requests this way and so you can just let the task run for as long as it needs. If you have a task which should run every 10 seconds but takes more than 10 seconds, you have a completely different type of problem ? -
That is your "block editor"? Do you mean PageFrontEdit from the core?
-
[SOLVED] LazyCron possible on every page load, or other technique?
poljpocket replied to nurkka's topic in General Support
If you are in need of something which runs periodically and the 30s interval is too long, using LazyCron isn't the right way to go. That is not really what it's designed to do. Remember, 30s is the minimum time in between runs. If your website doesn't see traffic for minutes, the next call to LazyCron will also only be minutes later. This will possibly lengthen your task when you don't see regular traffic (meaning more than one request at least every 30s) and you are splitting it up into small chunks. For what you are trying to do, you should use the crontab of your server or use an external server which will trigger a Webhook also using it's crontab. But anyway: Is there any harm in just letting your "long task" do it's thing? Not with LazyCron obviously. I get that this would block one of your visitors every once in a while. -
[SOLVED] $page->render can't render the current page twice
poljpocket replied to nurkka's topic in General Support
For me this sounds like a recursion loop. Why would you need to recursively call the render method again in the hook for said exact method? You can solve this for example by using an "after hook": <?php namespace ProcessWire; /** @var ProcessWire $wire */ $wire->addHookAfter('Page::render', function(HookEvent $event) { /** @var Page $page the page in question */ $page = $event->object; /** @var string $renderedMarkup the "after hook"'s return will contain the rendered page */ $renderedMarkup = $event->return; // ... do your stuff and use $renderedMarkup instead of a second call to render() as this would end up in a loop }); You can see something very similar in the PageRender docs here. To be completely honest, you should actually use the hook for when pages get saved because this is actually where the contents change. Using render for this sort of thing you are only wasting resources and re-writing the same markup again and again. Also, remember you don't need to reinvent caching. ProcessWire already has a full API for that! -
Indeed there was no optimization yet. This is fixed! Thanks for the input!
-
Thanks for pointing that out. A lot of videos on that page which still need optimization. The staff images are actually also videos which should have poster images as placeholders. I just saw that my colleagues didn't put the poster images everywhere. We will have to improve that.
-
Thanks everyone for the feedback. You know how it is with your own websites... they get neglected in favor of everything that can make you money and thus, image optimization wasn't the most important thing to finish because we are only targeting the Swiss market anyway. In Switzerland, load times much better. Nevertheless, I did now finish the optimizations and enabled webp everywhere and so most images are <100k now. The videos remain untouched but will be done at some point.
-
Fruitcake has been using ProcessWire for a while now but I didn't get around to posting any of the around 30 sites we did so far. I will create sort of a megathread here adding any project we did (and want to talk about :D). But let me start off with our own new website which launched earlier this year. Our new brand website had the goal to be modern and simple and uses a minimalistic approach. The centerpiece of the page of course is our portfolio which most of the effort went into. It uses a playful and seemingly random (it's not!) layout. The portfolio detail page uses a vertical slider which from a technical point of view was the most challenging part. As for modules we are using, we like to do most of the stuff ourselves so it really only boils down to the Repeater Matrix Fieldtype from @ryan's ProFields package and SEO is done using SeoMaestro by @Wanze. Here you can have a look yourself: Die Kommunikationsagentur | fruitcake.ch Here is a preview of the masthead: Let me know what you think ?
- 8 replies
-
- 11
-
As you might expect for a paid module, your support has ended and so most likely, your old version doesn't fully support PHP 8.1. You will not get support for paid modules outside the respective support forum. The only solution will be to renew your license and get access to the newest version and the support forum.
-
For further reference, this is the hook to accomplish this with UTF8 mode for page names: <?php namespace ProcessWire; // we are in ready.php $wire->addHook('/post/{post_slug}/?', function(HookEvent $hookEvent) { // find post to use, fallback 404: $post = $hookEvent->arguments('post_slug'); $postTranslated = $hookEvent->sanitizer->pageNameTranslate($post); $requestedPage = $hookEvent->pages->get('name=' . $hookEvent->sanitizer->selectorValue([$postTranslated, $post])); if ($requestedPage->id) { $hookEvent->session->redirect($requestedPage->url); $hookEvent->return = true; } else { $hookEvent->return = false; } }); Changes to above hook: it is using a simple named path argument and accepts both the non-translated and the translated version of the post slug (e.g. when the UTF8 mode was enabled after a few pages have been created already and have translated names).
-
@netcarver wow, perfect! It is exactly that. I have switched to the UTF8 line and changed $config->pageNameCharset over to UTF8. Now it works perfectly. Even without any funky regex. So follow-up question: Now, for new pages, the translation rules in InputfieldPageName are disabled - makes sense because we get UTF8 pages names now. I guess we can have one of the two worlds, right? We absolutely don't want non-ascii page names on the new website. I guess I have to resort to some other form of redirecting outside of PW to accomplish both at once?
-
Dear community, I am having a strange problem for which I don't have the time to investigte in detail and I'm hoping someone might know why that is or if this is simply something PW cannot do at all. We have some redirect rules for a client's site which we have redone matching old URLs to new ones. In one of the rules - for blog posts, they are having German Umlauts (öäü) in their URLs (sometimes, but not always) which we need to redirect. There are a lot of posts and hard-coding every one of them is simply unfeasible. So I came up with this simple hook to solve all of the blog redirects at once. It works like a charm as long as there are no Umlauts in the URL. <?php namespace ProcessWire; /* this is in ready.php */ $wire->addHook('/post/(post_slug:[\wöäü]+)/?', function(HookEvent $hookEvent) { // find a matching to redirect to, or fall back with a 404 $post = $hookEvent->arguments('post_slug'); $postTranslated = $hookEvent->sanitizer->pageNameTranslate($post); $requestedPage = $hookEvent->pages->get('name=' . $hookEvent->sanitizer->selectorValue($postTranslated)); if ($requestedPage->id) { $hookEvent->session->redirect($requestedPage->url); $hookEvent->return = true; } else { $hookEvent->return = false; } }); The page name translation and funky regex are me trying to get the regex to match with Umlauts. But the problem is somewhere else because the hook doesn't get called at all if there are non-ascii characters in the URL. Does someone know more details about this? Thank you a lot!
-
Thanks for asking. I have to be honest, it wasn't clear why then and still isn't now. I have looked up the project in question and cannot replicate it anymore with the most recent code base. This project makes heavy use of vue.js for the frontend which lead to several problems with Tracy in the frontend. We ended up just disabling Tracy for the frontend and everything was fine and we stopped looking into it as it did no longer matter. If I'm enabling it now, everything is fine.
-
Page sure does have a changed() method. https://processwire.com/api/ref/wire/changed/
-
Still, this is what's happening on your live version, right? And it all works on your local environment? There must be a difference in the systems which leads to this difference in behavior. Let me also ask this. Is there a specific reason you don't use a simpler approach like this (careful - untested): <?php namespace ProcessWire /** * @var Wire $wire */ $wire->addHookBefore('Page(template=booking)::changed(tickets)', function($event) { $page = $event->object; $oldValue = $event->arguments(1); $newValue = $event->arguments(2); // [...] } Or like that (again careful - untested; if you don't care about the old value): <?php namespace ProcessWire /** * @var Wire $wire */ $wire->addHookBefore('Pages::saveReady(template=booking)', function($event) { $page = $event->arguments(0); if ($page->isChanged('tickets')) { $newValue = $page->tickets; // [...] } }
-
Bug when installing multilanguage modules
poljpocket replied to Leftfield's topic in General Support
Line 126 is the $languages API variable seemingly being empty. Line 340 is about the language translation files, but must be of the same origin. This is all I can read from your context. We need more to help.. did you follow the steps to install the modules in order? Does this also happen on a fresh install of PW? -
Ok, I tried to reproduce your situation locally on Docker. There are two languages "default" and "other". I have used site-blank as template and just added a TinyMCE ML field for body and added it to basic-page. Also, I changed the title field to be ML. PW version is 3.0.227 and PHP version is 8.2.18. Here's the result after I have changed nothing and just hit "Save" (same result when I change something): And here is the relevant code I used. I tried to stay as true to your code as possible. ready.php <?php namespace ProcessWire; if(!defined("PROCESSWIRE")) die(); /** @var ProcessWire $wire */ $wire->pages->addHookAfter('Pages::saved(template=basic-page)', 'hookPageSaved', ['priority' => 200]); function hookPageSaved(HookEvent $event) { $wire = $event->wire; $page = $event->arguments(0); // get the saved page // save current settings $saved_lang = $wire->user->language; $saved_user = $wire->user; $saved_output_formatting = $page->of(); // set current user to guest user $wire->users->setCurrentUser($wire->users->getGuestUser()); $page->of(true); $json_data = []; foreach ($wire->languages as $l) { $lang_name = $l->name; // set current language for rendering the page $wire->user->language = $l; // get rendered json data as string $markup = $page->render(); $json_data[$lang_name] = json_decode($markup); } // restore saved settings $page->of($saved_output_formatting); $wire->users->setCurrentUser($saved_user); $wire->user->language = $saved_lang; // write the JSON data to Tracy bd($json_data); } basic-page.php <?php namespace ProcessWire; /** @var Page $page */ $json_data = []; $json_data['headline'] = $page->title; $json_data['text'] = $page->body; header('Content-Type: application/json'); echo json_encode($json_data); Note two differences: I have restricted the hook to only fire for pages with template basic-page (as this would throw a bunch of errors in the Admin otherwise) I am not using a module to add the hook Maybe this sheds some light into the situation.
-
@flydev is implying that just a difference in $debug configuration or the module TracyDebugger being active or not can make some difference in how PW works in cases as peculiar as yours. That's why you need to make sure your environment is actually identical not just with PHP versions and database versions. We've experienced some problems/differences with Tracy messing up the frontend only when it's enabled (not even necessarily showing it's panels). Also that's why I suggested you make a carbon copy of your local install and try to run it somewhere else and look for anything that's changed to rule out it being your code or make sure it actually is your code and not something external and out of your control.
-
Looking through your other posts again, it seems like your hosting provider does have some problems and actually might be the culprit. We have had some peculiarities with some of them as well. I would suggest you try a completely different provider just to try out your install and make sure it's not the server it's on. So many differences in two systems is very unusual. You can use @flydev's Duplicator module to move it from local to this new environment. ? If you don't have access to something like that, pm me. I have a VPS with a known-good PW environment ?
-
Is your module configured as autoload? Also, as @flydev beat me to the punch, I assume this is some sort of an execution order problem you are having. My question is exactly about that... any non-autoload module actually gets loaded and initialized only on-demand, e.g. only at a certain point down the road when you are actually using it (in a hook for example) which might be after PW decides which PageClass to use. Also, gathering from your other posts, config.php might be too early in the OOE and ready.php might be too late. EDIT: I have had these problems in the past. I took on the whole PW core in an afternoon in order to understand how stuff works and especially, how PW works under the hood. This shed a ton of light into how to do things and where to hook into. Right now, if I am having a problem, I am just looking at the actual source code as my documentation.