PagibleAI CMS is a Laravel package designed for seamless integration into existing Laravel applications. Installation is quick and straightforward, typically taking just a few minutes.
Requirements:
- Laravel 11, 12 or 13
- MySQL 5.7+, MariaDB 10.3+, PostgreSQL 12+, SQLite 3.26+, SQL Server 2017+
You need a working Laravel installation. If you don't have one, you can create it using:
composer create-project laravel/laravel pagible
cd pagible
The application will be available in the ./pagible sub-directory. Then, run this command within your Laravel application directory:
composer req aimeos/pagible
php artisan cms:install
php artisan migrate
Now, adapt the .env file of your application and change the APP_URL setting to your domain. If you are using php artisan serve for testing, add the port of the internal web server (APP_URL=http://localhost:8000). Otherwise, the uploading files will fail because they wouldn't be loaded!
Add a line in the "post-update-cmd" section of your composer.json file to update the admin backend files after each update:
"post-update-cmd": [
"@php artisan vendor:publish --force --tag=cms-admin",
"@php artisan vendor:publish --tag=cms-theme",
"@php artisan migrate",
...
],
To allow users to edit CMS content or to create a new users if they don't exist yet, you can use the cms:user command (replace the e-mail address by the users one):
php artisan cms:user -e editor@example.com
This adds admin privileges for the specified user. For more information regarding authorization and permissions, please have a look into the authorization and permission page.
The CMS admin backend is available at (replace "mydomain.tld" with your own one):
http://mydomain.tld/cmsadmin
To generate texts/images from prompts, analyze image/video/audio content, or execute actions based on your prompts, you have to configure one or more of the AI service providers supported by the Prism and Prisma packages.
Note: You only need to configure API keys for the AI service providers you are using, not for all!
For best results and all features, you need Google, OpenAI, Clipdrop, and DeepL at the moment and they are also configured by default. All service providers require to sign-up and create an account first. They will provide an API key which you need to add to your .env file or as environment variable, e.g.:
GEMINI_API_KEY="..."
OPENAI_API_KEY="..."
CLIPDROP_API_KEY="..."
DEEPL_API_KEY="..."
# Text translation
CMS_AI_TRANSLATE_API_KEY="${DEEPL_API_KEY}"
# For DeepL Pro accounts
# CMS_AI_TRANSLATE_URL="https://api.deepl.com/"
# Analyze content and generate text/images
CMS_AI_WRITE_API_KEY="${GEMINI_API_KEY}"
CMS_AI_REFINE_API_KEY="${GEMINI_API_KEY}"
CMS_AI_DESCRIBE_API_KEY="${GEMINI_API_KEY}"
CMS_AI_IMAGINE_API_KEY="${GEMINI_API_KEY}"
CMS_AI_INPAINT_API_KEY="${GEMINI_API_KEY}"
CMS_AI_REPAINT_API_KEY="${GEMINI_API_KEY}"
# Image manipulation
CMS_AI_ERASE_API_KEY="${CLIPDROP_API_KEY}"
CMS_AI_ISOLATE_API_KEY="${CLIPDROP_API_KEY}"
CMS_AI_UNCROP_API_KEY="${CLIPDROP_API_KEY}"
CMS_AI_UPSCALE_API_KEY="${CLIPDROP_API_KEY}"
# Audio transcription
CMS_AI_TRANSCRIBE_API_KEY="${OPENAI_API_KEY}"
If you want to use a different provider or model, you can to configure them in your .env file too. Please have a look into the ./config/cms.php for the used environment variables.
Note: You can also configure the base URLs for each provider using the url key in each provider configuration, e.g.:
'transcribe' => [ // Transcribe audio
'provider' => env( 'CMS_AI_TRANSCRIBE', 'openai' ),
'model' => env( 'CMS_AI_TRANSCRIBE_MODEL', 'whisper-1' ),
'api_key' => env( 'CMS_AI_TRANSCRIBE_API_KEY' ),
'url' => 'https://openai-api.compatible-provider.com'
],
Note: To protect forms like the contact form against misuse and spam, you can configure HCaptcha.
For scheduled publishing, you need to add this line to the routes/console.php class:
\Illuminate\Support\Facades\Schedule::command('cms:publish')->daily();
To clean up soft-deleted pages, elements and files regularly, add these lines to the routes/console.php class:
\Illuminate\Support\Facades\Schedule::command('model:prune', [
'--model' => [
\Aimeos\Cms\Models\Page::class,
\Aimeos\Cms\Models\Element::class,
\Aimeos\Cms\Models\File::class
],
])->daily();
You can configure the timeframe after soft-deleted items will be removed permanently by setting the CMS_PURGE option in your .env file. Its value must be the number of days after which the items will be removed permanently or FALSE if the soft-deleted items shouldn't be removed at all.
Using multiple page trees with different domains is possible by adding CMS_MULTIDOMAIN=true to your .env file.
PagibleAI CMS supports single database multi-tenancy using existing Laravel tenancy packages or code implemented by your own.
The Tenancy for Laravel package is most often used. How to set up the package is described in the Multi-tenancy SaaS Setup article.
The PagibleAI CMS backend is a SPA application based on VueJS 3 and Vuetify. To integrate it into your own Laravel-based admin backend, include these lines into the HTML head section:
@if($index = cmsadmin('vendor/cms/admin/.vite/manifest.json'))
<script type="module" crossorigin src="{{ asset('vendor/cms/admin/' . ($index['file'] ?? '')) }}"></script>
@foreach($index['css'] ?? [] as $file)
<link rel="stylesheet" crossorigin href="{{ asset('vendor/cms/admin/' . $file) }}">
@endforeach
@endif
Furthermore, add the HTML where the application will be rendered into into your page body:
<div id="app"
data-urlgraphql="{{ route('graphql') }}"
data-urladmin="{{ route('cms.admin', [], false) }}"
data-urlproxy="{{ route('cms.proxy', ['url' => '_url_']) }}"
data-urlpage="{{ route('cms.page', ['path' => '_path_'] + (config('cms.multidomain') ? ['domain' => '_domain_'] : [])) }}"
data-urlfile="{{ \Illuminate\Support\Facades\Storage::disk( config( 'cms.disk', 'public' ) )->url( '' ) }}"
data-theme="{{ json_encode( config( 'cms.admin.colors', [] ) ) }}"
data-locales="{{ json_encode( config( 'cms.locales', ['en'] ) ) }}"
data-config="{{ json_encode( config( 'cms.config', new \stdClass() ) ) }}"
data-schemas="{{ json_encode( config( 'cms.schemas', new \stdClass() ) ) }}"
data-multidomain="{{ (int) config('cms.multidomain', false) }}"
></div>