Manage any Laravel app as if it was a CMS

Published on by

Manage any Laravel app as if it was a CMS image

We all love working with Laravel but what if we could take a step further – imagine that we could edit any page or any email of our Laravel app as if it was some kind of a CMS. We see a rendered HTML page where we can click on any element and just edit it, instead of going to the Blade templates or language files?

As a consequence, we could invite our non-dev colleagues to collaborate – we could discuss, manage and deploy text updates together, our colleagues wouldn’t be blocked by developers anymore. But even if you are a single developer shop, the value is still lucrative – being able to see all texts in their real context, quickly navigate through different scenarios and edge cases without touching the database or seeding or anything of that sort.

Are you 100% sure that all your Blade templates and language files are completely in sync with the product’s current state and that nowhere, nowhere in your UX you say things to customers that aren’t right anymore? Are you 100% sure that all pages have SEO-optimised HTML meta tags? Are you 100% sure that all texts have corresponding translations in all product languages and they fit nicely within their UX elements?

A new paradigm

Paragraph offers a new paradigm – instead of managing view templates, language files, translation keys and all that other boring stuff, let’s try to think about our product from a higher level, from a customer level really – let’s start working with pages, emails and user journeys instead!

After all, users don’t land on “welcome.blade.php”, they land on Welcome page. They don’t create accounts on “auth.form”, they create accounts by filling a form on the Sign Up page. Calling things what they are is going to make it much easier to manage the product, for both developers and non-developers.

Getting started

In this example we will use a brand new Laravel app and work with its welcome page – the page that most of us are so familiar with 🙂 Let’s create an app using composer:

$ composer create-project laravel/laravel laravel-test
$ cd laravel-test

Now we head to Paragraph to create a new project (free!):

And now that we have received our API key and saved it in the .env file, we can install Paragraph’s composer package and then launch a local web server:

$ composer require paragraph/laravel
$ php artisan serve

Opening our brand new Laravel app in the browser shows this cute welcome page:

If you look at welcome.blade.php, you will notice that all texts are directly inside the HTML markup:

<div class="ml-4 text-lg leading-7 font-semibold">
<a href="https://laravel.com/docs" class="underline text-gray-900 dark:text-white">
Documentation
</a>
</div>

Let’s wrap them in Laravel’s localization directive so that they become translatable:

<div class="ml-4 text-lg leading-7 font-semibold">
<a href="https://laravel.com/docs" class="underline text-gray-900 dark:text-white">
@lang('Documentation')
</a>
</div>

This is a very safe thing to do and it won’t break anything regardless on whether you actually plan to translate your product or not. Laravel will always fall back to the original text if there is no translation available. This also means that you will not be tied to Paragraph, there is no lock-in. You are using a framework’s feature and you are free to swap your specific implementations at any time.

Now lets clear the cache by running php artisan paragraph:clear-views and then visit the same page again in browser:

Looks about the same? Well, it’s the same page. But now, with our Paragraph hook incorporated in the Laravel’s rendering mechanism, the view got analysed and saved as a snapshot in a temporary folder. We can submit all outstanding snapshots by running a console command:

$ php artisan paragraph:submit-views
Submitting storage/paragraph_view_snapshot_welcome.html
Submitted a total of 1 snapshots

If we go back to the Paragraph dashboard, we will find out that there is 1 page available to manage now:

If we click on “Pages” we can see a list of all our product pages. Currently it’s just the Welcome page that we imported a few seconds ago:

Click on the page to open a full page editor. As we can see, all texts are editable in-place now, CMS-style editing! Paragraph just turned our Laravel app into Wordpress, but in a good way.

From this moment, we don’t have to go back to the language files or Blade templates, we can just stay here, we can use Paragraph for any copy updates. As long as our @lang directives are in place, we can control the texts from a cloud dashboard that will allow us to be way more productive.

To bring the updates back to your Laravel app, we need to download the latest copy updates from time to time by running a console command either manually, via cron or as a part of your CI/CD pipeline:

$ php artisan paragraph:download

Localisation

If you need to localise your Laravel product – to translate it into different languages, then you just found a perfect package for that. Just add any languages you need in the project settings on Paragraph and you can start translating right away. You have two editor options – you can use the page view that we shown above, or you can open a more “traditional” table view with all texts.

To help you progress faster, we included AWS, Bing and Google Cloud machine translators that can provide you with a starting point:

We only made two clicks and now the progress of our Spanish translations moved to 100%:

SEO-optimisation

Your product might be the best in the world but people still need to be able to find it in order to become your customers. Having relevant, SEO-optimised HTML tags is crucial but not so easy to achieve when you have hundreds or thousands of Blade templates scattered around the repository.

Let’s wrap our HTML tags in the Laravel’s translation directive:

<meta
name="description"
content="@lang('A very efficient SEO description goes here')"
/>
<meta
name="keywords"
content="@lang('SEO keywords go here')"
/>
<title>@lang('Laravel')</title>

Let’s now clear the cache, refresh the page in browser and then re-submit the data to Paragraph:

$ php artisan paragraph:clear-views
Deleted storage/paragraph_view_snapshot_welcome.html
Deleted a total of 1 snapshots
$ php artisan paragraph:submit-views
Submitting storage/paragraph_view_snapshot_welcome.html
Submitted a total of 1 snapshots

Great, now the 3 SEO tags we just added are in Paragraph as well:

We can manage all our SEO tags (as well as translate them if necessary) in a breeze!

Going advanced

You probably noticed how we had to open the local page in browser before we could submit anything to the cloud. That’s the easiest way to start because it doesn’t require any additional work, a small website could even enable this in production – capture different pages and then submit them from time to time to Paragraph using cron.

But if you want to have a better control, a nicer way to do this is by incorporating the special Paragraph‘s trait in your test suite:

use Paragraph\WithParagraph;
 
class ExampleTest extends TestCase
{
use RefreshDatabase, WithFaker, WithParagraph;
}

This way, every time you run tests locally or in your CI/CD pipeline, pages will be updated to their new design and new texts will automatically be parsed.

On top of that, you can define user journeys – sequences of steps and outgoing communications:

/**
* @test
*/
public function journey()
{
$this->sequence('User creates an account', function () {
$this->name('Home page')->get('/');
$this->name('Sign-up page')->get('/sign-up');
$this->post('/sign-up', ['email' => '', 'password' => '']);
// Behind the scenes a WelcomeEmail($user) mailable is sent
});
}

This will automatically create a “User creates an account” journey on Paragraph consisting of 2 steps in browser and one outgoing welcome email.

Interested? Does this sound neat to you? You can connect your Laravel app by creating a free account on Paragraph today.

Eric L. Barnes photo

Eric is the creator of Laravel News and has been covering Laravel since 2012.

Filed in:
Cube

Laravel Newsletter

Join 40k+ other developers and never miss out on new tips, tutorials, and more.

Laravel Forge logo

Laravel Forge

Easily create and manage your servers and deploy your Laravel applications in seconds.

Laravel Forge
Tinkerwell logo

Tinkerwell

The must-have code runner for Laravel developers. Tinker with AI, autocompletion and instant feedback on local and production environments.

Tinkerwell
No Compromises logo

No Compromises

Joel and Aaron, the two seasoned devs from the No Compromises podcast, are now available to hire for your Laravel project. ⬧ Flat rate of $7500/mo. ⬧ No lengthy sales process. ⬧ No contracts. ⬧ 100% money back guarantee.

No Compromises
Kirschbaum logo

Kirschbaum

Providing innovation and stability to ensure your web application succeeds.

Kirschbaum
Shift logo

Shift

Running an old Laravel version? Instant, automated Laravel upgrades and code modernization to keep your applications fresh.

Shift
Bacancy logo

Bacancy

Supercharge your project with a seasoned Laravel developer with 4-6 years of experience for just $2500/month. Get 160 hours of dedicated expertise & a risk-free 15-day trial. Schedule a call now!

Bacancy
Lucky Media logo

Lucky Media

Get Lucky Now - the ideal choice for Laravel Development, with over a decade of experience!

Lucky Media
Lunar: Laravel E-Commerce logo

Lunar: Laravel E-Commerce

E-Commerce for Laravel. An open-source package that brings the power of modern headless e-commerce functionality to Laravel.

Lunar: Laravel E-Commerce
LaraJobs logo

LaraJobs

The official Laravel job board

LaraJobs
SaaSykit: Laravel SaaS Starter Kit logo

SaaSykit: Laravel SaaS Starter Kit

SaaSykit is a Multi-tenant Laravel SaaS Starter Kit that comes with all features required to run a modern SaaS. Payments, Beautiful Checkout, Admin Panel, User dashboard, Auth, Ready Components, Stats, Blog, Docs and more.

SaaSykit: Laravel SaaS Starter Kit
Supercharge Your SaaS Development with FilamentFlow: The Ultimate Laravel Filament Boilerplate logo

Supercharge Your SaaS Development with FilamentFlow: The Ultimate Laravel Filament Boilerplate

Build your SaaS application in hours. Out-of-the-box multi-tenancy and seamless Stripe integration. Supports subscriptions and one-time purchases, allowing you to focus on building and creating without repetitive setup tasks.

Supercharge Your SaaS Development with FilamentFlow: The Ultimate Laravel Filament Boilerplate
Rector logo

Rector

Your partner for seamless Laravel upgrades, cutting costs, and accelerating innovation for successful companies

Rector
MongoDB logo

MongoDB

Enhance your PHP applications with the powerful integration of MongoDB and Laravel, empowering developers to build applications with ease and efficiency. Support transactional, search, analytics and mobile use cases while using the familiar Eloquent APIs. Discover how MongoDB's flexible, modern database can transform your Laravel applications.

MongoDB

The latest

View all →
Asymmetric Property Visibility in PHP 8.4 image

Asymmetric Property Visibility in PHP 8.4

Read article
Access Laravel Pulse Data as a JSON API image

Access Laravel Pulse Data as a JSON API

Read article
Laravel Forge adds Statamic Integration image

Laravel Forge adds Statamic Integration

Read article
Transform Data into Type-safe DTOs with this PHP Package image

Transform Data into Type-safe DTOs with this PHP Package

Read article
PHPxWorld - The resurgence of PHP meet-ups with Chris Morrell image

PHPxWorld - The resurgence of PHP meet-ups with Chris Morrell

Read article
Herd Executable Support and Pest 3 Mutation Testing in PhpStorm 2024.3 image

Herd Executable Support and Pest 3 Mutation Testing in PhpStorm 2024.3

Read article