mageos / module-blog
Blog module for Mage-OS / Magento 2 — posts, categories, tags, authors, SEO, GraphQL.
MageOS Blog
A blog module for Mage-OS and Magento 2. Posts, categories, tags, authors, scheduled publishing, RSS, sitemap, 6 storefront widgets, SEO (meta tags, Open Graph, Twitter Cards, JSON-LD), and a full GraphQL API. Works with Luma and Hyvä themes.
Install
composer require mage-os/module-blog
bin/magento module:enable MageOS_Blog
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento cache:clean
For Hyvä storefronts, a template companion (mage-os/module-blog-hyva) is planned for v1.2; v1.0 renders Luma templates on Hyvä via graceful fallback.
Enable
The module ships disabled. Turn it on under Stores → Configuration → MageOS → Blog → General → Enabled (or set mageos_blog/general/enabled = 1).
Key admin settings
All settings live under Stores → Configuration → Blog → Blog.
| Path | Purpose |
|---|---|
mageos_blog/general/enabled |
Master kill switch. Router and cron both short-circuit when off. |
mageos_blog/post/posts_per_page |
Listing pagination size. |
mageos_blog/post/default_robots |
Fallback meta robots value for posts that don't override it. |
mageos_blog/seo/og_default_type |
Default og:type. Usually article. |
mageos_blog/seo/json_ld_enabled |
Emit Article JSON-LD on post detail pages. |
mageos_blog/seo/twitter_site |
Twitter handle used for twitter:site. |
mageos_blog/sidebar/* |
Per-widget toggles for search, recent posts, category list, tag cloud, archive. |
mageos_blog/sitemap/{post,category,tag}/* |
Per-entity sitemap enable + changefreq + priority. |
mageos_blog/rss/enabled, mageos_blog/rss/limit |
RSS feed at /blog/rss. |
Compatibility
| PHP 8.2 | PHP 8.3 | PHP 8.4 | |
|---|---|---|---|
| Magento 2.4.6 | yes | yes | — |
| Magento 2.4.7 | yes | yes | — |
| Magento 2.4.8 | — | yes | yes |
| Magento 2.4.9 | — | yes | yes |
| Hyvä 1.3+ | yes | yes | yes |
| Luma | yes | yes | yes |
Tested against Magento 2.4.6-p15, 2.4.7-p10, 2.4.8-p5, and 2.4.9, plus the equivalent Mage-OS releases.
Requires magento/module-url-rewrite-graph-ql for the GraphQL URL resolver integration.
Storefront URLs
By default:
- Post:
/blog/{url-key} - Category:
/blog/category/{url-key} - Tag:
/blog/tag/{url-key} - Author:
/blog/author/{slug} - RSS:
/blog/rss - Search:
/blog/search?q=...
URL rewrites are populated on save by the repository plugins in Plugin/Repository/. The router (Controller/Router.php) delegates path parsing to MageOS\Blog\Model\UrlResolver.
GraphQL
Queries: blogPost, blogPosts, blogCategory, blogCategories, blogTag, blogTags, blogAuthor, blogAuthors. Each list query accepts filter, sort, pageSize, currentPage and returns items + page_info + total_count.
Mutations: createBlogPost, updateBlogPost, deleteBlogPost (and the equivalent for category / tag / author). Every mutation requires an admin token and passes through Magento\Framework\AuthorizationInterface against the entity's ACL resource (MageOS_Blog::post, MageOS_Blog::category, MageOS_Blog::tag, MageOS_Blog::author).
urlResolver(url: "/blog/my-post") returns { type: BLOG_POST, id, relative_url }. Supported types: BLOG_POST, BLOG_CATEGORY, BLOG_TAG, BLOG_AUTHOR.
Full schema: etc/schema.graphqls.
Upgrade notes
v1.0.0 is a greenfield rewrite. There is no migration path from any v0.x fork, including the original Magefan-derived codebase that lived under this package name before the rewrite. To move off a v0 install, export content from the old admin, fresh-install v1, and re-import via the admin or GraphQL.
Development
composer install
vendor/bin/phpunit --testsuite unit
vendor/bin/phpstan analyse --memory-limit=1G
vendor/bin/phpcs --standard=phpcs.xml.dist
vendor/bin/php-cs-fixer fix --dry-run --diff --allow-risky=yes
XDEBUG_MODE=coverage vendor/bin/infection --threads=4
Integration tests live under Test/Integration/ and run in CI against a live Magento install via graycoreio/github-actions-magento2.
Contributing
Issues and PRs welcome at https://github.com/mage-os-lab/module-blog. Full workflow, quality bar, and review expectations in CONTRIBUTING.md. Participation governed by the Contributor Covenant 2.1.
Security
Security vulnerabilities: please don't open a public issue. See SECURITY.md for the private advisory flow.
License
OSL-3.0. See LICENSE.
Attribution
Design inspired by Magefan Blog (OSL-3.0). v1 is an independent implementation with no shared code.
Changelog
All notable changes to this project are documented here.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
1.1.0 - 2026-06-25
Admin usability and storefront-design release. No schema or API breaking changes; safe upgrade from 1.0.0.
Added
- Admin "no raw IDs" pickers. The post form now uses real pickers instead of hand-typed entity IDs: author, category, tag, related-post, and related-product. The category form gains a hierarchical parent-category picker. Backed by new option sources under
Ui/Component/Form/{Authors,Categories,Tags,ParentCategory,RelatedPosts,RelatedProducts}/Options.php. Related-post and related-product assignments now actually persist on save (Model\Post\Link\RelatedPostLinkManager,RelatedProductLinkManager,Model\Post\PostsByAssignmentProvider). - Human-readable admin listings. Linked author-name column on the post grid and a parent-category column on the category grid (
Ui/Component/Listing/Column/{AuthorName,ParentCategoryName}.php). - Storefront redesign. New
view/frontend/web/css/blog.csswith a typography scale, layout primitives, and card components. Sharedpost/card.phtml(replacingpost/item.phtml), hero-on-top post cards with pagination, a redesigned post-detail page (hero, tag chips, related posts), and context headers on category / tag / author / search pages. - API surface. Additional data fields and interface docblocks on
Api\Data\{Author,Category,Post,Tag}Interface(cleans upsetup:di:compile). - Project docs & CI.
CONTRIBUTING.md,CODE_OF_CONDUCT.md,SECURITY.md, GitHub issue/PR templates, and a GitHub Actions CI workflow.
Changed
- Naming. Module name references aligned to the
mage-osnaming convention (PR #12). - Layout. Blog storefront switched to a 1-column layout; Luma sidebar bleed removed. Body / heading / post-content type scale bumped;
.mageos-blog-containerleft-aligned. - Compatibility. Widened the
magento/frameworkconstraint to support Magento 2.4.6-p15.
Fixed
- Double
<h1>on category / tag / author / search pages (removed redundantpage.main.title). - Author avatar upload (dropped an invalid nested
xsi:type="string"param). - Admin form rendering and category / tag / author storefront post listings; flattened per-entity DataProvider row shapes and stringified IDs for ui-select.
setStringify/escaping fixes and numerous PHPCS warnings cleared; integration and unit test suites updated for 2.4.6-p15, 2.4.7-p10, 2.4.8-p5 & 2.4.9 & Equivilent MageOS versions.
Deferred
The following items were listed under "Deferred to v1.1" in the 1.0.0 release but are not included in 1.1.0. They remain planned for a future release:
- Comments (native, moderation, spam, email).
- Content importers from Mageplaza, Magefan, Aheadworks, Mirasvit, WordPress (planned as a separate
mage-os/module-blog-migrationpackage). - OpenSearch /
Magento_Searchindexer + mview +etc/search_request.xml. - PageBuilder content editing.
- Hyvä-native
.phtmlset (detection plugin is in place; the companionmage-os/module-blog-hyvapackage remains pending — see README). - Configurable URL prefix, custom per-page CSS, preview-token model, Commerce-only AdminGWS plugin, MFTF tests, gravatar autofetch, per-post multi-language content variants.
- Infection MSI ≥ 75% / Covered MSI ≥ 80%.
1.0.0 - 2026-04-20
First release of the greenfield rewrite. No migration path from pre-v1 forks.
Added
- Content model. Four entities (
blog_post,blog_category,blog_tag,blog_author) with DB-level foreign keys and cascading deletes. Store-view scoping via pivot tables. Fulltext indexes on post and category content for search. - Admin UI. UI-component grids and forms for posts, categories, tags, authors. Image upload (featured image, OG image, gallery) via a single
MageOS\Blog\ImageUploadvirtualType. Related-posts and related-products pickers on the post form. - Storefront. Custom router with URL-rewrite integration. Post detail, category detail, tag detail, author detail, blog index, search, pagination. Luma template set under
view/frontend/templates/; Hyvä template set ships in the companion packagemageos/module-blog-hyva. - Scheduled publishing.
Cron\PublishScheduledPostsruns every minute, finds posts whosepublish_datejust passed, and re-saves them to invalidate FPC. Gated bymageos_blog/general/enabled. - SEO.
meta title,meta description,meta keywords,meta robots, canonical link, Open Graph, Twitter Cards, andArticleJSON-LD on post detail pages. Configurable defaults undermageos_blog/seo/*. - RSS.
/blog/rssemits RSS 2.0 XML. Limit configurable viamageos_blog/rss/limit. - Sitemap. Three
ItemProviders (post, category, tag) wired intoMagento\Sitemap\Model\ItemProvider\Composite. Per-entity enable / frequency / priority undermageos_blog/sitemap/*. - Search. DB-fulltext-backed search against the
MAGEOS_BLOG_POST_FULLTEXTindex. Controller at/blog/search?q=.... OpenSearch / Magento_Search integration deferred to v1.1. - Widgets. 6 storefront widgets: recent posts, featured post, post list, post link, category link, tag link. Admin chooser blocks for picking a post / category / tag from grids.
- GraphQL. Queries (
blogPost,blogPosts,blogCategory,blogCategories,blogTag,blogTags,blogAuthor,blogAuthors). Mutations (create/update/deletefor all four entities). URL resolver integration:urlResolver(url:"/blog/my-post")returnstype: BLOG_POST. Mutations require admin token plus ACL. - Hyvä support. A
Plugin\Magento\Framework\View\TemplateEngine\Phpplugin injects aHyvaThemeDetectionhelper into every.phtmlscope.Plugin\Magento\Framework\View\Element\TemplateRewriteremapsMageOS_Blog::Xpaths toMageOS_Blog::hyva/Xon Hyvä themes. - i18n. Seed
i18n/en_US.csvwith 236 phrases. - Quality gates. PHPStan level 8, PHPCS (Magento2 ruleset), PHP-CS-Fixer, PHPUnit unit suite (57 tests), Infection mutation testing (baselines: MSI 54%, Covered MSI 70%).
Notes on design
Design inspired by Magefan Blog (OSL-3.0). v1 is an independent implementation with no shared code.
Deferred to v1.1
- Comments (native, moderation, spam, email).
- Content importers from Mageplaza, Magefan, Aheadworks, Mirasvit, WordPress. Will ship as a separate
mageos/module-blog-migrationpackage. - OpenSearch /
Magento_Searchindexer + mview +etc/search_request.xml. - PageBuilder content editing.
- Hyvä-native
.phtmlset (detection plugin is in place; the companion package is empty until v1.1). - Configurable URL prefix, custom per-page CSS, preview-token model, Commerce-only AdminGWS plugin, MFTF tests, gravatar autofetch, per-post multi-language content variants.
- Infection MSI ≥ 75% / Covered MSI ≥ 80%. v1.0 ships at 54% / 70% respectively; raising the floor depends on expanding unit-test coverage into
ViewModel/Post/Detail(JSON-LD shape edge cases) andModel/HyvaThemeDetection(theme-chain walking).
Requires 15
| Package | Constraint |
|---|---|
| php | ^8.2 |
| magento/framework | ^103.0.7 |
| magento/module-backend | * |
| magento/module-catalog | * |
| magento/module-cms | * |
| magento/module-customer | * |
| magento/module-graph-ql | * |
| magento/module-media-storage | * |
| magento/module-search | * |
| magento/module-sitemap | * |
| magento/module-store | * |
| magento/module-ui | * |
| magento/module-url-rewrite | * |
| magento/module-url-rewrite-graph-ql | * |
| magento/module-widget | * |
Requires-dev 6
| Package | Constraint |
|---|---|
| phpunit/phpunit | ^10.5 |
| phpstan/phpstan | ^2.0 |
| bitexpert/phpstan-magento | ^0.42 |
| friendsofphp/php-cs-fixer | ^3.50 |
| magento/magento-coding-standard | ^40 |
| infection/infection | ^0.29 |
Compatibility
Each Magento release line is installed on its supported PHP versions, then the module is built (DI compilation + static-content deploy) and its unit and integration suites are run. The matrix shows the lines and PHP versions the module is confirmed to install and run on. Code-quality results further down (phpstan, phpcs, …) are reported separately and never affect compatibility.
Code Quality
Advisory checks against the module's source. Static analysis runs once across the whole module; PHPStan re-runs per Magento + PHP version because resolvable symbols differ between releases. These NEVER affect the Compatibility badge. A phpcs finding can't make a module incompatible.
Static analysis
Coding standards (phpcs), mess detection (phpmd), copy-pasted code (cpd), PHP cross-version compatibility, composer.json validity. Each runs once for the whole module.
| Tool | Status | Findings | Summary |
|---|---|---|---|
| PHPCS | Fail | 206 | 21 errors, 185 warnings (ruleset: Magento2) — 1 auto-fixable with phpcbf |
| PHPMD | Warning | 145 | 145 rule violations (UnusedFormalParameter:102, MissingImport:16, CyclomaticComplexity:11, NPathComplexity:11, ExcessiveClassComplexity:2) |
| Cpd | Warning | 9 | 9 duplicated chunks spanning 311 total lines (min-lines=5, min-tokens=70) |
| Composer validate | Info | 13 | valid; 13 advisory notes (composer validate --strict) |
Tests
Unit and integration suites, run for each applicable Magento and PHP version. A test failure speaks to the module's behaviour, not its compatibility with a Magento line, so it is reported here separately and never reddens the compatibility matrix.
Unit tests
Security
Security checks run directly against the module: an audit of its declared dependencies for known vulnerabilities (composer audit) and a scan of its source for malware and web-shell signatures. Each runs once. A malware detection fails the version outright.
Turn an existing module into recurring revenue.
If you already maintain a Magento 2 module on GitHub or GitLab, listing it on Packagento takes about five minutes. We mirror your tags, handle distribution signing, and route paid licenses through Stripe Connect, so you can keep shipping the way you already do.