This commit is contained in:
Simon Vieille 2021-05-30 20:36:00 +02:00
commit 41455d8e39
17 changed files with 405 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
/site/
/Makefile

2
docs/crud.md Normal file
View file

@ -0,0 +1,2 @@
# Welcome to Murph FR

BIN
docs/img/settings/01.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

BIN
docs/img/settings/02.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

BIN
docs/img/settings/03.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

BIN
docs/img/settings/04.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

BIN
docs/img/tasks/01.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

BIN
docs/img/tasks/02.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

BIN
docs/img/tree/01.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

BIN
docs/img/tree/02.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

11
docs/index.md Normal file
View file

@ -0,0 +1,11 @@
# Welcome to Murph
Muprh is an open-source CMF built on **top of Symfony** that helps you to **build your
own CMS** with several domains and languages. It comes with a fully implemented
and customizable tree manager, a CRUD generator, a 2FA authentication, settings and tasks
managers.
Symfony developers will love build on Murph 💪
End users will be fond of the interface and the powerful tools 💜
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 79.375 79.375"><g stroke-width=".308"><path d="M7.662 0h64.051a7.645 7.645 0 0 1 7.662 7.662v64.051a7.645 7.645 0 0 1-7.662 7.662H7.662A7.645 7.645 0 0 1 0 71.713V7.662A7.645 7.645 0 0 1 7.662 0z" style="marker:none" color="#000" overflow="visible" fill="#1e2430" paint-order="stroke fill markers"/><g style="line-height:125%;-inkscape-font-specification:'Tahoma, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start"><path style="-inkscape-font-specification:'Trebuchet MS'" d="M61.806 63.011h-9.671L46.3 32.691l-11.322 31.05h-3.57L20.089 32.69l-6.064 30.32H4.39L15.713 6.747h5.296l12.166 37.88 11.898-37.88h5.258z" font-weight="700" font-family="Trebuchet MS" aria-label="M" font-size="24.235" letter-spacing="0" word-spacing="0" fill="#fc0" stroke-width=".082"/></g><path d="M77.107 2.214L2.212 77.107a7.638 7.638 0 0 0 5.45 2.268h64.052a7.644 7.644 0 0 0 7.661-7.661V7.663a7.637 7.637 0 0 0-2.268-5.449z" style="marker:none" color="#000" overflow="visible" fill="#19b4db" paint-order="stroke fill markers"/><path d="M52.23 16.059L37.533 30.756l-4.357 13.872-2.313-7.202-6.63 6.63 7.178 19.685h3.568l11.323-31.048 5.833 30.319h9.672zM16.211 52.076L5.275 63.012h8.75z" style="line-height:125%;-inkscape-font-specification:'Trebuchet MS';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start" font-weight="700" font-size="24.235" font-family="Trebuchet MS" letter-spacing="0" word-spacing="0" fill="#1e2430" stroke="#1e2430" stroke-width=".26594568"/></g></svg>

44
docs/install.md Normal file
View file

@ -0,0 +1,44 @@
# Installation
## Technical Requirements
* Install PHP 7.3 or higher and these PHP extensions (which are installed and enabled by default in most PHP 7 installations): Ctype, iconv, JSON, PCRE, Session, SimpleXML, and Tokenizer;
* [Install Composer](https://getcomposer.org/download/), which is used to install PHP packages.
* [Install NodeJS](https://nodejs.org/en/download/) 12 or higher, [Yarn](https://classic.yarnpkg.com/en/docs/install/#debian-stable) and [Webpack](https://webpack.js.org/guides/installation/)
* A created database (MySQL, PostgreSQL or SQLite)
* build-essential to run `make`
## Setting up the skeleton
Depending of you environment, PHP and composer could be located in specific paths.
Defines theme with environment vars:
```
export PHP=/path/to/php
export COMPOSER=/path/to/composer
```
Create your project:
```
composer create-project murph/murph-skeleton my_project -s dev
```
An error occured because of the unconfigured database.
* Copy `.env` into `.env.local`
* Edit `.env.local` ([documentation](https://symfony.com/doc/current/configuration.html#configuring-environment-variables-in-env-files))
* Run `php bin/doctrine-migrate` (or `make doctrine-migrate`)
And finally, build assets with `make asset`.
## Create an admin user
Run `php bin/console murph:user:create` and answer questions.
## Configure a web server
Read the documentation of Symfony to [configure a web server](https://symfony.com/doc/current/setup/web_server_configuration.html).
In case of a local server, you can use the [Symfony Local Web Server](https://symfony.com/doc/current/setup/symfony_server.html).
Then go to [https://127.0.0.1:8000/admin](https://127.0.0.1:8000/admin).

259
docs/settings.md Normal file
View file

@ -0,0 +1,259 @@
# Settings
## Global settings
![](/img/settings/02.png)
### Create settings
The creation of settings is based on events.
Using an event subscriber, you can create settings and define how to edit them.
A setting's value is stored in json so a value could be a string, a boolean, an array, etc.
See the example below.
```
// src/EventSuscriber/SettingEventSubscriber.php
namespace App\EventSuscriber;
use App\Core\Event\Setting\SettingEvent;
use App\Core\EventSuscriber\SettingEventSubscriber as EventSubscriber;
use App\Core\Setting\SettingManager;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ColorType;
class SettingEventSubscriber extends EventSubscriber
{
protected SettingManager $manager;
public function __construct(SettingManager $manager)
{
$this->manager = $manager;
}
public function onInit(SettingEvent $event)
{
$this->manager->init('app_font_color', 'Font color', 'Design', '#fff');
$this->manager->init('app_background_color', 'Background color', 'Design', '#333');
$this->manager->init('app_maintenance_enabled', 'Maintenance', 'System', false);
}
public function onFormInit(SettingEvent $event)
{
$data = $event->getData();
$builder = $data['builder'];
$entity = $data['entity'];
if (in_array($entity->getCode(), ['app_font_color', 'app_background_color'])) {
$builder->add(
'value',
ColorType::class,
[
'label' => $entity->getLabel(),
]
);
}
if (in_array($entity->getCode(), ['app_maintenance_enabled'])) {
$builder->add(
'value',
CheckboxType::class,
[
'label' => $entity->getLabel(),
]
);
}
}
}
```
### Access settings
Settings are accessible using `App\Core\Setting\SettingManager` which is a service.
```
// src/Controller/FooController.php
namespace App\Controller;
use App\Core\Setting\SettingManager;
use Symfony\Component\HttpFoundation\Response;
class FooController
{
public function foo(SettingManager $settingManager): Response
{
$fontColor = $settingManager->get('app_font_color');
$backgroundColor = $settingManager->get('app_background_color');
$maintenanceEnabled = $settingManager->get('app_maintenance_enabled');
// ...
}
}
```
In a template, you can use the function `setting`:
```
Font color: {{ setting('app_font_color') }}<br>
Background color: {{ setting('app_background_color') }}<br>
Maintenance enabled: {{ setting('app_maintenance_enabled') ? 'Yes' : 'No' }}<br>
```
### Update settings
Settings are accessible using `App\Core\Setting\SettingManager` which is a service.
```
// src/Controller/FooController.php
namespace App\Controller;
use App\Core\Setting\SettingManager;
use Symfony\Component\HttpFoundation\Response;
class FooController
{
public function foo(SettingManager $settingManager): Response
{
$settingManager->set('app_font_color', '#f00');
$settingManager->set('app_background_color', '#00f');
$settingManager->set('app_maintenance_enabled', true);
// ...
}
}
```
You can also edit them from UI:
![](/img/settings/01.png)
## Navigation settings
![](/img/settings/03.png)
### Create settings
The creation of settings is based on events.
Using an event subscriber, you can create settings and define how to edit them.
A setting's value is stored in json so a value could be a string, a boolean, an array, etc.
See the example below.
```
// src/EventSuscriber/NavigationSettingEventSubscriber.php
namespace App\EventSuscriber;
use App\Core\Event\Setting\NavigationSettingEvent;
use App\Core\EventSuscriber\NavigationSettingEventSubscriber as EventSubscriber;
use App\Core\Setting\NavigationSettingManager;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
class NavigationSettingEventSubscriber extends EventSubscriber
{
protected NavigationSettingManager $manager;
public function __construct(NavigationSettingManager $manager)
{
$this->manager = $manager;
}
public function onInit(NavigationSettingEvent $event)
{
$data = $event->getData();
$navigation = $data['navigation'];
$this->manager->init($navigation, 'nav_tracker_code', 'Stats', 'Tracker', '');
$this->manager->init($navigation, 'nav_contact_email', 'Contact', 'Email', 'foo@example.com');
}
public function onFormInit(NavigationSettingEvent $event)
{
$data = $event->getData();
$builder = $data['builder'];
$entity = $data['entity'];
if (in_array($entity->getCode(), ['nav_tracker_code'])) {
$builder->add(
'value',
TextType::class,
[
'label' => $entity->getLabel(),
]
);
}
if (in_array($entity->getCode(), ['nav_contact_email'])) {
$builder->add(
'value',
EmailType::class,
[
'label' => $entity->getLabel(),
]
);
}
}
}
```
### Access settings
Settings are accessible using `App\Core\Setting\NavigationSettingManager` which is a service.
```
// src/Controller/FooController.php
namespace App\Controller;
use App\Core\Setting\NavigationSettingManager;
use App\Core\Site\SiteRequest;
use Symfony\Component\HttpFoundation\Response;
class FooController
{
public function foo(NavigationSettingManager $settingManager, SiteRequest $siteRequest): Response
{
$trackerCode = $settingManager->get($siteRequest->getNavigation(), 'nav_tracker_code');
$contactEmail = $settingManager->get($siteRequest->getNavigation(), 'nav_contact_email');
// ...
}
}
```
In a template, you can use the function `navigation_setting`:
```
Tracker code: {{ navigation_setting(_navigation, 'nav_tracker_code') }}<br>
Contact email: {{ navigation_setting('my_nav', 'nav_contact_email') }}<br>
```
### Update settings
Settings are accessible using `App\Core\Setting\NavigationSettingManager` which is a service.
```
// src/Controller/FooController.php
namespace App\Controller;
use App\Core\Setting\NavigationSettingManager;
use App\Core\Site\SiteRequest;
use Symfony\Component\HttpFoundation\Response;
class FooController
{
public function foo(NavigationSettingManager $settingManager, SiteRequest $siteRequest): Response
{
$settingManager->set($siteRequest->getNavigation(), 'nav_tracker_code', '...');
$settingManager->set('my_nav', 'nav_contact_email', '...');
// ...
}
}
```
You can also edit them from UI:
![](/img/settings/04.png)

37
docs/tasks.md Normal file
View file

@ -0,0 +1,37 @@
# Tasks
![](/img/tasks/01.png)
Tasks are executable from UI. The creation of tasks is based on events.
```
// src/EventSuscriber/MyTaskEventSubscriber.php
namespace App\EventSuscriber;
use App\Core\Event\Task\TaskInitEvent;
use App\Core\Event\Task\TaskRunRequestedEvent;
use App\Core\EventSuscriber\Task\TaskEventSubscriber;
class MyTaskEventSubscriber extends TaskEventSubscriber
{
public function onInit(TaskInitEvent $event)
{
$event->addTask('my_task', 'Example', 'My task');
}
public function onRunRequest(TaskRunRequestedEvent $event)
{
if ('my_task' !== $event->getTask()) {
return;
}
$event->getOutput()->writeln('My task is started');
// ...
$event->getOutput()->writeln('My task is finished');
}
}
```
![](/img/tasks/02.png)

38
docs/tree.md Normal file
View file

@ -0,0 +1,38 @@
# Tree manager
Murph manages contents this way:
* You define navigations
* For each navigation, you define menus
* For each menu, you define elements (nodes)
* and for each element, you define:
- an optional page
- the routing
- some attributes
- a sitemap configuration
## Navigation
To create a navigation, go to `Navigations` and click on `New`. Then fill the form and save.
* The `label` is the label displayed whenever necessary (eg: `Example`)
* The `locale` is the language used in the content (eg: `en`)
* The `code` is a unique technical identifier useful in templating, routing and settings (eg: `example_en`)
* The `domain` defines the main domain used to access the navigation (eg: `example.com`)
* `Additional domains` are additional domains used to access the navigation (eg: `www.example.com`). You can specify regular expression to match all that you want
If several navigations share the same domain, then the locale will by used to prefix routes.
But if a navigation uses a single domain then the local will not prefix routes.
![](/img/tree/01.png)
## Menu
To create a menu, go to `Trees`, select the navigation and click on `Add a menu`. Then fill the form and save.
* The `label` is the label displayed whenever necessary (eg: `Top menu`)
* The `code` is an unique technical identifier (in the given navigation) and it is useful in templating, routing and settings (eg: `top`)
When a menu is created then an element is automatically generated.
![](/img/tree/02.png)

2
docs/users.md Normal file
View file

@ -0,0 +1,2 @@
# Welcome to Murph FR

10
mkdocs.yml Normal file
View file

@ -0,0 +1,10 @@
site_name: Murph documentation
theme: readthedocs
nav:
- Overview: index.md
- Installation: install.md
- Tree manager: tree.md
- CRUD: crud.md
- Settings: settings.md
- Users: users.md
- Tasks: tasks.md