PHPackages                             wp4laravel/wp4laravel - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Framework](/categories/framework)
4. /
5. wp4laravel/wp4laravel

ActiveLaravel-package[Framework](/categories/framework)

wp4laravel/wp4laravel
=====================

Laravel with Wordpress as CMS

v3.0.1(4mo ago)1214.2k5[1 issues](https://github.com/WP4Laravel/WP4Laravel/issues)MITPHPCI failing

Since May 9Pushed 4mo ago2 watchersCompare

[ Source](https://github.com/WP4Laravel/WP4Laravel)[ Packagist](https://packagist.org/packages/wp4laravel/wp4laravel)[ RSS](/packages/wp4laravel-wp4laravel/feed)WikiDiscussions 2.x Synced today

READMEChangelog (10)Dependencies (3)Versions (94)Used By (0)

WP4Laravel - A headless Wordpress concept
=========================================

[](#wp4laravel---a-headless-wordpress-concept)

Table of contents
-----------------

[](#table-of-contents)

- [Table of contents](#table-of-contents)
- [Supported versions](#supported-versions)
- [The concept](#the-concept)
- [Dependencies](#dependencies)
- [Installation](#installation)
    - [Gitignore](#gitignore)
    - [Composer](#composer)
    - [Environment file.](#environment-file)
    - [Database config](#database-config)
    - [Service provider](#service-provider)
    - [Install Corcel](#install-corcel)
    - [Publish public data](#publish-public-data)
    - [Storage](#storage)
    - [Remove unused migrations](#remove-unused-migrations)
    - [Install WordPress](#install-wordpress)
- [Basic usage](#basic-usage)
- [References](#references)
- [Advanced Custom Fields](#advanced-custom-fields)
- [Wordpress configuration](#wordpress-configuration)
- [Add plugins](#add-plugins)
    - [How do I use it?](#how-do-i-use-it)
- [Yoast Premium](#yoast-premium)
    - [Redirects](#redirects)
- [Multilanguage](#multilanguage)
    - [Translatable models](#translatable-models)
    - [Translatable taxonomies](#translatable-taxonomies)
    - [Making translatable menu's](#making-translatable-menus)
- [Best practices](#best-practices)
    - [Create your own models for each post type](#create-your-own-models-for-each-post-type)
    - [Register your post types](#register-your-post-types)
    - [Catch-all your pages](#catch-all-your-pages)
    - [Setup your homepage](#setup-your-homepage)
    - [Get the url of a page](#get-the-url-of-a-page)
    - [Rendering \\ tags](#rendering--tags)
        - [Configuration](#configuration)
        - [Usage](#usage)
        - [Using ImageFake in the styleguide](#using-imagefake-in-the-styleguide)
    - [Using the MenuBuilder to construct menus](#using-the-menubuilder-to-construct-menus)
        - [Example usage](#example-usage)
    - [Translated menu's](#translated-menus)
    - [Activate WP preview function](#activate-wp-preview-function)
    - [SEO tags for models](#seo-tags-for-models)
    - [Hosting assets on S3](#hosting-assets-on-s3)
        - [Requirements](#requirements)
        - [Usage](#usage-1)
    - [RSS-feeds](#rss-feeds)
        - [Example usage](#example-usage-1)

The concept
-----------

[](#the-concept)

WP4Laravel is by default a standard Laravel project. Instead of using a relational database it uses WordPress as Content Management System.

The benefits relative to a standard WordPress Setup:

- Use MVC-principles
- Better performance
- Flexibility
- Sustainability
- Security

The benefits relative to a standard Laravel project:

- No need to create a custom CMS
- Get the best of great WordPress plugins
- For commercial purposes, you can sell the customer a WordPress CMS.

Dependencies
------------

[](#dependencies)

The basis of WP4Laravel is just a fresh Laravel install. We add three open source projects in the mix:

- WordPress as a dependency ()
- Corcel: Get WordPress data with Eloquent ()
- Wordplate: Standard theme and plugin for WordPress (only for inspiration, not actually installed)

Installation
------------

[](#installation)

Start a fresh Laravel install:

### Gitignore

[](#gitignore)

Add the following rules to your `.gitignore`

```
public/languages
public/plugins
public/mu-plugins
public/upgrade
public/uploads
public/wp
```

### Composer

[](#composer)

To use WordPress as a dependency, you need to extend your composer.json. Add a repositories section to the composer.json and ad the following repositories:

```
"repositories": [
    {
        "type": "composer",
        "url": "https://wpackagist.org"
    }
],
```

Add an 'extra' section to the composer.json, to determine where to install Wordpress and plugins.

```
"extra": {
    "installer-paths": {
        "public/plugins/{$name}": ["type:wordpress-plugin"]
    },
    "wordpress-install-dir": "public/wp"
}
```

Add the following packages to your installation by executing on the command-line:

```
composer require "composer/installers" "johnpbloch/wordpress" "wp4laravel/wp4laravel" "wp4laravel/wp4laravel-plugin"
```

### Environment file.

[](#environment-file)

- Add the WordPress salts to your .env file, with
- Make sure you added a database and added your database credentials to your .env file.
- Make sure the APP\_URL environment variable, matches your local environment.
- Remove all settings that are not needed for your project, such as redis and email.

### Database config

[](#database-config)

Copy the default mysql connection and name it 'wordpress'. Set the table prefix of the database connection to 'wp\_' in `config/database.php`.

### Service provider

[](#service-provider)

> Note: Only if using Laravel 5.4 or below.

Add the Service Provider of the WP4Laravel package to your config/app.php

```
WP4Laravel\WP4LaravelServiceProvider::class
```

### Install Corcel

[](#install-corcel)

Publish the corcel config file:

```
php artisan vendor:publish --provider="Corcel\Laravel\CorcelServiceProvider"
```

Open the app/corcel.php config file and define your database connection.

If you're using Laravel 5.4 or earlier, you need to configure the CorcelServiceProvider. Add the following line to your config/app.php under "Package Service Providers":

```
Corcel\Laravel\CorcelServiceProvider::class,
```

### Publish public data

[](#publish-public-data)

Unfortunately, the base theme and config of WordPress has to be inside the webroot. You can publish these from WP4LaravelServiceProvider.

```
php artisan vendor:publish --provider="WP4Laravel\WP4LaravelServiceProvider"
```

### Storage

[](#storage)

All WordPress media will be saved in the location of the Laravel Public storage. To make this work, run the following Artisan command to make a symbolic link in your webroot.

```
php artisan storage:link
```

### Remove unused migrations

[](#remove-unused-migrations)

If you're only using tables managed by WordPress, it's recommended to remove the default migrations generated by Laravel. These files are in `database/migrations/`.

### Install WordPress

[](#install-wordpress)

Go to /wp/wp-admin to setup your WordPress project.

Basic usage
-----------

[](#basic-usage)

Edit the default web route in your Laravel

```
Route::get('/', function () {
    $post = Corcel\Model\Post::findOrFail(1);

    return view('welcome', compact('post'));
});
```

Replace the 'Laravel' heading in `resources/views/welcome.blade.php` by `{{ $post->title }}`.

Open your project in the browser, you will see 'Hello World!' as heading.

References
----------

[](#references)

- Read the docs of Corcel before you start:

Advanced Custom Fields
----------------------

[](#advanced-custom-fields)

What makes WordPress a real CMS? Right: Advanced Custom Fields. To implement this concept we use 2 packages

- The Advanced Custom Fields WordPress plugin
- The Corcel ACF plugin to fetch ACF data from a Corcel / Eloquent model.

The Corcel ACF plugin is a direct dependency of WP4Laravel and is automatically installed. To get the ACF 5 PRO plugin in WordPress using composer, follow the instructions on . Alternatively, if you don't have a license for ACF Pro, you can use the free version:

```
composer require wpackagist-plugin/advanced-custom-fields
```

Look at the docs of Corcel () for the usage of Corcel with ACF.

Wordpress configuration
-----------------------

[](#wordpress-configuration)

Within `/public/themes/wp4laravel/library` you can update the WordPress configuration. Most used for configuring post types and taxonomies. Every post type kan be defined in the directory post types. En example is already included. For taxonomies, it works the same.

If you want to define your post types and taxonomies with a WordPress plugin, that's no problem.

Add plugins
-----------

[](#add-plugins)

Because WordPress and his plugins are dependencies, you can only use plugins which are available with composer.

[WordPress Packagist](https://wpackagist.org) comes straight out of the box with WP4Laravel. It mirrors the WordPress [plugin](https://plugins.svn.wordpress.org) as a Composer repository.

### How do I use it?

[](#how-do-i-use-it)

Require the desired plugin using `wpackagist-plugin` as the vendor name.

```
composer require wpackagist-plugin/advanced-custom-fields
```

Plugins are installed to `public/plugins`.

Please visit [WordPress Packagist](https://wpackagist.org) website for more information and examples.

Yoast Premium
-------------

[](#yoast-premium)

WP4Laravel has some support for key features of Yoast Premium, mostly rendering SEO tags and following redirects.

### Redirects

[](#redirects)

Redirect can be enabled by adding the included middleware to the middleware-stack. You probably want to do this in the `web` middleware group in `app/Http/Kernel.php`:

```
protected $middlewareGroups = [
    'web' => [
        // ... existing middleware
        \WP4Laravel\Yoast\Redirects\Middleware::class,
    ],
];
```

The middleware will automatically check if the request should be redirected, and return the redirect instead of handling the original request. Note that the redirect is handled in middleware and takes precedence over any existing routing. Take care not to define redirects over critical pages in your website.

Multilanguage
-------------

[](#multilanguage)

WP4Laravel contains various options to work with multilanguage-enabled websites. These solutions are based on using the free version of Poylang ([plugin](https://wordpress.org/plugins/polylang/), [wpackagist](https://wpackagist.org/search?q=polylang&type=any&search=)).

### Translatable models

[](#translatable-models)

A Translatable trait is included for working with the [Polylang](https://wordpress.org/plugins/polylang/) plugin. Include this trait in your models to gain access to useful properties for working with translated versions of posts.

```
class Post extends \Corcel\Post
{
    use \WP4Laravel\Multilanguage\Translatable;
}
```

Including the trait with add a `language` scope for use with Eloquent and a `language` property.

```
$posts = Post::language('de')->published()->first();
echo $post->language; // de
```

It also includes a `translations` property which yields a collection, keyed by the language code, of all available translations of a given post.

```
$post = Post::slug('about-us')->first();
echo $post->translations['nl']->title; // Over ons
```

### Translatable taxonomies

[](#translatable-taxonomies)

Similarly to translating models, WP4Laravel also supports translating taxonomies. For this, you must enable the taxonomy to be translated in WP-Admin &gt; Languages &gt; Settings &gt; Custom post Types and Taxonomies. To use the translation information on the website, create a model for the taxonomy and add the TranslatableTaxonomy-trait:

```
class EventType extends \Corcel\Model\Taxonomy
{
    use \WP4Laravel\Multilanguage\TranslatableTaxonomy;

    protected $taxonomy = 'event_type';
}
```

The trait creates a scope on the model `language(string)` which can be used to filter terms:

```
$language = localization()->getCurrentLocale();
$eventTypes = EventType::language()->get(); // Returns only the
```

### Making translatable menu's

[](#making-translatable-menus)

The MenuBuilder has a utility function to work with menu's that have been translated using Polylang. First, configure your theme to have various menu locations. These are the slots on your website in which a menu is going to be displayed. Each entry has a location identifier and description:

```
register_nav_menu('main', 'Main navigation in header');
register_nav_menu('contact', 'Contact links in menu dropdown and footer');
register_nav_menu('footer', 'Additional footer links');
```

Polylang will automatically make translated locations for every language you specify. Use the Wordpress admin interface to create a menu and assign it to a location. Than, call the `MenuBuilder::menuForLocation($slot, $language)` method call to find the appropriate menu for a location. It returns a basic `Corcel\Model\Menu` class. This method supports both translated and untranslated menu structures.

```
// Get a untranslated menu
$menu = MenuBuilder::menuForLocation('main');

// Get a translated menu for a location
$menu = MenuBuilder::menuForLocation('main', Localization::getCurrentLanguage());
```

Best practices
--------------

[](#best-practices)

### Create your own models for each post type

[](#create-your-own-models-for-each-post-type)

If you want to take advantage of the power of Eloquent, we advise to create a Laravel model for each of your post types.

```
namespace App\Models;

use Corcel\Post as Corcel;

class Event extends Corcel
{
    protected $postType = 'event';
}
```

For example, you can add accessors to make life easier.

### Register your post types

[](#register-your-post-types)

When you access a post type from a specific model, you have to register this. You can do this to match a post\_type with the dedicated model in the config/corcel.php file. For example:

config/corcel.php

```
'post_types' => [
      'page' => \App\Models\Page::class,
      'faq' => \App\Models\Faq::class,
      'post' => \App\Models\Blog::class
],
```

If you choose to create a new class for your custom post type, you can have this class be returned for all instances of that post type.

### Catch-all your pages

[](#catch-all-your-pages)

First you have to make sure you define your catch-all route at the bottom of your routes file:

Route:

```
Route::get('{url}', 'PageController')->where('url', '(.*)')->name('page.show');
```

Create a PageController with the show method inside:

PageController:

```
