Jump to content

Peter Knight

Members
  • Posts

    1,549
  • Joined

  • Last visited

  • Days Won

    18

Everything posted by Peter Knight

  1. Is that an early version? I imagine they have either replaceable batteries now., I really like the mini Pebble by Logitech and it has replaceable AAA batteries. Probably too small for your usage with no num pad. https://www.logitech.com/en-eu/shop/p/pebble-keys-2.920-011851 I appreciate the multi device connection support. Handy when I need to switch from work to gaming machines 🙂
  2. Happy Friday, everyone. I'm starting this Friday with something I meant to do last Friday! The latest version of MediaHub (1.19.25) is now available, and thanks to our testers, we have improvements across the UI, module performance and some new features too. Existing Media hubbers: Download here New to hubbing: Read here Full changelog: Read here What's new and improved in 1.19.25... Upload screen refresh Uploading is one of the first things a new user will do, so the first impression should be positive, distraction-free and simple. But behind a screen that seemingly has 'just one job', people asked if they could organise their uploads from here. While you can do this later within the Library, being able to associate your uploads with Collections and Labels at this point across multiple images will save you a lot of time and asset admin. An "Organise uploads" bar above the dropzone lets you assign Collections and Labels before the batch starts. If one doesn't exist yet, you can create it from here. A scrollable card queue replaces the old list. Each file shows a thumbnail or file-type icon, inline status, and a per-file progress bar. Oversized or unsupported files stage with a clear warning and are excluded from the upload. Inline filename editing on each card is possible before you upload. We'll introduce a table view shortly if you're uploading at scale and want to sort and filter at this point. Once your upload starts, you can see the progress of each file and a master progress bar. Custom fields on assets Adding custom fields to a MediaHub input field works the same way as the existing workflow. Should you wish, you can also assign custom fields to a master asset depending on your use case. You can assign custom fields to your master asset or just the MediaHub field on your page. They work indenpendently when you want, but also have a relationship with and inherit-with-override model. Inherit-with-override works the same way Title and Alt already do: The asset detail page (left) holds the canonical (library-level) value. Every reference inherits it by default. On a page, custom fields appear below Title, Filename, Description, and Tags. An editor can override the value for that one reference only. The override saves when the page saves, no separate save button A small reset control next to any overridden field lets you revert to the library value in one click On a MediaHub input field, a developer can choose to display custom fields in a different order than on the asset detail page Two tiers Some metadata belongs to the asset everywhere (a photographer credit, a licence URL). Other metadata belongs to how the asset is used in a specific field. Both are supported: Asset-level fields go on pkd-mediahub-asset. Master value plus per-reference override and reset Field-specific fields go on a template named mediahub-field-{fieldName} (mirrors ProcessWire's native pattern). These appear only in that field's drawer and are per-reference only, no library master I hadn't planned on allowing custom fields on the asset detail page, but it was straightforward once I added some of the standard text-based fields. It works in the same way you'd add a field to any template and doesn't even require the extra custom field to input field step (creating an extra fileless template). Anything on that asset template that isn’t one of MediaHub’s built-in fields: title, image, alt, labels, collections, and so on - is treated as yours. Should you wish to uninstall MediaHub, we have safeguards in place to keep your custom fields on your ProcessWire install, which is what I think you might want. The only real downside I have found so far is that custom fields on the master asset template show on every asset detail page, so a name like Photographer fits a photo but feels odd on a PDF or spreadsheet. What has worked for me is broader labels from the start (Source, Description). We plan to make this more asset-aware in a future release, but for now, name fields as if every asset type will see them, because they will. But, this is just a side note and doesn't affect input fields, which was the core feature and of the 1.19.25 release. Library thumbnails 1.19.25 takes a leaner approach to thumbnail generation and makes more effort to reuse thumbnails across the UI vs generating the full scope on upload and import. One preview at upload. Each image gets a single small proportional preview. That's 75% fewer auto-generated files at upload time. One library thumb per asset. Grid, Masonry, and List share one canonical thumbnail. CSS handles grid cropping. Built on first browse. The full library size is generated the first time you scroll an asset into view, not during upload. The upload preview is shown immediately as a placeholder so nothing looks broken while it's being prepared Import Existing Images and the asset picker use the same on-demand model. Bulk imports of existing assets from existing fields should feel noticeably lighter on disk and CPU. Library bulk actions and toolbar The search and filter area of the Library was cleaned up for consistency and clarity in advance of some architectural changes (more below) Selecting assets now swaps the breadcrumb row for a compact bulk action bar with actions for Collections, Labels, and Delete. There's a useful workflow change here: you can select assets first and then create and assign a collection in one step, rather than having to create the collection first. Library and picker consistency MediaHub looks like it has one central Library, but under the hood there are actually three slightly different versions of it: the main Library, the InputfieldMediaHub picker, and the TinyMCE picker. Over time I found that improvements made to the main Library were easy to overlook on the other two, since they didn't share any underlying code. To reduce that drift, 1.19.25 moves the toolbar, sidebar, filters, and tiles onto shared partials so all three surfaces stay aligned going forward. This isn't just a tidy-up under the hood either. It lightens the module overall, and it's what made it possible to introduce the Collections and Labels sidebar into Library screens that didn't have it before. Import page images The ability to import images from your existing fields was an early feature and has been in MediaHub since v1 1.19.25 gives it an overhaul. BTW the import Page Images button is optionally enabled in the field config so you can enable it on a field-by-field basis. Repeater and RepeaterMatrix support The scan now walks Repeater and RepeaterMatrix fields up to three levels deep. Results are grouped under breadcrumb headings so you can see exactly where each image came from. How matching works Each image on the page is scored against the whole Hub using four signals: filename stem file size dimensions and a perceptual hash (a 64-bit visual fingerprint that can match re-encoded or renamed copies). Each result gets a confidence badge: New - not currently in the Hub Exact match - identical file already in the Hub Likely match - looks like an asset already in the Hub Possible match - filename matches a Hub asset but the file content appears different Already added - already used in this field When a match is confirmed, MediaHub adds a reference to the existing asset rather than copying the file again. Hardening for large pagesThere's also longer scan and import time limits, JSON error handling, a 200-selection cap per request, and client-side checks so a timeout doesn't surface as a cryptic error. Import Page Images was one of MediaHub's earliest features, and I think there's more we can do here. The import modal in particular could use a bit more cleanup, so that's on the list. That's pretty much it. Thanks for reading and scrolling! MediaHub is currently available for single sites, developers of multiple sites and agencies. If you'd like to try it first, DM me. Have a great weekend, Peter
  3. Nice illustration too 🙂 Did you need this module developed for your forums?
  4. One of my testers won't be available to test as soon as they thought. If anyone else would like to test MediaHub, please shout (DM). The PW community is pretty diverse. I've had testers from a technical, UI/UX and media background. That variety of interests has really helped improve MH from multiple angles.
  5. 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.
  6. the split space bar is interesting. You have it configured for different actions. Let me guess. Space and outer space? But seriously…what do you you use the extra one for?
  7. 😆 I blame the docs. But seriously glad it’s working now.
  8. 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.
  9. 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
  10. @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.
  11. Nice. Home office or office office ?
  12. 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.
  13. There's only 29.2k Total Topics 247.1k Total Posts 9,598 Total Members Who wants to volunteer their AI tokens? 🙂
  14. @maximus I was just thinking this week that ProcessWire forums should be built in ProcessWire. Both as a showcase of how flexible PW is and to demonstrate its ability as more than a regular CMS. Amazing stuff.
  15. Just Googled it Max. What do you like about it?
  16. 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.
  17. 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?
  18. 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?
  19. 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
  20. 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
  21. 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” 😉
  22. Thanks 🙏 Plenty of choice these days so feel free to find something that suits you. Also @maximus has a very comprehensive SEO module too.
  23. 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.
  24. 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
  25. Looking good, Mike. It's great to see image options. And thanks for the MediaHub mention too 🙂
×
×
  • Create New...