-
Posts
535 -
Joined
-
Last visited
-
Days Won
11
Posts posted by Sergio
-
-
On 11/21/2025 at 11:09 PM, olafgleba said:
I mostly work on multilingual sites/projects, so this affects me regularly,- its a pity PW doesn't handle this more smoothly. Like other CMF do.
Which CMF does this? It is very challenging to have a default solution for this in the codebase IMHO. This matter becomes more complex depending on the age and size of the website. It may have several repercussions: SEO implications and content considerations, such as:
- What if some pages only exist in English? Some sites may have pages with content available only in a secondary language.
- What about hardcoded URLs in content (WYSIWYG fields)?
- Some business logic checking the language on the templates
- Etc.
-
5
-
-
-
On 10/16/2025 at 6:53 AM, Robin S said:
Maybe one of these?
Yep, I confirm this still works today. However, the website in question is still using an earlier version of ProCache. 😄
-
2
-
-
Hello there friends,
As a learning challenge, with Claude Sonnet AI's help, I installed the PEST testing framework and created a bunch of tests for Ryan's Invoices site profile. I'm pretty happy with it. 🙂🙂
You can check the project on GitHub: https://github.com/sjardim/processwire-invoices-with-pestTo try it, just install the site profile on a fresh PW project as instructed here: https://processwire.com/blog/posts/invoices-site-profile/ and copy my project's :
- the entire /test folder,
- phpunit.xml file
- and composer.json file
and install composer dependencies. Next, in your terminal, run `./vendor/bin/pest --filter=InvoicePageTest` to see the magic.
Here's a preview of the InvoicePageTest class:
Spoiler<?php // Helper functions for creating test data function createTestInvoice() { $pages = pages(); $parent = $pages->get('/invoices/'); // Adjust path as needed if (!$parent->id) { $parent = $pages->get(1); } $invoice = $pages->add('invoice', $parent, [ 'title' => 'Test Invoice ' . time(), 'date' => time(), ]); $invoice->save(); return $invoice; } // Helper functions for creating test data function createInvoiceDayPage($qty) { $pages = pages(); $parent = $pages->get('/settings/invoice-days/'); if (!$parent->id) { // If path doesn't exist, use settings or root $settings = $pages->get('/settings/'); $parent = $settings->id ? $settings : $pages->get(1); } $days = $pages->add('invoice-day', $parent, [ 'title' => "$qty Days", 'qty' => $qty, ]); $days->save(); return $days; } function cleanup($page) { if ($page && $page->id) { pages()->delete($page, true); } } beforeEach(function() { $this->invoice = null; // Get the admin user (ID 41 is the default admin user created during install) $admin = pages()->get("id=41"); if (!$admin->id) { // Fallback to finding admin by name/role if ID is different $admin = pages()->get("template=user, name=admin"); } // Store the current user so we can restore it later $this->previousUser = wire('user'); // Log in as admin if($admin->isSuperuser()) { wire('users')->setCurrentUser($admin); } }); afterEach(function() { if (isset($this->invoice) && $this->invoice) { cleanup($this->invoice); } }); test('getSubtotal calculates correct invoice subtotal', function() { $invoice = createTestInvoice(); $invoice->addLineItem('hours', 'Development', 10, 100); $invoice->save(); $invoice->addLineItem('service', 'Consulting', 5, 150); $invoice->save(); $invoice->addLineItem('product', 'License', 1, 500); $invoice->save(); expect($invoice->getSubtotal())->toBe(2250.0); expect($invoice->getSubtotal())->toBeNumeric(2250.0); $invoice->addLineItem('hours', 'Support', 2, 75); $invoice->save(); expect($invoice->getSubtotal())->toBe(2400.0); expect($invoice->getSubtotal())->toBeNumeric(2400.0); $invoice->addLineItem('hours', 'Planning', 2.5, 90.50); $invoice->save(); expect($invoice->getSubtotal())->toBe(2626.25); expect($invoice->getSubtotal())->toBeNumeric(); cleanup($invoice); });
I hope this help you in your testing journey!
-
6
-
2
-
On 7/25/2023 at 4:22 AM, joer80 said:
Do the files stay on the server or go to cloud instead?
Both. ? In the end we didn't need to link to the copied files on S3, kept the local ones. S3 works as backup only in this case.
-
We upgraded a big multi language site to 3.0.200 and to PHP 8* + MySQL 8 a couple of days ago, several thousands pages, lots of templates and fields (120MB DB).
The upgrade went fine, and the site is running super fast! I didn't measure with tools, but just by reaching the URLs of some complex pages and you can see it loading waaay faster. The client could not be happier. ?
Fantastic job, Ryan and the other contributors!
Thank you,
Sergio
---
* I used RectorPHP to help upgrading my custom modules, which was nice.
-
10
-
3
-
-
Hey Helder,
I think this will help you:
TL:DR: https://stackoverflow.com/questions/8831183/error-mysqlnd-cannot-connect-to-mysql-4-1-using-the-old-insecure-authenticatio
Try on MySQL console:SET PASSWORD FOR 'campaigns'@'localhost' = PASSWORD('MyNewPass');Good luck!
-
Great tips from Diogo and I'd like to suggest Hugo (https://gohugo.io/) as a great SSG, specially if you want to explore alternatives to javascript-based ones for two basic reasons:
1. You don't want to mess with a lot of javascript dependencies fatigue, specially as you go back to edit the project in a few months/years, and things start to break when you try to run the project.
2. The project will have 100s or 1000s of pages and you want to generate it as fast as possible.
-
2
-
-
Hi!
I think this post can help you:
-
1
-
-
Greetings!
Webflow has an super nice tutorial on implementing this using their app, BUT it's totally fine to just learn from it and to it by hand, so if you are more of a visual learner, like me, you'll enjoy it:
-
3
-
-
This looks amazing!! Thank you for your hard work and generosity! Super contribution to ProcessWire!
-
1
-
-
2 hours ago, daniel_puehringer said:
Question: is it possible to have one global field in which changes the content for the footer of all pages?
Hi Daniel!
It sure is. A simple way to do it is to have the field on only ONE page, like the homepage or a "settings" page and get this page's field content in your footer template.
For instance, if you have this field on your homepage, called "footer_text", you can get it this way:
// On your footer.php file //Get the homepage reference $homepage = $pages->get('/'); // Let's say your field is called "footer_text" echo $homepage->footer_text; // Docs: https://processwire.com/api/ref/pages/get/
-
2
-
-
14 minutes ago, PWaddict said:
It doesn't work. The title field is still empty.
Your code seems to be missing one line:
$wire->addHookAfter("Pages::saveReady", function(HookEvent $event) { $page = $event->object; //this line if($page->template->name != 'mytemplate') return; $defaultLang = wire("languages")->get("default"); $page->title->setLanguageValue($defaultLang, "New Value"); });
-
1 hour ago, JeevanisM said:
Any suggestion for this ?
25,000 per hour/day/week? It all depends.
From what you described about the app, even 25k users a day should be fine to start with a VPS with 2GB of RAM. If its usage increase a lot you can move the database to another VPS on its own AND/OR increase the VPS CPU and RAM resources very quick.
My advice is to keep things simple and not try to over-engineer the application performance from the start. But if you feel "adventurous" ? or think that the project will have this many users right away on day one (which I doubt) you can start with a "serverless" approach where the infrastructure is scaled on-demand, using https://vapor.laravel.com/ and you don't have to worry. There's a course about this approach that is very interesting: https://serverlesslaravelcourse.com/
-
2
-
1
-
-
Although doable, I'd only recommend a system like this to be implemented using ProcessWire if the rest of the project must (or already is) be highly coupled with PW and it doesn't make sense to decouple it for whatever reason. Otherwise I'd recommend you to implement it using another framework. PW shines in the content management part, and I love it, but it may present you with some limitations in its developer-experience department when you need to implement some business logic that relies heavily on integration of payment systems, user data input, generation of reports and especially tests. There's also a myriad of similar systems like this already implemented that you can use as a base, like this one https://github.com/LaravelDaily/Laravel-Test-Result-PDF (demo: https://www.youtube.com/watch?v=GmLFHGud7I8).
-
4
-
-
Try to unpublish the page where you put the iframe using the API or directly on the database 'pages' table by changing its status to "2049".
-
Strange problem. Can you try increase the maximum memory for PHP (memory_limit) by editing the file php.ini in your server directly or using a control panel?
Look for a line like this: memory_limit = 512M
-
Hi @Youbility, yes I did. It's working on production at https://www.brightline.org/
Here's a slightly different version of that one: https://gist.github.com/sjardim/d74fae71b5bfe6a44ab88efc9aaa5279
Hope that helps!
-
5
-
-
Actually, ignore that! After closing Chrome and opening it again the font-weight 300 is fine! So it was a cache on its end. The real problem seems to be my local Rubik version like you suspected!

-
1
-
-
18 hours ago, schwarzdesign said:
Maybe you have an older version of the font installed on your Computer?
Good call. I checked and I had Rubik installed so I disabled it but the problem remained, maybe I need to restart the computer to work, but I can't do it right now. But I also checked again the website and the only problem appears to be on 300 font-weight. 400 or more are fine ( I changed it to 400 on the Body as a test, screenshot attached).

-
1
-
-
-
1 hour ago, kongondo said:
Hi @Sergio, just for clarity, Carbon will work with what you hand to it, right? i.e., it has no way of knowing a user's (browser client) TZ.
Hi @kongondo, sure, but he mentioned "logged-in users can publish posts" so I think he can capture the user timezone settings on the server side, and/or, give the user to overwrite this preference on admin.
EDIT: sorry, I misread it. You are right, @kongondo! my bad!
-
I would go with the great Carbon library and handle the timezone conversion in PHP.
https://carbon.nesbot.com/docs/#api-timezone
$tz = new CarbonTimeZone('Europe/Zurich'); // instance way $tz = CarbonTimeZone::create('Europe/Zurich'); // static way // Get the original name of the timezone (can be region name or offset string): echo $tz->getName(); // Europe/Zurich echo "\n"; // toRegionName returns the first matching region or false, if timezone was created with a region name, // it will simply return this initial value. echo $tz->toRegionName(); // Europe/Zurich echo "\n"; // toOffsetName will give the current offset string for this timezone: echo $tz->toOffsetName(); // +02:00 echo "\n"; // As with DST, this offset can change depending on the date, you may pass a date argument to specify it: $winter = Carbon::parse('2018-01-01'); echo $tz->toOffsetName($winter); // +01:00 echo "\n"; $summer = Carbon::parse('2018-07-01'); echo $tz->toOffsetName($summer); // +02:00 // With no parameters, a default timezone is created: echo new CarbonTimeZone(); // UTC echo "\n"; echo CarbonTimeZone::create(); // UTC
-
You can filter by dates like so:
$events = $page->children('limit=50, date<=today, sort=-date');
Also check this thread to see more details:
date_start>=today date_start>=1365436783 date_start>=2013-04-08 date_start>=4/8/2013 date_start>=8.4.2013 date_start>="April 8, 2013"
-
2
-


How to redirect from an existent file path in the site directory or throw a 404 when its URI is requested?
in API & Templates
Posted
Considering you have i.e. `example.com/site/assets/file.zip` being accessed, you could:
1. Add a rule on Nginx as you mentioned. But ProcessWire won't help you with that; you need to change the Nginx config yourself.
location = /some/spec/path/ { root /home/myweb/path; try_files /file.zip =404; } //NOT TESTED!2. Or, if you are using Cloudflare as DNS provider, you can add a rule there to create the redirect without touching your server.