artisanpack-ui/cms-framework 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

artisanpack-ui/cms-framework

Composer 安装命令:

composer require artisanpack-ui/cms-framework

包简介

Adds in the back end support for building a CMS with any front end framework.

README 文档

README

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

A comprehensive Laravel package that provides back-end support for building a CMS with any front-end framework. This package offers a complete set of features for content management, user management, authentication, and more.

Features

  • Content Management: Content types, taxonomies, and media management
  • Admin Interface: Admin pages, dashboard widgets, and settings management
  • User Management: User roles, permissions, and profiles (powered by artisanpack-ui/rbac in 2.0.0)
  • Authentication: Two-factor authentication with Laravel Sanctum integration
  • Notifications: Comprehensive notification system
  • Site Editor (new in 2.0.0): WordPress-style templates, template parts, patterns, global styles, and menus
  • Visual Editor Integration (new in 2.0.0): Opt-in bridge to the optional artisanpack-ui/visual-editor package
  • Blog Comments (new in 2.1.0): Threaded post comments with public read / guest submit, rate-limited public submission, and auth-gated moderation
  • Themes: Discovery, activation, ZIP upload, and lifecycle hooks
  • Plugins: Plugin system ⚠️ Experimental
  • Core Updates: Automatic update checking and management with rollback support
  • PWA Support: Progressive Web App features
  • Audit Logging: Track changes and user actions

Requirements

  • PHP 8.3 or higher
  • Laravel 12.0 or 13.0
  • Laravel Sanctum 4.1 or higher

Quick Installation

You can install the CMS Framework package by running the following composer command:

composer require artisanpack-ui/cms-framework

After installation, publish the configuration file:

php artisan vendor:publish --tag=cms-framework-config

Run the migrations to set up the database tables:

php artisan migrate

Documentation

📚 Complete Documentation

Quick Start

Content Types

Register a custom content type:

use ArtisanPackUI\CMSFramework\Features\ContentTypes\ContentTypeManager;

app(ContentTypeManager::class)->register('product', [
    'name' => 'Product',
    'plural' => 'Products',
    'description' => 'Products for the store',
    'supports' => ['title', 'editor', 'thumbnail'],
]);

Admin Pages

Register a custom admin page:

use ArtisanPackUI\CMSFramework\Features\AdminPages\AdminPagesManager;

app(AdminPagesManager::class)->addPage([
    'title' => 'Custom Settings',
    'slug' => 'custom-settings',
    'callback' => function() {
        return view('custom.settings');
    }
]);

Settings

Register and retrieve settings:

use ArtisanPackUI\CMSFramework\Features\Settings\SettingsManager;

// Register a setting
app(SettingsManager::class)->register('site_name', 'My Awesome Site');

// Get a setting
$siteName = app(SettingsManager::class)->get('site_name');

Customization with Hooks

The CMS Framework uses hooks and filters for extensive customization:

// addFilter and addAction are global helper functions provided by the framework

// Add a filter
addFilter('ap.cms.migrations.directories', function($directories) {
    $directories[] = __DIR__ . '/database/migrations';
    return $directories;
});

// Add an action
addAction('ap.cms.after_content_save', function($content) {
    // Do something after content is saved
});

Using with the visual editor

cms-framework is fully usable standalone, but pairs with artisanpack-ui/visual-editor to expose its Post and Page content to a Gutenberg-style block editor, back core/site-* blocks with real site settings, and seed visual_editor.* permissions into the RBAC tables. The full integration contract lives in visual-editor's docs/plans/12-cms-framework-integration.md; the reciprocal narrative is visual-editor's Using with cms-framework section.

Install both packages

composer require artisanpack-ui/cms-framework artisanpack-ui/visual-editor

Both packages are loosely coupled — every cms-framework hook into the editor is guarded by class_exists(\ArtisanPackUI\VisualEditor\VisualEditor::class), so cms-framework continues to work standalone if visual-editor is not installed.

Run migrations

php artisan migrate

The cms-framework migration set adds a block_content json nullable column to the posts and pages tables (alongside the preserved legacy content longText column, which keeps powering search / excerpt / backwards-compatibility). Editing a legacy post in the visual editor populates block_content on first save; the legacy column is left untouched. See plan 12 §4.2 Block content storage for the dual-state guidance.

Resource map (ap.visual-editor.resources)

When visual-editor is detected, cms-framework's service provider auto-registers Post and Page into the editor's ap.visual-editor.resources filter:

// CMSFrameworkServiceProvider::boot()
if ( class_exists( \ArtisanPackUI\VisualEditor\VisualEditor::class ) ) {
    addFilter( 'ap.visual-editor.resources', function ( array $resources ): array {
        return array_merge( [
            'posts' => \ArtisanPackUI\CMSFramework\Modules\Blog\Models\Post::class,
            'pages' => \ArtisanPackUI\CMSFramework\Modules\Pages\Models\Page::class,
        ], $resources );
    } );
}

Host-app overrides in config/artisanpack/visual-editor.php always win on key collision, so swapping posts to a custom App\Models\Post is just a config edit. Full filter contract (input/output shape, collision behavior, validation guarantees, contributor timing): plan 12 §4.1 Resource filter contract.

PostResolver accessors

Post and Page expose a handful of accessors that visual-editor's PostResolver reads to stamp _resolved* attributes on core/post-* and core/navigation blocks:

Accessor Type Source Used by
rendered_content string HasRenderedBlockContent concern — renders block_content through the visual editor's server-side renderer, falling back to the legacy content column when block_content is null _resolvedContent on core/post-content
previous_post ?Post adjacent post ordered by published_at (ties broken by id) _resolvedPreviousPost on core/post-navigation-link
next_post ?Post adjacent post ordered by published_at (ties broken by id) _resolvedNextPost on core/post-navigation-link
comments_count int approved comments only _resolvedCommentsCount on core/post-comments-count
comments_url string canonical #comments anchor on the post URL _resolvedCommentsUrl on core/post-comments-link

All accessors are eager-load friendly and safe to call on detached models — the adjacency lookup short-circuits to null for unsaved or unpublished posts.

Site-meta bridge

cms-framework registers the site.* setting family via SettingsManager and exposes a WordPress-shape envelope at GET /api/v1/settings/site that the editor's core/site-* blocks consume:

$settings->registerSetting( 'site.title',    config( 'app.name', '' ),  'sanitizeText',  SettingType::String );
$settings->registerSetting( 'site.tagline',  '',                         'sanitizeText',  SettingType::String );
$settings->registerSetting( 'site.url',      config( 'app.url', '' ),    'sanitizeUrl',   SettingType::String );
$settings->registerSetting( 'site.logo_id',  null,                       'sanitizeInt',   SettingType::Integer );
$settings->registerSetting( 'site.icon_id',  null,                       'sanitizeInt',   SettingType::Integer );
GET /api/v1/settings/site
{
    "title": "ArtisanPack UI Demo",
    "description": "A Laravel CMS",
    "url": "https://example.test",
    "site_logo": 42,
    "site_icon": 17
}

Mutating endpoints (PUT /api/v1/settings/site) update the matching Setting rows through SettingsManager. See plan 12 §4.3 Site-meta REST shape.

Permissions seed (visual_editor.*)

When visual-editor is detected, cms-framework seeds the editor's permission family into its RBAC tables so host apps can grant them on roles immediately:

visual_editor.access
visual_editor.posts.edit
visual_editor.pages.edit
visual_editor.templates.edit
visual_editor.template-parts.edit
visual_editor.patterns.edit
visual_editor.global-styles.edit
visual_editor.navigation.edit

Permissions are registered but not yet enforced by visual-editor's policies — that flips in a future release behind artisanpack.visual-editor.authorization.delegate_to_cms_framework. See plan 12 §4.6 Permissions seed (G5).

Version pairing

cms-framework and visual-editor ship as a version pair — the supported combinations are tracked in visual-editor's Version compatibility matrix. Bumping the major on either package without bumping the partner is unsupported.

AI features

The framework ships five AI-powered content-authoring agents (added in 2.3.0). Each maps to a feature key in the artisanpack-ui/ai foundation and is registered automatically via the service provider's aiFeatures() hook — no wiring required in host apps.

Feature key Agent What it does
cms.post_title PostTitleSuggestionAgent Generate 3–5 title variants from a draft body.
cms.excerpt ExcerptGenerationAgent Generate a natural excerpt (default ≤200 chars) from full content.
cms.suggest_tags TagSuggestionAgent Select tags from an existing taxonomy (optionally propose new ones).
cms.suggest_category CategorySuggestionAgent Pick a single category (as a slash-delimited path) from a tree.
cms.suggest_slug SlugSuggestionAgent Produce an SEO-friendly slug (short, keyword-forward, no stop words).

Every agent honors the feature toggle configured in artisanpack.ai.features.<key>.enabled — when the toggle is off, the agent throws FeatureDisabledException and no model call is made.

Trigger surfaces

The same five agents are exposed to every front-end framework:

  • Livewire: dispatch ap-cms-ai:{action} browser events at the ap-cms-ai-tools component (ArtisanPackUI\CMSFramework\Livewire\Ai\AiTools). Results come back on ap-cms-ai:{featureKey}:{success|invalid-input|disabled|missing-credentials|error}.
  • React / Vue / anything else: POST to the REST endpoints mounted under /api/v1/cms/ai (AiController). This keeps @artisanpack-ui/react and @artisanpack-ui/vue framework-agnostic — those packages do NOT need to know anything about CMS AI features.

Available endpoints (all auth middleware, JSON body):

Method Path Body
GET /api/v1/cms/ai/features
POST /api/v1/cms/ai/post-title { content, tone?, count? }
POST /api/v1/cms/ai/excerpt { content, max_chars? }
POST /api/v1/cms/ai/suggest-tags { content, available_tags, allow_new?, max_selected? }
POST /api/v1/cms/ai/suggest-category { content, category_tree }
POST /api/v1/cms/ai/suggest-slug { title, excerpt?, max_chars? }

Error responses use consistent status codes: 403 feature_disabled, 422 invalid_input, 503 missing_credentials, 500 internal_error.

Requirements

The AI features require artisanpack-ui/ai ^1.0. It's declared as a suggest in composer.json — install it explicitly to opt in:

composer require artisanpack-ui/ai:^1.0

Without it, the agents, the Livewire component, and the REST endpoints stay unregistered — the framework boots normally.

Experimental Features

The following features are experimental in the 1.0.0 release and should be used with caution in production environments:

Plugin System

The plugin system provides a foundation for extending the CMS with custom functionality.

What Works:

  • Plugin model with activation/deactivation tracking
  • Plugin manager for lifecycle management
  • Plugin installation and validation
  • Plugin update manager integration

Known Limitations:

  • Plugin lifecycle hooks not fully implemented
  • No plugin dependency management
  • Limited plugin configuration API
  • No plugin marketplace integration

Recommendation: Use for testing and development. Not recommended for production until full lifecycle support is added in a future release.

Theme System

The theme system allows customization of the CMS appearance.

What Works:

  • Theme manager with theme discovery
  • Theme activation mechanism
  • JSON manifest validation
  • Basic theme structure
  • Lifecycle hooks for install/activate (see below)

Known Limitations:

  • Asset compilation not implemented
  • No child theme support
  • Limited theme customization API
  • No theme preview functionality

Theme Lifecycle Hooks

The Themes module fires doAction() callbacks around installFromZip() and activateTheme() so host applications can subscribe listeners (seed content, register theme-supplied service providers, etc.) without forking the framework.

Hook Fires Payload Throwing semantics
theme.installing After the ZIP is extracted and the manifest is validated, before the install is finalized. string $slug, array $manifest Throwing aborts the install; the extracted directory is rolled back.
theme.installed After the install completes and the discovery cache is cleared. string $slug, array $manifest Throwing propagates to the caller (install is already complete).
theme.activating After the target theme is resolved, before themes.activeTheme is updated. string $slug, array $manifest Throwing aborts activation; the active theme setting is not changed.
theme.activated After themes.activeTheme is updated and cache invalidation is attempted (including view:clear, which is logged-and-continued on failure). string $slug, array $manifest Throwing propagates to the caller (activation is already complete).
addAction('theme.activated', function (string $slug, array $manifest): void {
    // Seed pages, register navigation entries, etc.
});

Recommendation: Use for testing and development. Full theme support including asset compilation and child themes will be added in a future release.

Reporting Issues

If you encounter issues with experimental features, please report them on our issue tracker with the experimental label.

Contributing

We welcome contributions! Please see Contributing Guide for details on:

  • Development setup
  • Code style guidelines
  • Testing requirements
  • Submission process

Security

If you discover a security vulnerability, please send an email to security@artisanpack.com. All security vulnerabilities will be promptly addressed.

Credits

License

The MIT License (MIT). Please see License File for more information.

Changelog

Please see CHANGELOG.md for more information on what has changed recently.

artisanpack-ui/cms-framework 适用场景与选型建议

artisanpack-ui/cms-framework 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 504 次下载、GitHub Stars 达 0, 最近一次更新时间为 2025 年 07 月 13 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 artisanpack-ui/cms-framework 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 artisanpack-ui/cms-framework 我们能提供哪些服务?
定制开发 / 二次开发

基于 artisanpack-ui/cms-framework 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 504
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 12
  • 依赖项目数: 1
  • 推荐数: 2

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-07-13