All Activity
- Today
-
Hey everyone! I just released a new module called InviteAccess. It's something I built for my own workflow and figured it might be useful for others too. The problem: when handing off a staging site to a client or a design agency, you either open it to the world or reach for HTTP Basic Auth — which works but isn't pretty and requires server config. I wanted something in between: a proper gate page that looks like it belongs to the project, with separate codes for each team. What it does InviteAccess hooks into ProcessPageView::execute (before any template rendering) and blocks all frontend requests until a valid invite code is entered. Logged-in ProcessWire users always pass through automatically. You define codes in the module config, one per line: SUMMER2025|Summer Campaign AGENCY-PREVIEW|Agency Team CLIENT-ACCESS|Client Preview The label after the pipe shows up in the access log, so you can see exactly which team accessed the site and when. Features Multiple invite codes with optional labels Session-based auth — enter once, stays valid for a configurable number of hours JSON access log with timestamp, IP, user agent, URL — last 50 entries shown right in the admin config panel Light / Dark / Auto theme switcher on the gate page (saved in localStorage, reacts to OS preference) Accent color setting — red, blue, green or black Configurable allowed pages that bypass the gate entirely CSRF protection, hash_equals() for timing-safe comparison, Cloudflare-aware IP detection The gate page uses ApfelGrotezk font and a design inspired by processwire main page itself — warm gray background, white card, mobile-first. Screenshots Installation cd site/modules git clone https://github.com/mxmsmnv/InviteAccess.git Then Modules → Refresh → Install → Configure. GitHub: https://github.com/mxmsmnv/InviteAccess Happy to hear any feedback or suggestions!
-
- 1
-
-
Hi everyone, I'd like to share a module I've been working on: WirePDF — a PDF generation module with full UTF-8 and Cyrillic support. What it does Adds a toPdf() hook to any page, so generating a PDF is as simple as: $page->toPdf(['filename' => 'document.pdf']); You can also pass custom HTML, use a dedicated template file, or save the PDF directly to disk. Key features Two engines: mPDF (recommended) and Dompdf Full field support: all native PW fields + ProFields (Table, Repeater, RepeaterMatrix, Combo) Typography: 14 fonts including DejaVu Sans for multilingual/Cyrillic content Headers & footers with {PAGENO}, {nbpg}, {DATE}, {sitename} variables Watermarks, password protection, configurable margins and paper sizes Logging via ProcessWire's built-in log system (Setup > Logs > wirepdf) Installation cd /site/modules git clone https://github.com/mxmsmnv/WirePDF.git cd WirePDF composer install Then install via Modules > Refresh in the admin. GitHub: https://github.com/mxmsmnv/WirePDF Feedback and bug reports welcome!
-
- 1
-
- Yesterday
-
For those who want to play around with that workflow: https://github.com/webmanufaktur/pwaiworkflow-profile DDEV setup (customise .ddev/config.yaml to your needs) clean ProcessWire installation clean database backup: site/assets/backups/database/clean-start.sql all necessary modules (core, 3rd party) Skills in .agents + custom symlinks for various IDE/tools AGENTS.md ready to go Testing & Demo: Branch: feature-restaurants-directory Specs file: https://github.com/webmanufaktur/pwaiworkflow-profile/blob/feature-restaurants-directory/specs/restaurants-directory.md Ask your agent to run that file and see what happens. Results may vary. Minimax M2.5 was fine, Z.AI GLM-5 did way better. Tell me your results and findings if you like to share. Reference result with Claude Sonnet 4.6 for comparison: https://github.com/webmanufaktur/pwaiworkflow-profile/tree/feature-restaurants-directory-claude-sonnet-46
-
i think you need complete form https://processwire.com/about/contact/
-
elabx started following [WIP] Media Hub - the centralised hub for your PW media
-
[WIP] Media Hub - the centralised hub for your PW media
elabx replied to Peter Knight's topic in Module/Plugin Development
This looks amazin @Peter Knight, are you releasing this to the public or as a paid module? -
pgoronja started following How to Leverage AI for Smarter ProcessWire Development , AiWire , PromptAI and 1 other
-
https://github.com/MSCLN/processwire-basque-language-pack Translated from the spanish language pack https://processwire.com/modules/pw_spanish/
-
- 2
-
-
Hello, how can I remove my project from the showcase directory?
-
Glad to hear that! In the age of AI I think it's hard to get your mind to have patience and stop to learn the fundamentals, so kudos to you!
- 7 replies
-
- 2
-
-
- beginner portfolio
- masonry
-
(and 3 more)
Tagged with:
-
Very helpful, thanks. Haha yes Claude is very supportive 😂 Always try to verify if I can though while I'm learning. So it's a bit like function scope in JS then, the use keyword lets the function see outside itself. You've taught me a lot in this thread, cheers for that
- 7 replies
-
- beginner portfolio
- masonry
-
(and 3 more)
Tagged with:
-
Just seems more appropiate! Since WireArray is the base iterable array type in ProcessWire, it's a really handy way to work with lists of things imho. PageArray is meant to work for situations that need pagination from my understanding. Here the intention is to import Pagefile objects returned within a collection (Pagefiles, heads up on plural!), from the findTag method. So you end up with a WireArray containing Pagefile objects. I haven't tested any of this so please bear with me if there are any errors! You're absolutely right! (Claude pun intended) it should be $item as the anonymous function parameter. The syntax for use (&$images) is to pass the WireArray as reference into the context of the anonymous function, the anon function wouldn't know about the $images variable if not passed like this. If we didn't use the "&" we would be passing the value not the reference to the variable and we wouldn't be able to use $images as a "bucket of Pagefile objects". Example.
- 7 replies
-
- 1
-
-
- beginner portfolio
- masonry
-
(and 3 more)
Tagged with:
-
Really appreciate your time, @elabx thank you. Out of interest, what are the benefits of using wire arrays over page arrays here? $images = new WireArray(); $project->section->each(function($images) use(&$images){ // should it be function($item) here, where $item is a repeater item group? $images->import($item->images->findTag("gallery")); }; I tried to get Claude to explain the code line by line but sometimes it doesn't get it right 😅 Did you mean function($item) instead of function($images)? - I'm assuming this like looks at each item in the section repeater like a foreach loop (?) - the use(&images) thing confuses me too. My guess is that it updates/appends the $images wirearray with the images inside the section items? it's just that use(&... thing I don't understand. Sorry! EDIT: So use(&$variable) allows the original $images variable to be updated directly, if i understand correctly.
- 7 replies
-
- beginner portfolio
- masonry
-
(and 3 more)
Tagged with:
-
wbmnfktr started following How to Leverage AI for Smarter ProcessWire Development
-
Not that long ago I started with a completely new approach in regards to ProcessWire an AI. I had some rules, commands, and settings for Windsurf and Cursor months back but nothing really worked as good as I hoped it would and lost interest. Even switched to Astro, NextJS, BHVR, and other JS solutions. 🙈 ProcessWire-based development went back to 80% hand-coded with some assistance on the sidelines, mostly debugging, security, and tasks that were more PHP-focussed than ProcessWire-related. Then AGENTS.md and SKILLS came up. Custom instructions, guardrails, links to docs and example code. Almost similar to a README.md but for AI coding tools. The main problem still was the knowledge gap in models. They just didn't know enough about ProcessWire works and how to do more complex stuff. With SKILLS this changed. I pulled the entire docs, some blog posts, took some of the old recipes and let the AI do its magic. The AI repackaged the entire docs, custom instructions, module docs, PHP best practices, and everything else into skills. I installed new and clean instances of ProcessWire and just asked the AI to build things. Yeah... didn't work as expected. I gave the AI more tools to work with and fixed the AGENTS.md: RockMigrations - for creating and updating templates, fields, and pages 🥰 AutoTemplateStubs - for details about existing templates and fields 🤯 ProcessDatabaseBackups - can be a good idea to give your tools a database file it can look into without the need to bootstrap ProcessWire into a custom script or similar. Inline comments in config.php to mark things as important or noteworthy otherwise that file would be ignored /init - a custom action OpenCode, Claude Code, and some other tools have to initialize the whole project 💯 Now my tools have all the skills and know how to use RockMigrations to create templates, fields, and pages, can trigger database backups and look into the made changes, know how to build a custom module. Even custom page classes or URL hooks aren't a problem anymore. The AGENTS.md contains now critical changes in the config.php, has links to all the skills, and whatever necessary. The /init command is very capable of creating it nowadays. I just started to test it more and more. With fresh installations, older projects and even recent projects that have tons of everything. Whenever problems occure I let the AI update the skills or create new ones that take care of the problems it faced. Learning by mistakes. The overall workflow A README.md with a scope of the project, necessary templates and their fields, overall main features besides handling page rendering, like a bookmarking function for recipes or read articles, newsletter signups, automation tasks to clean up older data, and whatever the project needs. The amount of typing is still the same but now mainly in markdown files that explain what to build (/specs), what to fix (/issues), and what we have done already (/docs). I always start in PLAN mode. Starting simple with the overall idea, goals, and outcome. Then the combination of tool and model is important. OpenCode and Claude Code are great at thinking and planning but they need a capable model like Opus, Kimi K2.5 Thinking or even GLM-5. They start to ask questions, give options, recommend workflows. When that's done i ask to save everything to a file in the /specs folder. From here I can either switch to BUILD mode, manually tweaks the plan file, or let other models (Gemini 3 Pro or Codex) review it and ask for suggestions, changes, fixes. Github: https://github.com/webmanufaktur/pwaiworkflow/ Installation: Download and extract files Move entire .agents folder into the project root next to the wire/ folder Look into create-symlinks.sh, run if necessary --- Plans Windsurf $10/month (Legacy) with access to all Anthropic, OpenAI, Google models, and many more Z.AI Coding Plan Pro $120/year (BlackFriday Deal) with all GLM models, including GLM-5 and future releases Kimi Moderato $19/month with Kimi K2.5 (just expired) Minimax Coding Plan $20/month with M2.5 (started using it as successor to Kimi) Tools OpenCode - https://opencode.ai/ Similar to Claude Code, easy to configure, and even easier to extend with custom modes, agents, skills, and whatever you might need or want. Has a great planning mode and doesn't ask unnecessary questions in the middle of tasks like Claude Code did for a while just to burn more tokens. Kimi Code CLI (with Kimi K2.5) - https://www.kimi.com/code/en Tested it last month and while it's a CLI like OpenCode/Claude Code it feels and works totally different. It doesn't have any modes but supports AGENTS.md and SKILLS. Super fast and it is super capable for quick fixes, smaller features, or heavy automations. Windsurf IDE - https://windsurf.com/editor Like Cursor with almost identical features, a custom terminal integration, includes a browser that has full access and control which is great for debugging, UI/UX (especially with Opus 4x.) - I guess most of you have seen in the past or even tried it. Was called Codium before and I know some of you used that Codium Extension which was awesome.
- Last week
-
I can guarantee from experience all these work together fine. This could be another logic for your what you are trying to achieve, although I don't see anything wrong in your snippet! Just figuring out that if you are getting started you might find these examples useful: // assuming section is the name of the repeater $projects = $pages->find("template=project, section.images.tags=gallery"); foreach ($projects as $project) { $title = $project->project_header->first()->project_title; // Maybe something like this to get images from any of the repeaters? $images = new WireArray(); $project->section->each(function($images) use(&$images){ $images->import($item->images->findTag("gallery")); }; foreach ($images as $img) { echo "<a href='{$project->url}' title='{$title}'>"; echo $img->render(); echo "</a>"; } }
- 7 replies
-
- beginner portfolio
- masonry
-
(and 3 more)
Tagged with:
-
module StripePaymentLinks – Simple Checkout Integration for ProcessWire
chuckymendoza replied to Mikel's topic in Modules/Plugins
Hello Mikel, First of all, this looks like a great module. We have been looking for a way to sell fonts as easily as possible for a long time, but haven't found a simple solution. I have a question regarding product delivery for multiple digital products. We want to sell digital files, specifically fonts. There are special requirements for fonts, and I would like to know if this is possible with the module. We usually have several product pages for different font families. Here, either the entire family or individual styles can be purchased. We don’t have product pages for single fonts that belong to a font family. Example: The product page “Font Family A” contains 4 purchase options: 1) Font style Regular 2) Bold font style 3) Italic font style 4) Family (includes Regular, Bold, Italic) Of course, there are also cases with font families where we have 15 or more font styles. My question is, if someone buys and pays for Regular and Bold, what does the customer get as the product delivery page? Our idea is, they receive a delivery page showing all fonts purchased to date, including the fonts they have just purchased, which can be downloaded by clicking on one of the font styles. As I understand it, the customer receives one delivery page per product? That would make it quite cumbersome for the customer to download all font styles. Would love to hear about your thoughts. Thomas -
Hi @elabx Thanks for your post. Your code looks clean but I'd like a little more flexibility ideally for my use case. I'd like the option to choose any image from my projects (not just the first). Also, sometimes I'll need to pick more than one image from the same project for display on the masonry gallery. For this reason, I'm thinking image tags might be the way to go but then the question is, how do I wrap that image in a link to its respective project page.. Page references seem like the way to go, but I'm still trying to wrap my head around how these work tbh. Custom image fields could also work but I'm trying to keep things as simple as possible. I also don't want to screw up alt fields for SEO and I'm looking to use PageimageSource to manage srcset and webp automatically (maybe I'm looking to learn too much at once for my first PW site 😂) https://github.com/nbcommunication/PageimageSource Assuming all image fields are image arrays with tags enabled in admin, could I do this?: // "sections" is the repeater on my projects pages that contain images and content. // "project_header" is a repeater in project template that contains project title and info. // Can I can use find() to get repeaters with template=repeater_repeaterName, like this? $projSections = $pages->find("template=repeater_sections, images.tags=gallery"); foreach ($projSections as $section) { $projectPage = $section->getForPage(); $title = $projectPage->project_header->first()->project_title; foreach ($section->images->findTag("gallery") as $img) { echo "<a href='{$projectPage->url}' title='{$title}'>"; echo $img->render(); echo "</a>"; } } It seems inefficient to me to have to parse through all project content repeaters for tagged images like this but maybe with caching it wouldn't be a problem? In my setup project title and description text is in one repeater, and all images are in another - not sure if that complicates things. I would like to wrap each image in a <a> that links to the respective project page.
- 7 replies
-
- beginner portfolio
- masonry
-
(and 3 more)
Tagged with:
-
My personal solution for this issue, without using third party modules, has been: Setup a page reference field on the home template, that lets me pick the projects I want to showcase, and I make the assumption that l'll pick the first image of the gallery of each project. So i the home template you'll end up with something like: <div id="masonry-gallery"> <?php foreach($page->portfolio_pick as $project):?> <img src="<?=$project->gallery->first->url?>"> <?php endforeach ?> </div> - gallery being the field within the project template. - portfolio_pick being the page reference field on the home template. Another thing I've done, but that I'm not a huge fan of for certain uses, is adding a extra fields to the image field, in this example, the field "gallery" in the project template. So you can then code something like this on the home template: <div id="masonry-gallery"> <?php foreach($page->portfolio_pick as $project):?> <img src="<?=$project->gallery->findOne('is_main_image=1')->url?>"> <?php endforeach ?> </div>
- 7 replies
-
- beginner portfolio
- masonry
-
(and 3 more)
Tagged with:
-
Hello @ttbb This should work by default 😐, so there is no need to add it to the JS manually. To be more specific: If a form submission is successful or has errors, than the page jumps to the start of the form (not to the top as you have written), so the user can see the success or the error message (independent of the length of the form). This should work with or without AJAX. If it does not work in your case, please post your form code here or send it to me via PM and I will test it. Best regards Jürgen
-
Hello all, Another day, another thread! 😅 So I'm building out a portfolio site bit by bit, and trying to learn how ProcessWire works for clients in the meantime. Below is a screenshot of what a project page might look like. The project header is made with a project repeater and some txt fields. Below this is another repeater (sections) - that's where my project images live. What I'd like to make: a curated gallery page (like a photographer's portfolio page) where I can manually choose images from across my project pages to be displayed in a masonry style layout (e.g. like Masonry.js https://masonry.desandro.com/) I'd like to avoid duplication or double uploads - I'd like to reuse existing project images and keep my setup as fast/light as possible Clicking an image on the gallery should link to the related project Ideally without resorting to third party solutions - could image tags be used like an image reference? I've read a discussion on community requests for something like an image reference field (which would be great) but it looks like this isn't natively supported in PW yet: https://github.com/processwire/processwire-requests/issues/207 I'm wondering if I could use PW's built in image tags or something and then display all of those on a gallery page layout. But I'm not sure if I could grab the related project page links through tags alone? Fyi, I'm also using the PageimageSource module to keep things efficient. https://github.com/nbcommunication/PageimageSource Beginner here, so maybe I'm thinking about this the wrong way. Would be nice to hear your thoughts. Thanks!
- 7 replies
-
- beginner portfolio
- masonry
-
(and 3 more)
Tagged with:
-
Thanks @maximus - looks good so far - I'll keep testing and let you know if I find any other issues.
-
BenSlayers changed their profile photo
-
I wanted to add: This gives you basically something like context7. But locally with your very specific knowledge and not implemented as MCP but as skill which has less overhead in the context window. And you could modify it easily for other knowledge. Different frameworks, whatever.
-
Skill is up at https://github.com/gebeer/processwire-ai-docs/tree/main/skills/processwire-memory You need to install memvid-cli. It's all in the README and skill. You can build your memory file with docs you need from https://github.com/phlppschrr/processwire-api-docs/blob/main/api-docs/index.md If you want me to share my mem file (~35MB), I can do that, too. I haven't used it a lot yet but it seems to work quite well. Maybe needs some work on the proactive part so that agents know when to lookup stuff even if not explicitly prompted. Implementing that depends very much on the AI tools you're using. For Claude Code hooks would be a good place. Others like Cursor, I don't know.
-
Yes, very good results. It's fast and pretty token efficient. You can connect it to an already open browser wit a logged in session etc. no need for auto-login route. let your agent read the mcp instructions. mine said to start chrome with a debug flag. Let me pulled that up through my conversation-search MCP quickly. Here it is :-) Launch command (detached from terminal): setsid chromium --remote-debugging-port=9222 &>/dev/null & - --remote-debugging-port=9222 — enables CDP so the MCP can connect - setsid — creates a new session, fully detached from the terminal's process group (plain nohup doesn't survive terminal close because the terminal sends SIGTERM, not just SIGHUP) - &>/dev/null & — suppresses output and backgrounds it That's for Linux but should work on your Mac, too. In that browser you open your PW project, backend and then the mcp can connect. That's the way it's supposed to be done, I guess.
-
And you get useful results? I installed it in cursor and it was impressive to see the browser pop up, but not really useful... I even added an /auto-login route to RockDevTools to make the mcp login as superuser by default, but still it was not able to fix such a latte exception issue.