Table des matières
- Installer Wordpress
- Activer la réécriture des liens
- Créer un nouveau projet Symfony
- Faire un RouteLoader qui chargera les routes
- Faire un Controller qui affichera les pages
- Le résultat
Installer Wordpress
L'idée du projet est d'utiliser Wordpress pour administrer le contenu du site, et un Symfony pour consommer l'API de Wordpress et pour afficher les pages.
Je dois donc commencer par installer un nouveau Wordpress. Pour cela, je vais à l'adresse suivante: Wordpress
Une fois le téléchargement terminé, j'extrais l'archive dans mon dossier de travail et je lance la commande suivante:
php -S localhost:9999
Ensuite, si je me rends à l'adresse suivante http://localhost:9999
, je peux commencer l'installation du Wordpress.
Une fois l'installation terminée, Wordpress me propose de me connecter à l'interface avec le compte que j'ai renseigné lors de l'installation.
Activer la réécriture des liens
Pour activer l'API de Wordpress, il suffit d'activer la réécriture des liens à la page suivante: http://localhost:9999/wp-admin/options-permalink.php
Ensuite, l'API devient accessible à l'url suivante: http://localhost:9999/wp-json/
. Cette url est une sorte de documentation de l'API du Wordpress.
Nous pouvons voir la liste des endpoints disponibles et les paramètres qu'ils acceptent.
Créer un nouveau projet Symfony
Dans un autre dossier, je vais créer un nouveau projet Symfony. C'est ce dernier qui lira l'API de Wordpress et qui affichera les pages aux clients.
Je commence par exécuter les commandes suivantes:
symfony new --full my-blog-symfony
cd my-blog-symfony
Et si je vérifie, je n'ai pour le moment aucune route configurée.
bin/console debug:router
-------------------------- -------- -------- ------ -----------------------------------
Name Method Scheme Host Path
-------------------------- -------- -------- ------ -----------------------------------
_preview_error ANY ANY ANY /_error/{code}.{_format}
_wdt ANY ANY ANY /_wdt/{token}
_profiler_home ANY ANY ANY /_profiler/
_profiler_search ANY ANY ANY /_profiler/search
_profiler_search_bar ANY ANY ANY /_profiler/search_bar
_profiler_phpinfo ANY ANY ANY /_profiler/phpinfo
_profiler_search_results ANY ANY ANY /_profiler/{token}/search/results
_profiler_open_file ANY ANY ANY /_profiler/open
_profiler ANY ANY ANY /_profiler/{token}
_profiler_router ANY ANY ANY /_profiler/{token}/router
_profiler_exception ANY ANY ANY /_profiler/{token}/exception
_profiler_exception_css ANY ANY ANY /_profiler/{token}/exception.css
-------------------------- -------- -------- ------ -----------------------------------
Faire un RouteLoader qui chargera les routes
Je vais donc commencer par déclarer un RouteLoader dans mon fichier de routing.
my_blog_pages:
resource: 'App\Routing\RouteLoader::loadPages'
type: service
Ce service a besoin d'implémenter RouteLoaderInterface
et la méthode loadPages
déclarée dans le fichier de routing doit retourner une RouteCollection
.
<?php
declare(strict_types=1);
namespace App\Routing;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Component\Routing\Route;
use Symfony\Bundle\FrameworkBundle\Routing\RouteLoaderInterface;
use Symfony\Component\Routing\RouteCollection;
class RouteLoader implements RouteLoaderInterface
{
private $client;
public function __construct(HttpClientInterface $client)
{
$this->client = $client;
}
public function loadPages(): RouteCollection
{
$routes = new RouteCollection();
foreach ($this->fetch() as $routeConfiguration) {
$routeIdentifier = $routeConfiguration['id'];
$routes->add("page_$routeIdentifier", new Route($routeConfiguration['slug'], [
'_controller' => 'App\Controller\PageController::show',
'pageData' => $routeConfiguration
]));
}
return $routes;
}
private function fetch(): array
{
$response = $this->client->request('GET','http://localhost:9999/wp-json/wp/v2/pages');
return json_decode($response->getContent(), true);
}
}
Si je relance une détection des routes, j'ai bien mes deux nouvelles pages dynamiquement créees.
bin/console debug:router
-------------------------- -------- -------- ------ -----------------------------------
Name Method Scheme Host Path
-------------------------- -------- -------- ------ -----------------------------------
_preview_error ANY ANY ANY /_error/{code}.{_format}
_wdt ANY ANY ANY /_wdt/{token}
_profiler_home ANY ANY ANY /_profiler/
_profiler_search ANY ANY ANY /_profiler/search
_profiler_search_bar ANY ANY ANY /_profiler/search_bar
_profiler_phpinfo ANY ANY ANY /_profiler/phpinfo
_profiler_search_results ANY ANY ANY /_profiler/{token}/search/results
_profiler_open_file ANY ANY ANY /_profiler/open
_profiler ANY ANY ANY /_profiler/{token}
_profiler_router ANY ANY ANY /_profiler/{token}/router
_profiler_exception ANY ANY ANY /_profiler/{token}/exception
_profiler_exception_css ANY ANY ANY /_profiler/{token}/exception.css
page_3 ANY ANY ANY /privacy-policy
page_2 ANY ANY ANY /sample-page
-------------------------- -------- -------- ------ -----------------------------------
Faire un Controller qui affichera les pages
Il ne me reste plus qu'à créer le Controller, qui se chargera simplement de transférer les données de l'aAPI à la vue.
<?php
declare(strict_types=1);
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class PageController extends AbstractController
{
public function show(Request $request): Response
{
return $this->render('page.html.twig', $request->get('pageData'));
}
}
Le template de la vue se chargera juste d'afficher le titre de la page et le contenu des pages dans des sections dédiées
{% extends 'base.html.twig' %}
{% block body %}
<h1>{{ title.rendered }}</h1>
<p>{{ content.rendered | raw }}</p>
{% endblock %}
Le résultat
Ensuite, lorsque je vais sur http://localhost:8000/sample-page, j'ai une erreur doctrine, parce que ma base de données n'est pas correctement configurée.
Rien de grave, je modifie le fichier .env
(ou je crée une copie .env.local
et modifie cette dernière) pour me connecter à une base de données.
J'exécute ensuite la commande suivante et tout revient dans l'ordre.
bin/console doctrine:database:create
Une fois la page chargée, le système de cache de sSymfony enregistrera l'url et le contenu dans app/cache
.