Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation since 06/09/2026 in all areas

  1. This week we've got a big batch of issue fixes on the core dev branch (about 18 fixes), most related to GitHub issue reports. I've also been catching up on some client work this week, so not as many updates as in the last few weeks. As I use more AI in my work, I've been building up a real desire to understand how it works. To me it seems like magic. So recently I started building a language model in PHP. Admittedly PHP isn't the ideal language for building such a thing, but this is really about learning, and so I thought I should use the language I know best. Using something like PyTorch in Python would certainly make things much easier, but would also abstract away a lot of the understanding I want to get out of the project. The new model (and future ProcessWire module) is called Rambler. Currently it rambles on, often incoherently, hence the name Rambler. Though it'll get more coherent as time goes on, no doubt (hopefully!). Rambler uses zero machine learning libraries, no black boxes, and in fact has no dependencies at all. It's just pure PHP implementing the same mathematical foundations that power modern AI systems like GPT, at least that's the goal. I'm writing all the code myself, but I do have Claude as my teacher, describing each step, teaching me the concepts and terminology, and telling me what I need to code. After I code each part, he looks at it and tells me what I did right and wrong. It's a slow process but I learn by doing, and so it's also a lot of fun. It certainly helps to have an infinitely patient teacher. Currently the project runs two models side by side (for comparison): A Markov n-gram model, which is a classical statistical approach that predicts the next word based on how often word sequences appeared in training data. A neural network model that learns distributed word representations called embeddings. The neural model passes those embeddings through a hidden layer with ReLU activation, then predicts the next word using a softmax output. As far as I understand it, these are the same core building blocks used in early neural language models. The most time consuming part of doing this in PHP is the training. Python has libraries and functions that handle a lot of the hardcore math in ways that can take advantage of the hardware, like GPUs. But this is not the case with PHP, so training uses the CPU, and a lot of it! As far as the training system goes, it uses mini-batch gradient descent with backpropagation. The model makes predictions, measures how wrong it was (which is the "loss"), and then works backwards through the network, computing gradients to adjust every weight in the right direction. Rambler also includes two tokenizers: A word-level tokenizer, and a BPE (byte pair encoding) tokenizer. BPE is the subword strategy that is used by GPT, Claude and other modern LLMs. But for the small scale that I'm working at, the word-level tokenizer works faster, so far. The next milestone is adding an attention mechanism in a RamblerTransformer subclass. This attention mechanism (a transformer) is the core innovation behind a lot of modern LLMs. I'm hoping to get started on that part this weekend. Beyond being a learning exercise, the longer-term goal is to train it on all of the ProcessWire documentation (which is what they call a "corpus" in this context) and release it on GitHub as a learning resource, and a PW module. Perhaps someday it'll be a tool in ProcessWire, or at least a really smart search engine for ProcessWire, we'll see. As far as I could tell, there aren't any other PHP-based language models that use the same technologies used by modern LLMs, so I figured, why not. I want to understand how they work under the hood without wading through Python frameworks, and I'm sure others do too. Once I get a little farther along with it, I look forward to getting it up on GitHub as a standalone project, but also as a ProcessWire module. The slowness of the training process (the model, not me... well okay, probably me too) is the hard part. I'm currently running a 30 hour training on all the text from a book. When the project is finished, I'm likely going to have Claude or Codex do a translation of the training code into C, that takes advantage of the much faster math capabilities available there. From what I understand, a 30 hour training in PHP will take about 30 minutes in C. I don't know if that's accurate or not, but it sounds good enough that I'm going to find out. 🙂 Thanks for reading and have a great weekend!
    27 points
  2. Hi everyone, Most ProcessWire sites need some form of community interaction — reviews on product pages, Q&A on documentation, discussions on articles. Vox adds all of that without leaving your PW install. GitHub: https://github.com/mxmsmnv/Vox Demo: https://vox.smnv.org/vox-demo/ What it does Reviews — star or dot ratings, custom fields per template, photo attachments Q&A — questions with best-answer selection Discussions — open threads with nested replies Block comments — inline comment panels for specific sections on a page Guest posting — with optional email requirement Moderation — approval queues, reports, stop-word filtering Gamification — points, ranks, badges, leaderboards REST API — via VoxApi submodule Admin section — browse, filter, approve/reject/remove content; configure per template; manage ranks and badges Screenshots One or multiple widgets per page, combinable into tabs. Ships with an optional demo with restaurant, hotel, and product sample data. Requirements: ProcessWire 3.0+, PHP 8.0+ MIT License.
    11 points
  3. Wake up. Work with ProcessWire. Drink coffee. Repeat. Anyone else wonder how they got so lucky to be able to work with ProcessWire every day? 🤗 I often wonder if developers on other systems feel the same. What are you working on today?
    10 points
  4. Thx for the loveletter @gebeer and others. I thought I've already replied, but it seems that post got lost. I'm getting a lot of 500 errors these days in the forum. I wouldn't say I've quit the community. What I've stepped away from is making significant investments in the ecosystem and trying to build a business around it. That didn't work out for me, so I had to move on. As for RockMigrations: I understand and even share some of the concerns raised here (even though I find terms like "bloated nature" a bit harsh). It started as a somewhat experimental proof of concept, and yes, I built it with my other modules in mind. At the same time, it has always been completely free because I felt it was too important to put behind a paywall, and it has always been open to PRs. 😉 Nevertheless, over time it turned out to be very reliable and became an essential tool for my work. Considering that all my ProcessWire projects from the last decade rely on it, I expect it will remain supported for quite some time. That's the status quo. What I did find a little surprising, though, was seeing migrations become part of the core years later, seemingly almost overnight, while RockMigrations and the other migration modules weren't much of a reference point in that process. Unfortunately, it's not the first time I've seen that happen. What I learned from that experience is that it's not something I can build a business on. So I really haven't quit on the community — I've simply moved on from trying to build a business around my ProcessWire contributions, and my reduced forum activity is just a consequence of that. But I check in from time to time to see what's going on and I try my best to be available and helpful if anybody needs anything related to my modules. 🙂
    8 points
  5. 7 points
  6. Hi everyone, Accessibility overlays have a bad reputation — mostly because they're sold as SaaS, phone home to third-party servers, and charge monthly fees for something that should be built-in. Ally is different: self-hosted, MIT, no external requests at runtime. GitHub: https://github.com/mxmsmnv/Ally What it does Adds an accessibility panel to your site's frontend, powered by Sienna (MIT). The JS bundle and OpenDyslexic font ship with the module and are served from your own server — nothing loads from external CDNs at runtime. Font size adjustment Dark, light, and high contrast modes High/low saturation, monochrome Dyslexia-friendly font (OpenDyslexic, bundled locally) Highlight links and headings Letter spacing, line height, bold text Reading guide, stop animations, big cursor 53 languages with auto-detection from html[lang] or browser settings Full ProcessWire multi-language support — maps $user->language to the correct locale automatically Configurable position, offset, button size, and accent color Skips admin pages and Chrome Lighthouse by default No build step — prebuilt JS bundle included. One caveat: the widget is injected via Page::render hook. If you serve pages through ProCache static HTML, the hook doesn't run on cached pages — exclude those pages from ProCache if you need the widget there. Overlay widgets supplement, but do not replace, accessible markup. Use Ally alongside good semantic HTML, not instead of it. Requirements: ProcessWire 3.0.200+, PHP 8.1+ MIT License.
    7 points
  7. Hi all, I've made the SeoNeo repo public as planned. SEO Neo is a modern SEO module for ProcessWire that started as a practical fix for real-world canonical, pagination, and hreflang bugs on multilingual sites, and grew into a full replacement path for MarkupSEO and Seo Maestro. GitHub: https://github.com/PeterKnightDigital/SeoNeo Current version: 1.1.3 · Requires: ProcessWire 3.0.200+, PHP 8.1+ What makes it different SeoNeo is a coordinator module, not a custom Fieldtype. It creates ordinary ProcessWire fields (Text, Textarea, URL, Checkbox, etc.), reads them via a configurable mapping, resolves fallbacks, and renders the <head> block. That means: Every SEO value is a real PW field — full multi-language support, selectors, import/export No custom database schema or Fieldtype complexity The SEO tab sits alongside your existing Content / Settings tabs Add seoneo_tab to a template and save — the rest of the SEO fieldset (seoneo_preview, title, description, canonical, robots, etc.) is inserted automatically. What it outputs Full <head> SEO block in one call: echo $page->seoneo; // or echo $page->seoneo->render(); Includes: <title> with configurable format, separator, site name, pagination placeholders Meta description, keywords, author Canonical URL (with configurable URL-segment and pagination policy) Robots meta (noindex/nofollow per page, auto-noindex for unpublished/hidden pages, site-wide defaults) Granular Google robots directives (max-snippet, max-image-preview, etc.) AI/LLM opt-out signals (noai, noimageai) — polite signals, not a substitute for blocking bots at HTTP/robots.txt level Open Graph (title, description, url, type, site name, locale, image + dimensions/secure_url/type) Twitter/X cards (auto summary vs summary_large_image) Hreflang alternates with configurable BCP47 map (default=en-GB, de=de-AT, etc.) Search-engine verification tags (Google, Bing, Yandex, Pinterest, Facebook, Baidu) JSON-LD @graph emitter (Consider BETA IE works, but API/defaults may still change; hooks recommended for production-critical schema) Partial renders and resolved values are available too — flat API ($page->seoneo->renderOg()) or SeoMaestro-style namespaces ($page->seoneo->og->render()). Everything is hookable. Editor / admin features Bundled InputfieldSeoNeoPreview (installs with the module): Live Google SERP preview that updates as you type Desktop / mobile toggle — mobile truncates earlier (separate char budgets) Multilingual language switcher on the preview card Surface-aware character counters (green/amber/red zones, optional hard maxlength) Per-page noindex/nofollow checkboxes Optional NEO badge on the Wire tab — handy when running alongside MarkupSEO's also-named "SEO" tab during migration Configuration highlights Module config covers site name (per-language) title format smart field mapping with ancestor walk (*summary) per-template defaults with placeholders OG image field paths (including dotted paths like banner.image) default OG image locale map Twitter handles auto-inject position canonical policy and more. ProCache: documented and tested on cache-miss and cache-hit paths. Migrating from MarkupSEO or Seo Maestro You can run both modules during migration . You keep legacy fields on the template, copy values into seoneo_* fields at your own pace, then switch templates from $page->seo to $page->seoneo (shape is largely preserved). Migration is being worked on. Watch for doubled <head> output if both modules auto-inject — disable auto-inject on whichever isn't authoritative yet. Quick steps: Install SeoNeo (Modules → Refresh → Install) Add seoneo_tab to templates Copy field values (seo_description → seoneo_description, etc.) Rewrite template API calls Uninstall legacy module when ready Full feature comparison and migration notes are in the README: https://github.com/PeterKnightDigital/SeoNeo#migrating-from-markupseo-or-seo-maestro Deliberately out of scope SeoNeo focuses on <head> SEO coordination, not Swiss-Army-knife extras. For these, dedicated modules are a currently a better fit: Sitemap → MarkupSitemap Redirects → Jumplinks2 or ProcessRedirects robots.txt editor → MarkupRobotsTxt or a template override Analytics/GTM → MarkupGoogleTagManager or similar (A PRO companion bundle with deeper editor tooling is planned separately) Install Copy SeoNeo to site/modules/ Modules → Refresh → Install SeoNeo Add seoneo_tab to any template that needs SEO Feedback very welcome. Especially from anyone migrating off MarkupSEO or Seo Maestro on multilingual or ProCache sites. Issues and PRs on GitHub are the best place for bugs and feature requests. Cheers, Peter
    6 points
  8. No Num-Pad you say? Then you aren't ready for this... Vortex Core, Cherry MX Brown switches...
    5 points
  9. "Claude please convert for me the processwire.com/talk IP.Board into a native ProcessWire CMS/CMF application. Make no mistakes." 😊
    5 points
  10. @AndZyk It's been requested by another person and I was just waiting for someone else to ask for it. I've added a setting (in tomorrow's version) that let's you choose where you want the response to appear: notification, in the field, or both. In my case, I need the "both" option because my PageEngineer fields are pretty far down on the page. If there's no notification, the person editing sometimes misses the response. And if it doesn't appear in the PageEditor field, then you don't see what you are replying to. But now you can choose what works best for your case. I agree, tomorrow's version will also repeat the prompt above the response. Maybe for a future version. Right now PageEngineer is a Fieldtype using an Inputfield that's part of the page editor form, and that gives you the flexibility of putting it where you want it. The current setup means you could always present it as its own tab in the page editor too. But I do like your idea as a potential option for a future version. I found that some of these requests can take quite awhile to complete and something more than a spinner was needed to communicate what was happening. I asked Codex to come up with a spinner that better represented the thinking process that takes place when you submit an engineer request, and I was pleasantly surprised by the result. Like anything else, if some people don't like it we could always make it optional. It's possible, but it depends on the Inputfield supporting it. Most core ones do, but at this point I prefer predictable reliability, aiming for stuff that will work everywhere. As the AgentTools module matures maybe more options like this can be available. Not all models support image files, though I think most of the big ones do. Likely we'll add this at least to the site engineer. Maybe for page engineer too, though you could do it now just by adding a file field to the page and telling page engineer to use it, whether in a prompt, or in the system prompt defined with the page engineer field.
    5 points
  11. New version (v 0.55.0) – This changes everything Barely a week on from the public beta release here's where Image Library went next. Short version: it grew a brain for duplicates, and that quietly changed what the module is for. How it continued. Barely a week after the first post, a different client site handed us the next problem – and this time it wasn't missing metadata, it was duplication, and a lot of it. ~10,000+ images on the site, of which only ~3,500 were actually unique – meaning roughly 6,500 exact-or-near-duplicate copies of the same pictures scattered across lead_image, body_images, galleries, repeaters, you name it. Years of "just re-upload it on this page too." So we went looking for a way to make duplicates stop mattering – without migrating anything. The full rationale is in the repo (docs/deduplication-design.md); the gist: Give every image a content identity – a byte hash (xxh128, md5 fallback), computed lazily and cached by path+size+mtime, with a cheap size/dimension pre-filter so we only hash real candidates. Group identical images into clusters = "this picture, in these K places." Then duplicates become manageable, not just visible: a Duplicates filter, a copy-count badge per image, an expandable cluster in the table (a cluster modal in the gallery), where-used per cluster, and the big one – edit-once-propagate: caption/tag a cluster once, written to all copies. Pure DB writes, fully reversible, zero filesystem risk. Optional, opt-in, reversible disk reclaim: byte-identical copies get hardlinked onto one inode, so 6,500 copies stop costing 6,500× the bytes. Lossless, runs in the background (on save + hourly), with Scan / Re-measure / Revert tools and a live "disk reclaimed" readout. (We tried perceptual near-dup detection too – dHash/pHash — and pulled it: it grouped unrelated photos that merely share a tonal layout. Detection-only, never destructive, and still not trustworthy enough to ship.) And then it clicked. What we'd built, almost by accident, was a DAM without the DAM. Strip a digital-asset manager down to what it actually gives you: one logical asset instead of scattered copies, metadata edited once as a single source of truth, a "where is this used," a central place to browse and pick – and storage that doesn't pay for the same file twice. Every one of those falls straight out of the content-identity + cluster technique. The difference: we get it over the images already sitting in native FieldtypeImage fields – the asset layer is synthesised from what's there, not a store you migrate into. No central library, no new page type, no migration, and crucially no template changes. That last part is the whole point: on some of these projects, re-wiring every template and every chunk of content onto a new media model would be a multi-week job and a regression-test nightmare. We just… didn't have to – and the editors get the DAM experience anyway. A word on MediaHub. If you are starting a fresh project and want a proper central media model from day one, MediaHub is – in our opinion – the best option out there. Huge thanks to @Peter Knight for letting us test it; we're genuinely impressed, it's a lovely piece of work. Different tool, different job: new site → MediaHub. Existing site full of scattered images → this. Image Library isn't trying to change the way PW image handling works; it's a layer over the files, pages, templates, methods and structures you already have. Which is exactly the rule we build by: must work with existing installations, as-is; plug & play – install, open, done; no rebuild, no migration, no new fields, no template surgery; no new workflow for editors; and – new – front-end-editor capable. BAM. 💥 That last one is the other big addition: two optional, off-by-default picker add-ons: Choose from library – a button on every image field to assign an existing library image without re-uploading (version-aware: inside a page version it lands in that version's folder, and it's deduped on the spot). Insert from library – a button in TinyMCE and CKEditor that drops a library image straight into rich text… and it works in the front-end inline editor (PageFrontEdit) too. Editor live on the page, click, pick, done. Plus, while we were in there: Collections – a hand-picked set of images no filter could reproduce (tick the ones you want, save them as a named tab). Recalled by a tiny ?coll=<id> link – the image list lives in your user profile, not the URL, so a 100-image collection is still a ~12-character link. Add/remove just by clicking a collection's tab while images are selected (the cursor tells you which way it goes), and collections are themselves filterable. Masonry gallery view – height-balanced (shortest-column) packing, natural aspect ratios, hover-revealed selection checkboxes – the same selection that drives bulk edits and collections. Status. v0.55.0 – public beta on top of the original. Module + docs (EN + DE concept, plus the dedup design doc) on GitHub / the Modules Directory. As before: feedback very welcome – especially duplication in the wild, odd Fieldtype combos in custom-field templates, ProFields, deep Repeater/RepeaterMatrix nesting, and anything the front-end picker trips over. Cheers, Mike
    5 points
  12. Have FUN this weekend Ryan! Isn't that feeling of discovery a wonderous thing.
    4 points
  13. It seems I had completely missed the part in the documentation regarding the Apache timeouts which finally led me in the right direction. However, the way to correct these did not match my MAMP Pro set-up. In MAMP Pro, Templates are used for files like httpd.conf. MAMP then merges these into a live, read-only httpd.conf file that Apache uses. In order to get this working, I had to edit the Apache template (File → Open Template → Apache → httpd.conf), and change the placeholder MAMP_FastCgiServer_MAMP into MAMP_FastCgiServer_MAMP -idle-timeout 300 This made sure that in the compiled httpd.conf the timeout was set correctly.
    4 points
  14. It's more like entering the mind of Zach Galifianakis I'd prefer the matrix.
    4 points
  15. Update: Withdrawals tab + Stripe custom fields (v 1.1.0) Hi all, a quick update on StripePlAdmin, the companion admin module for StripePaymentLinks. Two new things in this release: Withdrawals tab Surfaces the right-of-withdrawal (cancellation) requests that the main module stores per user (spl_withdrawals repeater). Same architecture as the other tabs — configurable columns, status/date/search filters, CSV export — plus inline-editable status and admin notes that save immediately via a small CSRF-protected AJAX endpoint. Consumer name/email link straight to the user account. The tab only shows up when the main module actually provides the feature. Custom Fields column Stripe checkout custom fields (the ones you define on a Payment Link) are now read out of the stored stripe_session meta and shown as Label: Value pairs — text, numeric and dropdown fields (dropdowns mapped back to their option label). It's a configurable column on the Purchases tab, flows into the CSV export, shows up in the purchase-details modal, and is included in the search. As always, feedback welcome, Cheers, Mike
    4 points
  16. Hi @Stefanowitsch, Yes, this is now possible. I added a global Title Format setting in Ichiban settings under: Settings → Rendering → Title Format You can use it like this: {meta_title} | {site_name} or, if you prefer a fixed suffix: {meta_title} | my-company.com Supported placeholders are: {meta_title} {site_name} {entity_name} {host} So your examples would render as: Home | my-company.com Our Services | my-company.com The title format is applied to the rendered <title> tag, and Ichiban’s Audit / Bulk Editor title length checks now include the formatted title length as well. After changing the format, rebuild the audit index so the stored title length checks are refreshed.
    3 points
  17. @eelkenet Thanks, I'm adding your suggestion to our README to accompany the other example(s).
    3 points
  18. Yes true. I purposely omitted sitemap generators in this phase. A significant volume of issues on the SEO threads are actually site map related so if I’m going to support it, I want it to work properly. And also I’m a big fan of Ryan’s pro sitemap module and simply prefer not to overlap existing modules that are actively developed. But it I’m not saying “never” 😉
    3 points
  19. Yeah I just installed this module too and when comparing your module with that from maximus (and the old trusty Seo Maestro) there is no perfect "all in one" solution. Each module does something better than the other and vice versa! I think it is still mandatory to try out what module fits for your projects and fills out the gaps in your personal workflow. For example: I like that @maximus module includes sitemap generation and redirect handling I like that your module offers per-template defaults and so on...
    3 points
  20. @zilli this is such a great progress review you gave us here. From "not knowing where to start/anything" to trying and exploring, finding solutions and new options, and even noticing that nothing is perfect on first try but iterating on it can you bring you quite far. 3 months ago I had to ton of ProcessWire skills in my projects to be able to get things done in a proper and clean way, but since Ryan started to explore and use AI more and brought us AgentTools, I skipped my skill files in projects that use AgentTools. It's working perfectly fine so far. Modules are sometimes edge-cases but at the end everything started to work as intended. I love to explore more tools, guidelines, agents, harnesses, models, and whatever the latest hype is. But at the end of the day I mostly only use OpenCode with Z.AI and the OpenCode Go plan to get things done. Sometimes for really huge tasks I try the Opus models through Windsurf/Devin ($10 legacy plan ftw!). What I learned with trends and hype cycles... wait a week or two. If people still talk about it, try it. Otherwise don't even care. Gastown? Beads? OpenClaw? Ralph Loop? Karpathy XYZ? SpecKit? [...] - meh. Not really. Looks nice, may work for some, but not for me.
    3 points
  21. Respectfully disagree here. I believe ProcessWire follows a convention where it's air-gapped / doesn't rely on outside servers like CDNs for libraries. It's a potential security issue and goes against things being fully unified. Also it doesn't pass the "can I work on a site without internet" test.
    3 points
  22. Hey, just a follow up here 🙂 Following the advice in this thread, I’ve been pretty happy with Codex CLI so far. I also tried Claude, but I ended up using Codex more. From what I’ve seen, both can do the job well. Most of the time, when something goes wrong, the problem is on my side 🫣 Usually weak planning, a vague prompt, or both. I’m still very much at the beginning, so there’s a lot to learn. But these are a few things that have been working for me: I treat AI like a very competent junior developer. Most of the time, I plan the task first and then ask him to execute. I might promote him to associate if things keep going well 🤣 I’m using the $20 Codex plan. You can actually get quite a lot done with it if you spend some time planning before asking it to code. I’ve just started using RTK to save tokens. I’m not sure yet whether it’s worth it, but I’m giving it a try. I’m comfortable with the CLI, so my setup is pretty simple: Arch Linux, Codex CLI, phmate, sqmate, and gog. I don't use MCP. Reading the model documentation and best practices has helped a lot too. It gives you a better understanding of how the model works. From there, it’s much easier to build your own workflow instead of just throwing prompts at it and hoping for the best. One of the most important things for me has been mindset, and I had to work on that quite a bit 😅 Before AI, building a new feature or even fixing bugs could take days, weeks, or months. Today, you can sometimes get something working in minutes. That’s incredibly powerful, but it can also be dangerous, especially for newer developers. The temptation to expect everything to be done in minutes or hours is huge, but reality is often more complicated. Maybe things will be different in the future, but for now, I’m perfectly happy spending a few days on something that would have taken me months before. That still feels like a big win. Finally, I wanted to ask @ryan and the others: are you using any additional guidelines, like the Karpathy Guidelines?
    3 points
  23. Now available in the Modules directory at https://processwire.com/modules/chat-ai/ and on gitHub at https://github.com/clipmagic/ChatAI What is it? ChatAI is a native ProcessWire AI chatbot module designed to answer questions about your site content, with a focus on: ProcessWire-first workflows Site-aware answers using RAG (Retrieval Augmented Generation) Respect for ProcessWire access control rule Admin visibility into usage and performance Keeping content ownership within ProcessWire Features include AI chat widget for frontend use RAG indexing of ProcessWire content Multi-role message support (system / assistant / user) Admin dashboard with metrics and observations Configurable prompts and behaviour Integration with AgentTools for model selection Role-aware retrieval (users only see content they can access) Frontend page restrictions Dictionary / weighting support for retrieval tuning Quick Start Ensure prereqs are installed, ie: PHP>=8.0, ProcessWire>=3.0.255, AgentTools>=0.1.1, TextformatterEntities, TextformatterNewlineBR Configure your chat LLM in AgentTools Configure your textembedder LLM in AgentTools Configure ChatAI module config with both the above Go to Setup->ChatAI and index your site pages (turn off Dry Run when you're ready). Add the CSS, Script and Widget to your template(s). After that, tweak to your heart's content, including adding languages, widget theming and prompts. Current status: Alpha Test thoroughly before using on live sites. Feedback welcome.
    3 points
  24. MediaHub 1.19.2 is on the way, and while I'm finalising some UI polish, I wanted to share the custom fields integration, which some of you have requested. And because both a MediaHub asset page and an input field are new to ProcessWire, we benefit from some new features I hadn't planned. You can add custom fields at two distinct levels... On an asset detail page (fig 1), useful for asset organisation and metadata On the MediaHub input field, giving editors access to those fields when placing assets (fig 2) Fields can exist independently at either level, but when the same field appears in both, they work together. So you might have custom fields on only the asset detail page or only on the input field. Explanations after screenshot... Fig 1 - Asset-level defaults Custom fields on the asset detail page act as the source of truth for that asset. Fig 2 - Editor field overrides You can choose whether to expose those fields to your editors on the MediaHub input field, or not. Your call. Fig 3 - Inherited value with reset option When the same field exists at both levels, the MediaHub field inherits the value set on the asset detail page. You can override it on a field-by-field basis, and if you change your mind, the rewind icon lets you reset it back to the asset value. It only appears once you've made a change. Fig 4 - Independent field ordering The order of fields on the MediaHub input field can be completely independent of the order on the asset detail page. I'll share a few more details when I wrap up and create a dedicated post.
    2 points
  25. Vox 1.6.2: Answers mode, profiles, forum layout, Textformatter and refreshed frontend I have released Vox 1.6.2. This release combines the recent work into one larger update after the first public release. The main goal was to make Vox easier to embed into real ProcessWire sites, not only as a single comments widget, but as a flexible community layer. The biggest additions are: Answers mode Vox can now be used for StackOverflow-style Q&A pages, with question lists, filters, question detail pages, answer forms, best answers, voting, Q&A stats and contributor sidebar. Useful tokens: [[vox:answers]] [[vox:answers-index]] [[vox:answers-ask]] [[vox:answers-sidebar]] Flexible profile sections User profile output is now split into separate sections, so you can build account/profile pages more freely: [[vox:profile]] [[vox:profile-header]] [[vox:profile-rank]] [[vox:profile-badges]] [[vox:profile-activity]] [[vox:profile-points]] [[vox:profile-leaderboard]] This makes it possible to show reputation, ranks, badges, recent activity, points and leaderboard blocks wherever they fit in your own template. TextformatterVox The new TextformatterVox module allows editors to place Vox widgets directly inside textarea or rich-text content, without editing template files. Examples: [[vox:forum]] [[vox:reviews]] [[vox:questions]] [[vox:discussions]] [[vox:all]] Inline editorial forms are also supported, so a compact participation form can be inserted between paragraphs: [[vox:form]] [[vox:discussion-form]] [[vox:question-form]] [[vox:review-form]] Custom copy can be passed directly in the token: [[vox:form type="question" title="Ask the editors" intro="We will answer useful questions here." button="Send question"]] Forum-style overview There is now a forum landing view with category cards, recommended threads, newest threads, search and a start-discussion form. [[vox:forum]] Demo installer The optional demo has been expanded into a complete showcase for: reviews questions and answers discussions Answers mode forum overview inline editorial forms flexible profile sections reputation, ranks, badges and leaderboard This should make it easier to test Vox quickly on a clean installation and see how the different pieces can be combined. Frontend refresh The public frontend has also been cleaned up: larger base typography 4px border radius no shadows no decorative gradients Remix Icon instead of FontAwesome on the public side improved spacing for profile sections, sidebars and mobile stat cards more realistic demo user names The current version is 1.6.2. Repository: https://github.com/mxmsmnv/Vox Release: https://github.com/mxmsmnv/Vox/releases/tag/v1.6.2
    2 points
  26. Is the eventual goal to perhaps have PW help us build our code without the need of an external LLM? And also take into account PW’s community modules? Imagine if it could also do front-end (HTML & CSS through the current frameworks UIKit, but including Tailwind too). That would honestly make PW a one-stop-shop.
    2 points
  27. Thanks Adrian, this is now possible via a new hook: Ichiban::resolvedSeoValue. It runs after Ichiban has resolved the page/template/global defaults and built-in fallbacks, so the rendered tags, previews, Audit, Dashboard stats, and Bulk Editor all see the adjusted value. That means you can use it for automatic descriptions on staff/blog pages and OG image fallbacks without those pages showing as incomplete in the dashboard. Example is in the README, but the shape is: wire()->addHookAfter('Ichiban::resolvedSeoValue', function(HookEvent $e) { $page = $e->arguments(0); $group = $e->arguments(1); $key = $e->arguments(2); $value = $e->return; if (in_array($page->template->name, ['person', 'blog-post'], true) && $group === 'meta' && $key === 'description') { $source = $value !== '' ? $value : wire('sanitizer')->textarea($page->get('summary|body')); $e->return = wire('sanitizer')->truncate($source, 155); } if ($group === 'og' && $key === 'image' && $value === '' && $page->template->name === 'blog-post' && $page->images->count()) { $e->return = $page->images->first()->httpUrl; } });
    2 points
  28. I love that rather than just consuming AI, you're trying to learn how it actually works. Speaking of the translation of code - I wonder if AI would make it easy to provide a PostgreSQL database layer for ProcessWire? Also speaking of C, I wonder about translating the entire ProcessWire codebase into Rust. (It would probably be expensive in terms of token use) ProcessWire is fast as PHP apps go, but Rust is blindingly fast, but harder to learn than PHP. It's also memory safe whereas C isn't. It might not work, as PHP is interpreted so it makes it easy to deploy individual files, whereas Rust compiles to a single binary executable, so it's probably like comparing apples with pumpkins, but all kinds of things ight be possible of you don't have to painstakingly write all the code by hand.
    2 points
  29. Update (v 0.58.0): tag-vocabulary management & a "Used in" column Hi, everyone! We´ve been enjoying developing the module a bit further this week. Since the last update the module has grown from 0.55 to 0.58. Two bigger additions: 🏷️ Tag-vocabulary management You can now curate a field's predefined tag vocabulary right inside the tag picker, with no trip to the field settings: Rename or delete a predefined tag library-wide, inline (no modal-on-modal). Table rows live-refresh immediately after a library-wide rename/delete. Newly entered tags can be promoted into the field's predefined list. This is only available when the image fields file tags setting is set to "User selects from list of predefined tags + can input their own". Alphabetical ordering, and a mobile-friendly single-column tag chooser with touch controls. 🔎 "Used in" – a content-based where-used column A new column answers the question you actually have at a glance: which pages embed this image? It scans rich-text content (not just the field relations), so it also catches images placed via "Insert from library": Cross-page "Insert from library" embeds are resolved to their true source image, and embeds inside (Matrix)Repeaters are attributed to the owning page. The count is a plain link that opens a dialog listing every page and the fields the image is embedded in. The "Used in" and "Variations" columns are now sortable, and integer columns are centre-aligned. Next up (in development): nested collections – group collections into subgroups with a drag-and-drop manager, cascading fly-out menus in the bar, and touch-friendly curation. Have a nice weekend! Cheers, Mike
    2 points
  30. Pretty good prompt engineering! Why have I never thought of this? :D
    2 points
  31. My workplace at the moment 😊
    2 points
  32. The old forum format has long since outlived its usefulness, as generations have changed and a new format is needed, even one different from Reddit. Therefore, to maintain engagement, we need to come up with new ways to keep our audience on the page. By the way, the archive contains mockups of the future service from March 2026. Vox-FB.zip
    2 points
  33. NativeAnalytics 1.0.29 is out This release polishes the recent contributions from @adrian and fixes a few edge cases: Hourly trend chart now live-updates the current hour (previously it could update the last slot of the day). "Find page" autocomplete now suggests only real pages with recorded data — bot rows and 404 probes are excluded. Page search no longer fails on environments without mbstring. Uninstalling only the dashboard module is now non-destructive — it won't remove the main module or drop your analytics tables. Full data removal still happens when you uninstall the main NativeAnalytics module. And anwser to @millipedia No step missing on your side — this was a bug. The tracking endpoint (/pwna-track/) was being recorded as the pageview path on some setups (subdir/proxy/trailing-slash), so every session showed it. Fixed in 1.0.29 release: the endpoint paths are now hard-excluded from being stored. Thanks R
    2 points
  34. It was nice until my wife arrived home and the monitor was promptly relocated off the kitchen table 😂 Re. numeric keypad. Is that because you are a proper developer? Using them mainly for coding?
    2 points
  35. It's now possible to run multiple scripts in different Console tabs at the same time. Probably not something you'll need often, but if you have a very long running one you can run other ones in other tabs at the same time without needing to wait.
    2 points
  36. SEO Neo feature focus: SERP Preview The SERP Preview has two useful tab groups. Live Google SERP preview with desktop/mobile toggle. Multilingual language switching is also possible. The tab group is auto-generated based on your installed languages. Apologies in advance if the DE/FI translation isn't spot on. CleanShot Google ChromeEdit Page Lakes & Trails • lakesandtrails.go2026-06-10 at 21.56.57.mp4
    2 points
  37. Here's a handy FAQ with the types of issues I needed to solve and are built into SEO Neo. FAQ (quick answers) 1. Can meta descriptions be filled automatically from existing page fields? Yes. Smart field mapping and per-template defaults pull from fields like summary or body when the SEO description is left blank. Auto-resolved text is truncated to a configurable length at a word boundary. 2. Can page titles get a consistent suffix (e.g. “About us | My Company”)? Yes. That is built into module config: site name, title format, and separator — no custom code needed for the usual pattern. 3. Can I override or extend resolution logic with hooks? Yes. Individual resolvers (title, description, OG image, etc.) are hookable, so sites with non-standard rules can plug in custom logic without forking the module. 4. Does the admin SERP preview reflect auto-resolved values? Mostly. On load it uses the same resolver chain as the frontend. If SEO fields are empty, the preview shows the computed title and description. If an editor types into the SEO fields, those values take precedence. 5. I am on MarkupSEO or Seo Maestro — can I migrate gradually? Yes. Both legacy fieldsets can stay on the same template while you copy values across. The SeoNeo tab can show a small NEO badge so it stays distinct when both tabs are labelled “SEO”. Migration helper planned. FAQ Longer versions 1. Automatic descriptions from content fields A common requirement is that staff and blog pages should not need a separate meta description when summary or body already exists. SeoNeo handles this in module config, not by asking editors to duplicate content: Smart field mapping defines fallbacks when seoneo_description is empty — for example, try summary, then body. Per-template defaults go further: a [blog-post] or [person] block can set description={summary|body} so only those templates use that chain. Truncation applies to auto-resolved values only. Values typed directly into the SEO description field are left as-is. The max length is set once in module config. There is also an ancestor walk prefix (*fieldname) if a section landing page should supply a default description for child pages. For edge cases — inheriting a homepage description site-wide, template-specific truncation rules, or pulling from a custom settings page — hooks on the description resolver are the extension point. 2. Title suffixes and branded <title> patterns Another frequent ask is a predictable title pattern: Page name | company.com That is a first-class feature via site name, title format, and title separator in module config. Per-template defaults can influence the source part of the title (e.g. {long_title|title} on blog posts) while the suffix still comes from the global format. Homepages that already store a fully branded title in the SEO field can use a hook on the title formatter to skip the automatic suffix on that one page. 3. Hooks for custom SEO logic Sites with existing custom SEO logic often need to tweak titles, descriptions, or OG images based on template, page ID, or external settings. SeoNeo splits resolution into hookable steps — reading and resolving individual values, formatting the final title, resolving OG image, hreflang, and so on — rather than one monolithic hook. Render methods are hookable too if you need to append tags rather than change resolved values. 4. What the SERP preview in the admin actually shows The bundled SERP preview calls the same PHP resolvers the frontend uses on initial render. While editing, typed SEO values take precedence; empty SEO fields fall back to server-resolved values from page load. One limitation: the live preview watches the SEO input fields, not every source field in the fallback chain. Editing summary will not update the preview until save/reload if the description comes from smart-map. A richer fallback-chain visualisation in the editor is on the PRO roadmap. 5. Multilingual sites Multilingual support is a common question for any SEO module, especially when hreflang and locale tags need to stay in sync with ProcessWire’s language tabs. SeoNeo is built around native PW language-aware fields, not a separate storage layer. Each seoneo_* field behaves like any other translatable field — editors fill in SEO values per language tab, and the resolver chain returns the value for the currently active language on the frontend (or whichever language you switch $user->language to in PHP). Configuration for multilingual output: Per-language site name — override the global site name per language (e.g. de=Mein Beispiel). Used in title formatting, template defaults, and og:site_name. Locale map — map PW language names to BCP47 codes (default=en-GB, de=de-AT, etc.). Powers og:locale, og:locale:alternate, and hreflang codes. Hreflang alternates — emitted per language with correct URLs, including x-default pointing at the default-language URL. Segment and pagination handling matches the canonical URL policies. In the page editor: The SERP preview includes a language switcher (on multilingual sites) so editors can preview each language’s title and description without leaving the current PW language tab. Resolved values in the preview use the same per-language fallback chain as the live site, including the localised URL in the breadcrumb. Desktop/mobile toggle and character counters apply per surface regardless of language. Smart-map and template defaults respect language context too — a German summary field resolves when the German language is active, not a mixed default. For sites with unusual language setups (custom domain-per-language, non-standard hreflang codes, or locale rules that differ from PW’s language names), the hreflang and locale resolvers are hookable. 6. Migrating from MarkupSEO or Seo Maestro Both legacy modules can stay installed while you move page by page: Install SeoNeo (InputfieldSeoNeoPreview installs with it). Add seoneo_tab to templates — remaining SEO fields insert automatically on save. Copy legacy values at your own pace. Switch templates from $page->seo to $page->seoneo when ready. Uninstall the legacy module when frontend output is fully on SeoNeo. Watch for doubled <head> output if both modules auto-inject meta tags.
    2 points
  38. @cb2004 There was a lot of FA data that didn't need to be there. I've deleted it, so we should be down to ~1.6 MB now. @jploch The problem I ran into is that it's just too many icons to display at once, it made the whole window lag. We could always add a link to a page with all the icons on this site, or at the font awesome site?
    2 points
  39. Hi everyone, I've been building this for a while - a full genealogy system inside ProcessWire. Family trees, people, relationships, sources, documents, DNA kits, research workflow, and GEDCOM export. All inside the PW admin. GitHub: https://github.com/mxmsmnv/Arbor Status: Beta. Usable on a test copy. Always backup before installing. Screenshots: Why ProcessWire for genealogy? Genealogy data is complex, relational, and research-driven - not a blog. ProcessWire's flexible data model and custom DB table support make it a natural fit. Everything in Arbor lives in arbor_ prefixed tables, completely separate from the PW page tree. What it does Multiple trees - owner/public settings per tree Person profiles - names, events, notes, sources, photos, relationships Family/union management - partners, parents, children, relationship types Interactive tree viewer - main person panel, selected-person panel, agenda, legend Places & repositories - archives, sources, citations, documents, document leads Research workflow - questions, tasks, search log, proof conclusions, next actions DNA - kits, matches, segments GEDCOM 5.5.1 and GEDCOM 7 export GEDCOM import foundation (in progress) AI helper via AiWire-compatible providers - research suggestions, name analysis REST API via ArborApi submodule Three submodules: Arbor - schema, models, configuration, permissions, shared services ProcessArbor - admin UI under Setup → Arbor ArborApi - optional REST endpoints Requirements: ProcessWire 3.0.200+, PHP 8.1+, MySQL/MariaDB with InnoDB MIT License.
    2 points
  40. 😆 I blame the docs. But seriously glad it’s working now.
    1 point
  41. That's the reason why it didn't work on first try on my instances. 🙈
    1 point
  42. SeoNeo 1.1.4 is live. Pushed to: PeterKnightDigital/SeoNeo (GitHub) Release: https://github.com/PeterKnightDigital/SeoNeo SeoNeo 1.1.4 — what's new Resilience. If anything goes wrong while building the SEO meta block, the page now still renders cleanly — visitors see normal content and styles, only the SEO tags are absent on that one page. Previously, certain failures could blank out the entire <head> and break the page layout. New seoneo log. When something does fail, SeoNeo writes a one-liner to site/assets/logs/seoneo.txt (also visible at Setup → Logs → seoneo in the admin) telling you which page tripped and what the error was. The log file is created on demand, so clean installs that never hit a problem won't see it appear. Better setup feedback. The auto-inject checkbox in module config now warns you if no template has seoneo_tab yet — the most common reason new users see no SEO output on the front-end. Docs. The README's Installation section now spells out that you only need to add seoneo_tab to a template (the rest of the SEO fields are auto-inserted on save — a 1.1.0 feature that was easy to miss), and the JSON-LD section has a worked example for adding custom Schema.org types like Recipe or Event via a hook. Backwards-compatible — drop in over 1.1.3, hit Modules → Refresh, you're done.
    1 point
  43. Hi @wbmnfktr Thanks so much for the feedback, and I'm glad you like it 🙂 I can only take credit for the planning and direction, but I put a lot of thought into it, and I'm glad to hear it's working (kinda') ok. On the specifics... That's interesting because I had a lot of issues getting it to work on the first pass. It turned out to be a non-related PHP error in my <HEAD> include was blocking the auto-inject. Once I cleared that, it worked. But I will now triple-check. Maybe hold off until I can come back to you tomorrow? I might have mistakenly assumed the issue was closed by "fixing" an unrelated event. I'm not sure I'm understanding correctly here, so apologies for starting from scratch. Yes, the module adds several fields between the SEO open and close tabs. I was thinking that manually adding these to every template would be a chore for people; the fields should be auto-added once you manually add the SEO open and close tab, and then save. LMK if I misunderstood there. Would you find it useful to pick the templates from the SeoNeo module config page (bulk add in one save), or do you prefer the standard PW workflow of opening each template individually? I'm quoting the following from the docs and AI (spot the em-dashes) 🙂 What ships today (built-in): Organization, WebSite, WebPage, Article, Person, BreadcrumbList — auto-generated as a linked @graph How to add custom types (Recipe, Event, Product, RealEstate, etc.) right now: Hook ___getJsonLd() in your site's ready.php or a custom module: $wire->addHookAfter('SeoNeo::getJsonLd', function(HookEvent $e) { $page = $e->arguments(0); if($page->template->name !== 'recipe') return; $data = $e->return; $data['@graph'][] = [ '@type' => 'Recipe', 'name' => $page->title, 'description' => $page->summary, 'prepTime' => 'PT' . $page->prep_time . 'M', 'cookTime' => 'PT' . $page->cook_time . 'M', 'image' => $page->image ? $page->image->httpUrl : '', ]; $e->return = $data; }); What's planned (future, not committed to a version): A higher-level API — $page->seoneo->schema('Recipe', [...]) — with per-type hookable helpers. It's in the roadmap (section J in the backlog) but deferred because the API shape isn't stable enough to ship without risking breaking changes. The hook approach above is the recommended production path for now. Also I believe my own docs are fuller in detail: https://www.peterknight.digital/docs/seoneo/1.x/structured-data-json-ld/ Anywho LMK if any of those are useful answers and feel free to DM me too. Cheers P
    1 point
  44. 😄 If I could, I would turn it off for ever, but haven`t found a way. So I use a very low gliw and 80% is white light. I found this in a local media store for under 50% of the regular price, maybe between 5 - 7 years ago.
    1 point
  45. @AndZyk Your Mac desktop and your real desktop are very clean 🥇 Re. the view, it's just a park at the back of the home office. Not quite the countryside, but nice to have some greenery.
    1 point
  46. All looking well used. I've been tempted to try the Razer stuff. It looks very nice, but my Razer machine, which I use for gaming, already has enough glowing lights.
    1 point
  47. Since back in 1996 I'm a big fan and user of the smallest Cherry Keyboards, with and without NumPads. But mainly the types without NumPads, CHERRY G84-4100: But on my primary Desktop working place I use a Razer Huntsman Elite RZ03-0187 :
    1 point
  48. Awesome, thank you. Yes I tried out putting my page engineer field at the end of the editor first and for this case the notification is useful. But then I switched my field to a tab and for this case the notification is a little bit redundant. 😀 Nice 😀 Thank you, right now I prefer the field visibility as tab for the page engineer field. But maybe a new field visibility setting, f.e. off-canvas or modal could help to not scroll or switch to much between the fields. That makes totally sense and you need this for long requests. Actually the animation is growing on me, I was just a little bit overwhelmed by the flying words. 😅 That is understandable. Reliability is more important than convenience. I guess it will be difficult to implement a Ajax driven page engineer field that is reliable. Ah thank you, I have not tried this out yet. I only gave page engineer an external image and this worked well. Nice to hear it already works with different file fields.
    1 point
  49. I think I just moved to this one because it has touch ID and USB charging. I'm sure the numeric keyboards now have all those, but I couldn't go back. My mouse position Vs edge of keyboard has been re-established.
    1 point
  50. Please do 🙂. I can’t guarantee everything is flawless at this early stage but I can guarantee speedy fixes. LMK where you can see areas for improvement. P
    1 point
×
×
  • Create New...