All Activity
- Today
-
Great, thanks.
-
Ryan has already merged the code from the dev branch into main branch and setup a release page for 255. However, Ryan hasn‘t yet created a 255 release tag on the Github main branch. The Github tag typically follows in some days unless a serious show stopper is found. So if you want to be 100% sure, wait a couple of days until the 255 release tag is published on Github. Have used the previous dev version for two public projects for about 1 month now without any issues, so I don‘t expect big surprises at this state.
-
DrQuincy started following ProcessWire 3.0.255 – Core updates
-
Forgive the possibly dumb question but what does this mean? I notice that the .255 tag has already been added. Does this mean that .255 will receive changes after the tag has been added or that there will be another new master version coming soon? I'm just deciding whether to upgrade my core PW site from .246 to .255 or to wait. Thanks, I love this CMS and its community!
- Yesterday
-
Hi Ivan, I haven’t had time yet to verify what (if anything) needs to be done on my side, but I’m fairly sure ProcessTranslatePage already uses the DeepL API v2. It relies on the official PHP client library and was updated in mid‑2025, so we should be in good shape. If any updates are required to keep the module working, I’ll take care of them – thanks for the heads up!
-
Good day, @robert! Thanks for the module! @FireWire has updated Fluency for DeepL API v. 2.0 which uses different authentication method. Could you please write if ProcessTranslatePage has already done that in v. 1.0? If not are you planning to update?
-
Hi @Stefanowitsch I can integrate as option a base CSS with semantic class names, similar to how I handled it in my WireMagnet module. This way, the styling can be done independently of Tailwind. I plan to release the module on GitHub in the next 2–3 weeks, once I've successfully completed some final tests.
-
Hi @markus-th! That is looking really promising. I was talking about that feature with a client not so long ago. They wanted to include a booking system (for "time slots") almost exactly like that. I am really looking forward to try out your module! Let me know when it is finished. To answer your questions: Is this something you would use? Is there a need for a native "Calendly" alternative? -> Yes. Is the dependency on Tailwind a dealbreaker? Since the markup relies on Tailwind utility classes, it might be hard to style if you use Bootstrap or custom CSS. -> I am not using Tailwind at all but UIKit. Would you provide a basic stylesheet with the module or is the Tailwind integration a must-have in that case? I am not afraid to tweak the module code to alter the style classes to make it work for UIKit, though.
-
Hi @markus-th, That’s so smart — exactly what I needed! Thank you very much for your help. Have a wonderful day!
-
-
Dee_ started following Admin with many images - performance issues
-
Hi, I’m very new to ProcessWire and I’ve tried to find some recommendations, but haven’t managed to find what I’m looking for yet. I’ve built a site (only in local for now) with each page containing one or two image fields. Some pages can contain close to 150 images per page (unfortunately, reducing the number of images is not an option in this project). This results in very long loading times in the admin when opening those pages for editing, as well as slow save times even when no new images are uploaded or modified. For context: each image only has the default thumbnail variation. All other image variations are generated independently from ProcessWire and are not handled by ImageSizer. Are there any recommended or well-known approaches to improve admin performance in this kind of scenario (many images per page)? Any best practices, architectural patterns, or optimizations would be greatly appreciated. Thank you for your help.
-
-
Hi everyone! I am currently developing a new module for a client project and wanted to quickly reach out to see if there is broader interest in the community for a solution like this. The Use Case My client needed an appointment booking system similar to "Calendly". However, they had specific requirements: Zero external dependencies: No third-party SaaS for GDPR/DSGVO compliance and to avoid monthly fees. Full Design Control: It had to fit seamlessly into their custom design. Lightweight: No heavy bloat. The Solution: WireBooking is a native ProcessWire module that handles appointment slots and bookings using standard ProcessWire pages. Current Features: Frontend Wizard: An interactive, step-by-step booking process built with AlpineJS and Tailwind CSS. Native Storage: Bookings are saved as standard ProcessWire pages (booking-entry), allowing you to use the full power of PW selectors and hooks. Backend Management: Simple interface using the native ProcessWire Admin Theme (UIkit) to view bookings. Notifications: Sends confirmation emails to the customer and admin, including generated .ics calendar files for Outlook/Apple/Google Calendar. Availability Management: Manually block specific time slots or entire date ranges via the module settings. AJAX Driven: Dynamically loads available slots via JSON to keep the initial page load light. The "Catch" (Requirements) To keep the module lightweight and modern, it is opinionated regarding the frontend stack. It assumes you are already using (or are willing to include): Tailwind CSS (Utility classes) for the styling. Usage Example: Using it in a template is extremely simple: <?php echo $modules->get('WireBooking')->renderWizard(); ?> I need your feedback! The module is currently functional for this specific use case (Consultants/Service Providers). Before I invest time into generalizing it for a public release on the modules directory, I have two questions for you: Is this something you would use? Is there a need for a native "Calendly" alternative? Is the dependency on Tailwind a dealbreaker? Since the markup relies on Tailwind utility classes, it might be hard to style if you use Bootstrap or custom CSS. Looking forward to your thoughts and suggestions! Cheers, Markus
- 3 replies
-
- 10
-
-
- Last week
-
Today I’ve merged the dev branch to the main/master branch in preparation for our next official tagged version, which is likely to be 3.0.255. I’ll likely git tag it with the version number early next week. This doesn’t mean that work on the next main/master version is complete. Just that no new issues have appeared that would warrant delaying it any longer. So while there’s still work to do, we’re also at a good point to start getting these updates on the main/master branch. As before, if you run into any issues after upgrading, please report them in the processwire-issues repo. I’ll compile and post a list of all that’s new in 3.0.255+ relative to 3.0.246 within the next week or two so stay tuned. There have been some really nice sites showing up in our sites directory lately. Thank you for those that have been submitting new ProcessWire-powered sites, and please keep it up! It’s great to see such awesome web design and development work.
- 4 replies
-
- 13
-
-
-
Dee_ joined the community
-
Nicole H started following File Mover
-
Hello everyone, I’m happy to share a new module I’ve been working on: WireMagnet. We often face the requirement to offer "gated content" (like Whitepapers, PDFs, or Zip files) where users need to provide their email address to receive a download link. While there are external services for this, I wanted a native, privacy-friendly, and lightweight ProcessWire solution. What does WireMagnet do? WireMagnet handles the entire flow of capturing leads and delivering files securely. It intercepts form submissions, logs the lead, and sends an email with a unique, temporary download token. It prevents direct access to the files (assets are not just sitting in a public folder). Key Features: Secure Delivery: Generates unique download tokens (valid for 24 hours) and serves files via wireSendFile(). Double Opt-In (DOI): Optional support for DOI to verify email addresses before sending the file. Automated Emails: Automatically sends the download link (or attaches the file directly if preferred). AJAX Ready: Comes with built-in Alpine.js support for seamless, reload-free form submissions. Lead Management: Logs all subscribers (Email, IP, Timestamp) to a custom database table (leads_archive). Admin Interface: View leads and export them to CSV directly from the ProcessWire backend. Easy Integration: Render the form with a single line of code. How to use: Install the module. Create a page (e.g., using a lead-magnet template) and upload your file to a file field. Output the form in your template: // Render the subscription form (default field: 'lead_file') // The module automatically handles success/error messages and styling. echo $modules->get('WireMagnet')->renderForm($page); // OR: Render for a specific field (e.g., if you have multiple magnets or custom field names) echo $modules->get('WireMagnet')->renderForm($page, 'my_custom_file_field'); // OR: Override the button text manually echo $modules->get('WireMagnet')->renderForm($page, 'lead_file', 'Send me the PDF!'); Configuration: You can configure the sender address, email subject, DOI settings, and styling preferences (like button text) in the module settings. Download & Source: GitHub: https://github.com/markusthomas/WireMagnet Modules Directory: later I'm looking forward to your feedback and suggestions! Cheers, Markus
-
- 13
-
-
-
@szabesz Thanks, I was able to duplicate that also. I couldn't figure out how to fix it, but @diogo had a look and came up with a solution. It should be on the dev branch now. Please let me know if you still run into the issue.
-
Awesome! Yes, Opus 4.5 is really good now with PW. It also helps a lot that they have implemented the LSP in Claude Code directly. Honestly, at this stage I don't think we even need to feed docs to it anymore. Just instructions to explore the relevant API methods for a task itself itself in the codebase. Is there a specific reason why you implemented that as MCP and not as Skill? MCPs eat a lot of context. Depends on the implementation, of course. So dunno about how much context Octopus occupies. ATM I have some basic instructions in CLAUDE.md that explain how to bootstrap PW and use the CLI through ddev for exploration, debugging, DB queries. That makes a big difference already. Opus is great at exploring stuff through the PHP CLI, either as one-liners or as script files for more complex stuff. Here's my current instructions: ## PHP CLI Usage (ddev) All PHP CLI commands **must run through ddev** to use the web container's PHP interpreter. ### Basic Commands ```bash # Run PHP directly ddev php script.php # Check PHP version ddev php --version # Execute arbitrary command in web container ddev exec php script.php # Interactive shell in web container ddev ssh ``` ### ProcessWire Bootstrap Bootstrap ProcessWire by including `./index.php` from project root. After include, full PW API is available (`$pages`, `$page`, `$config`, `$sanitizer`, etc.). **All CLI script files must be placed in `./cli_scripts/`.** **Inline script execution:** ```bash ddev exec php -r "namespace ProcessWire; include('./index.php'); echo \$pages->count('template=product');" ``` **Run a PHP script:** ```bash ddev php cli_scripts/myscript.php ``` **Example CLI script** (`cli_scripts/example.php`): ```php <?php namespace ProcessWire; include(__DIR__ . '/../index.php'); // PW API now available $products = $pages->find('template=product'); foreach ($products as $p) { echo "{$p->id}: {$p->title}\n"; } ``` ### PHP CLI Usage for Debugging & Information Gathering Examples **One-liners** — use `ddev php -r` with functions API (`pages()`, `templates()`, `modules()`) to avoid bash `$` variable expansion. Local variables still need escaping (`\$t`). Prefix output with `PHP_EOL` to separate from RockMigrations log noise: ```bash # Count pages by template ddev php -r "namespace ProcessWire; include('./index.php'); echo PHP_EOL.'Products: '.pages()->count('template=product');" # Check module status ddev php -r "namespace ProcessWire; include('./index.php'); echo PHP_EOL.(modules()->isInstalled('ProcessShop') ? 'yes' : 'no');" # List all templates (note \$t escaping for local var) ddev php -r "namespace ProcessWire; include('./index.php'); foreach(templates() as \$t) echo \$t->name.PHP_EOL;" ``` **Script files** — preferred for complex queries, place in `./cli_scripts/`: ```php // cli_scripts/inspect_fields.php <?php namespace ProcessWire; include(__DIR__ . '/../index.php'); $p = pages()->get('/'); print_r($p->getFields()->each('name')); ``` ```bash ddev php cli_scripts/inspect_fields.php ``` ### TracyDebugger in CLI **Works in CLI:** - `d($var, $title)` — dumps to terminal using `print_r()` for arrays/objects - `TD::dump()` / `TD::dumpBig()` — same behavior **Does NOT work in CLI:** - `bd()` / `barDump()` — requires browser debug bar **Example:** ```php <?php namespace ProcessWire; include(__DIR__ . '/../index.php'); $page = pages()->get('/'); d($page, 'Home page'); // outputs to terminal d($page->getFields()->each('name'), 'Fields'); ``` ### Direct Database Queries Use `database()` (returns `WireDatabasePDO`, a PDO wrapper) for raw SQL queries: ```php <?php namespace ProcessWire; include(__DIR__ . '/../index.php'); // Prepared statement with named parameter $query = database()->prepare("SELECT * FROM pages WHERE template = :tpl LIMIT 5"); $query->execute(['tpl' => 'product']); $rows = $query->fetchAll(\PDO::FETCH_ASSOC); // Simple query $result = database()->query("SELECT COUNT(*) FROM pages"); echo $result->fetchColumn(); ``` **Key methods:** - `database()->prepare($sql)` — prepared statement, use `:param` placeholders - `database()->query($sql)` — direct query (no params) - `$query->execute(['param' => $value])` — bind and execute - `$query->fetch(\PDO::FETCH_ASSOC)` — single row - `$query->fetchAll(\PDO::FETCH_ASSOC)` — all rows - `$query->fetchColumn()` — single value **Example** (`cli_scripts/query_module_data.php`): ```php <?php namespace ProcessWire; include(__DIR__ . '/../index.php'); $query = database()->prepare("SELECT data FROM modules WHERE class = :class"); $query->execute(['class' => 'ProcessPageListerPro']); $row = $query->fetch(\PDO::FETCH_ASSOC); print_r(json_decode($row['data'], true)); ``` ### ddev Exec Options - `ddev exec --dir /var/www/html/site <cmd>` — run from specific directory - `ddev exec -s db <cmd>` — run in database container - `ddev mysql` — MySQL client access
-
I spent a few hours this morning making an MCP module for ProcessWire similar to Laravel Boost. I'm going to call it Octopus. In just 2-3 hours with Opus 4.5, I'm already what feels like being done with 90% of it. I'm going to finish the remaining 90% (heh) as I work on various projects to actually test it. I will have to figure out the best way on how to provide ProcessWire documentation to the MCP (hence why I'm on this thread), but even without it, Opus 4.5 is insanely good in following ProcessWire conventions, even with little context! The hype is real. Let me know if you have any questions or suggestions. Screenshot attached.
-
Taskbar Icon Overlay (custom little Windows 11 program)
Jonathan Lahijani replied to Jonathan Lahijani's topic in Pub
@BrendonKoz The problem with that option in the screenshot is that while it ungroups the taskbar items, it keeps the "text" part of it, which I don't want because it's not necessary for me and I like to have a lot of windows open so I want to conserve horizontal space. Windows 10 used to have that option, but they removed it in Windows 11. That's why you have to use this Windhawk mod I mentioned in the readme: https://windhawk.net/mods/taskbar-grouping A registry setting alone won't fix it unfortunately. Come on Microsoft! -
Taskbar Icon Overlay (custom little Windows 11 program)
BrendonKoz replied to Jonathan Lahijani's topic in Pub
That's a pretty neat way to distinguish without hovering over the app icon for the window preview (or using WIN+TAB). For what it's worth, if you didn't want to install an application to un-group your applications in the taskbar, I think the Windows Settings app allows you to customize that. If I'm wrong, then it still exists via registry, and is accessible via Group Policy. Start -> Run: "gpedit.msc" User Configuration > Administrative Templates > Start Menu and Taskbar > "Prevent grouping of taskbar items" ... set to "Enabled". -
Jonathan Lahijani started following Taskbar Icon Overlay (custom little Windows 11 program)
-
While my plan is to switch to Linux one day (probably Omarchy), I'm still putting that (and tiling window managers) off for a bit. Let it cook a little more. In Windows 11, I like my taskbar, but one nagging thing is that it's hard to differentiate the icons of many Code/Codium instances given that I don't group them. I use both programs actually: Code for actual coding and Codium as my Markdown note taking tool (I prefer to not use Obsidian and the million other markdown editors; Code/Codium for Markdown is fantastic since you get all the developer ergonomics) With the help of AI, I developed a program with dotnet that makes it easy to add custom icon overlays effectively differentiating the program instances. This saves a lot of headache of knowing which icon corresponds to which project with a quick glance. Feel free to use it! https://github.com/jlahijani/TaskbarIconOverlay
-
WaQ9FXrA joined the community
-
Fieldtype module, field names cannot be used in selectors
thei replied to thei's topic in Module/Plugin Development
next effect: mapping of fieldnames to true columns names has also be handled by overloading getMatchQuerySort() of FieldType private function mapColumnNames($fieldName) { $subfieldMap = [ 'date_from'=>'data', 'date_to'=>'to']; $col = array_key_exists($fieldName, $subfieldMap) ? $subfieldMap[$fieldName] : $fieldName; return $col; } /** * adapts the getMatchQuery() of the parent by mapping the column names */ public function getMatchQuery($query, $table, $subfield, $operator, $value) { return parent::getMatchQuery($query, $table, $this->mapColumnNames($subfield), $operator, $value); } /** * adapts the getMatchQuerySort() of the parent by mapping the column names */ public function getMatchQuerySort(Field $field, $query, $table, $subfield, $desc) { $col = $this->mapColumnNames($subfield); // return PW internal sort query string return "_sort_{$field->name}_{$subfield}.{$col} " . ($desc ? 'DESC' : 'ASC'); } Welcome to the PW reverse engineering club - Happy hour wednesday 17-18 pm -
In need for a Media Manager solution
Stefanowitsch replied to Stefanowitsch's topic in General Support
Until we get an "official" media manger module we need to make some workarounds. Let me tell you about my personal solution for this: I am using the FileMover module from @Robin S for copying images from a global "media library" field (that is placed inside a dedicated "media library" template ) to any of my image fields. Please have look at robins comment here where he extended the functionality of his module through a hook. In this case you can open the image library page through a modal with a click from any image field. There is also a small screencast that shows this – for me this is a really good workaround. Please have a look for yourself and give it a try (and some credits to robin!). -
David Guez Art joined the community
-
adrian started following FieldtypeTimezone - Dynamic Timezone Field with DST Support
-
timezone FieldtypeTimezone - Dynamic Timezone Field with DST Support
adrian replied to maximus's topic in Modules/Plugins
Thanks for this @maximus - timezone DST changes are definitely an annoyance in development. I am curious though why you have a limited set of timezones available, rather than the complete set? I feel like it might be particularly problematic if you rely on a service like https://ipapi.co/ to determine the user's timezone from their IP address. Many of the timezones returned from that are not likely to match your list. I can see that the way you have organized them makes it much simpler for user selection, and maybe that is your primary goal but I still wonder about how it might impact its functionality. -
@thei Glad you got it working. It should be possible to use an array for this, but I might be forgetting something about it, as I think it's been a long time since I used one for this. In any case, it's definitely better to use a WireData object (or one derived from it) because ProcessWire can track changes to the properties in the object. Whereas there's no change tracking built into an array.