mageos / module-blog
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 mageos/module-blog
bin/magento module:enable MageOS_Blog
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento cache:clean
For Hyvä storefronts, also install the companion template package:
composer require mageos/module-blog-hyva
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 → MageOS → 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 | |
|---|---|---|
| Magento 2.4.6 | yes | yes |
| Magento 2.4.7 | yes | yes |
| Hyvä 1.3+ | yes | yes |
| Luma | yes | yes |
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 shape is driven by mageos_blog/permalink/* config. URL rewrites populate on save via the repository plugins in Plugin/Repository/.
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
vendor/bin/infection --min-msi=75 --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/module-blog. Please follow Conventional Commits, include tests for new behavior, and keep PRs small and reviewable.
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.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) |
PHPStan
Type-checks the module's PHP against a real Magento install at the configured gate level. Re-runs per Magento and PHP version because resolvable symbols differ between releases. Cell → details modal.
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.