maximus Posted May 16 Posted May 16 Hi everyone, I've been timing my bigger releases with the lunar cycle β new moon for launches, full moon for milestones. Collections shipped on the full moon two weeks ago. Tonight the moon is invisible. The module isn't. π GitHub: https://github.com/mxmsmnv/Ichiban Quote Status: 0.1.2-alpha. The module is usable on real sites. Start on staging with a database backup. Why Ichiban? Ichiban (δΈηͺ) is Japanese for "number one" β fitting for an SEO module whose entire purpose is to help your pages rank first. Why another SEO module? There hasn't been a comprehensive SEO module for ProcessWire for a while. Yoast and RankMath solve this for WordPress β both charge $59β$99/year for the full feature set. Ichiban is MIT, free, and built specifically for ProcessWire. What it does Page field β five-tab editor per page: Meta (Google-style SERP preview), Social (OG + Twitter/X cards), Schema, Sitemap, Advanced. Render with echo $page->seo; or enable auto-injection. Source expressions β resolve field values dynamically: title|truncate:70 field:summary|truncate:160 {splash} Admin sections: Dashboard β battery-style site score, health stats, GSC highlights, indexing issues Bulk Editor β edit all meta titles/descriptions in one table, grouped by Critical/Warnings/Healthy Audit β site-wide SEO rule checks, priority cards, CSV export, hookable rule system Redirects β 301/302/307/410/451, regex rules, hit counts, CSV import/export, auto-redirects on slug change Insights β Google Search Console OAuth, metrics, top pages/queries, countries, devices, URL Inspection scan Backlinks β Moz API snapshots, cached history, links/domains/anchors views Schemas β database-backed Schema.org builder, map properties to PW fields Revisions β tracked SEO field changes with restore Cleanup β remove low-value head tags, block spam crawl queries Migration β SeoMaestro β Ichiban converter (15 fields mapped) Reports β scheduled SEO email reports, DOCX export AI β OpenRouter-backed SEO prompt workspace with Context module integration XML Sitemap β built-in generator with hreflang, image sitemap, LazyCron auto-regeneration IndexNow β one-click key generation and verification robots.txt / llms.txt β dynamic serving (companion to RobotsTxt module) Known alpha limits GSC requires a Google OAuth client setup β not plug-and-play Moz free API quota is very small β refresh intentionally Schema Builder is alpha β test before production Auto head injection can conflict with existing theme SEO tags β use manual echo $page->seo; first SeoMaestro migration is experimental β always backup before running Disable debug mode before production Requirements: ProcessWire 3.0.200+, PHP 8.1+ MIT License β free, no Pro tier, no upsell. 16
Peter Knight Posted May 17 Posted May 17 Congrats Maximus. Looks like a really impressive set of SEO tools. π
maximus Posted May 18 Author Posted May 18 Thanks for the kind words, Peter! This actually gave me the push to keep going - after several iterations I had almost given up on building something substantial, because every popular CMS already has mature SEO tooling. I went through Yoast, RankMath, SEOmatic, and a bunch of others, took notes on what worked and what didn't, and tried to bring the best of it to ProcessWire.Β Still a long way to go, but the foundation is there. Looking forward to seeing SEO NEO when it's ready too - good SEO tooling for ProcessWire benefits everyone! 3 1
maximus Posted May 18 Author Posted May 18 Also checked BuiltWith β there are 22,000+ live ProcessWire sites out there. Would love to see Ichiban running on as many of them as possible someday. π 4
Peter Knight Posted May 18 Posted May 18 54 minutes ago, maximus said: Also checked BuiltWith β there are 22,000+ live ProcessWire sites out there. Would love to see Ichiban running on as many of them as possible someday. π True - that would be amazing. But also, think about 22,000 support tickets?Β π«£
Krlos Posted May 21 Posted May 21 Β Hi @maximus, I have been testing your module, and so far itβs really impressive! The only problem Iβve found is how to map an image field that lives inside a combo field to an og:image. Iβve triedΒ combo:image,Β combo.image, andΒ {combo.image}, but none of those have worked. Β I also want to take the chance to thank you for your recent modules, youβve been on an impressive productivity streak and personally Iβm using several of your modules in production Β 2
maximus Posted May 22 Author Posted May 22 Hi @Krlos, Thank you so much for testing Ichiban and for the kind words. I really appreciate it. You found a real gap there. Ichiban was resolving top-level image fields, but it was not yet following ProFields-style dot notation for nested fields inside Combo/Table/Repeater Matrix fields. Iβve fixed this in v0.1.1-alpha. For a Combo image field, you should now be able to use: field:combo.image or: {combo.image} I also aligned it with the same dot-notation style used in Collections, so nested ProFields paths are supported too, for example: field:blocks.hero.image field:media.property_photos.photos field:prices.*.image For Open Graph images, the resolved image will still go through Ichibanβs normal OG image handling and create the 1200x630 variation when possible. Thanks again for catching this, and also for the very kind note about the recent modules. It means a lot, especially knowing youβre using some of them in production. 2
Krlos Posted May 22 Posted May 22 Hi @maximus, Thank you for taking my request into consideration, I have updated Ichiban and I can confirm that in my case {combo.field} and combo.field is working as expected and og:image is showing as intended, the only detail is when Iβm using combo fields as source for OG image URL, Ichiban doesnβt show the resolved path and social preview doesnβt show up, but itβs still rendering the correct URL in the source code. In pages that have a unique image field {image} shows the correct resolved path and the social preview image
maximus Posted Sunday at 07:39 PM Author Posted Sunday at 07:39 PM Hi Krlos, Thanks for confirming, and good catch on the admin preview. The frontend output was already resolving the Combo image correctly, but the page editor preview JavaScript was still only recognizing simple tokens like {image} and field:image. It did not recognize dotted expressions such as {combo.image} or combo.image when deciding whether to use the resolved URL for the preview. Iβve fixed this in v0.1.2-alpha. After updating, the resolved image path and the social preview should now appear in the editor for Combo image sources as well. 1
adrian Posted yesterday at 12:39 AM Posted yesterday at 12:39 AM Hi @maximusΒ - I have a fairly detailed hook set up for SEOMaestro. It tweaks the homepage title, but most importantly it sets an automatic description for staff bio pages amd blog posts from existing text fields. It also pulls the first image from the blog post for the ogimage. If I switch to Ichiban I think I will need to do something similar so that staff don't need to manually enter separate descriptions for these pages. Is there an available hook to replicate this? And, if so, could the dashboard process this hook so it knows that these pages actually do have completed descriptions.Β $this->wire()->addHookAfter('SeoMaestro::renderSeoDataValue', function (HookEvent $event) { $group = $event->arguments(0); $name = $event->arguments(1); $value = $event->arguments(2); $p = $event->wire('page'); if($p->template->name == 'admin' && $event->wire('process') == 'ProcessPageEdit' && $event->wire('input')->get('id')) { $p = $event->wire('pages')->get((int) $event->wire('input')->get('id')); } $service_name = $event->wire('siteSettings')->serviceName ?? 'My Site Title'; if($group === 'meta' && $name === 'title') { if($p->id === 1) { // remove automatically appended [[service_name]] from homepage because we add it to the front in the SEO tab of the homepage $event->return = str_replace(' | [[service_name]]', '', $value); } else { $event->return = str_replace('[[service_name]]', $service_name, $value); } } // people (staff & experts), blog posts β keep the meta description to whole words under 155 chars, // using the editor's explicit description when set, otherwise falling back to summary|body. if(($p->template->name === 'person' || $p->template->name === 'blog-post') && $group === 'meta' && $name === 'description') { $source = $value !== '' ? $value : $this->wire('sanitizer')->textarea($p->get('summary|body')); $event->return = $this->wire('sanitizer')->truncate($source, 155); } elseif($p->id !== 1 && $group === 'meta' && $name === 'description' && $value == '') { $event->return = $this->wire('pages')->get(1)->seo_fields->meta_description; } if($p->image && $value !== "" && $group === 'opengraph' && $name === 'image') { $event->return = $p->image->httpUrl; } elseif($p->template == 'blog-post' && $p->images->count() > 0 && $value !== "" && $group === 'opengraph' && $name === 'image') { $event->return = $p->images->first->httpUrl; } }); Β 2
maximus Posted 23 hours ago Author Posted 23 hours ago I'll take a look in the near future, I think it's possible to automate this somehow. 1
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now