init
2
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
/site/
|
||||
/Makefile
|
||||
2
docs/crud.md
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
# Welcome to Murph FR
|
||||
|
||||
BIN
docs/img/settings/01.png
Normal file
|
After Width: | Height: | Size: 53 KiB |
BIN
docs/img/settings/02.png
Normal file
|
After Width: | Height: | Size: 61 KiB |
BIN
docs/img/settings/03.png
Normal file
|
After Width: | Height: | Size: 74 KiB |
BIN
docs/img/settings/04.png
Normal file
|
After Width: | Height: | Size: 68 KiB |
BIN
docs/img/tasks/01.png
Normal file
|
After Width: | Height: | Size: 56 KiB |
BIN
docs/img/tasks/02.png
Normal file
|
After Width: | Height: | Size: 52 KiB |
BIN
docs/img/tree/01.png
Normal file
|
After Width: | Height: | Size: 66 KiB |
BIN
docs/img/tree/02.png
Normal file
|
After Width: | Height: | Size: 58 KiB |
11
docs/index.md
Normal 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
|
|
@ -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
|
|
@ -0,0 +1,259 @@
|
|||
# Settings
|
||||
|
||||
## Global settings
|
||||
|
||||

|
||||
|
||||
### 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:
|
||||
|
||||

|
||||
|
||||
|
||||
## Navigation settings
|
||||
|
||||

|
||||
|
||||
### 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:
|
||||
|
||||

|
||||
37
docs/tasks.md
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
# Tasks
|
||||
|
||||

|
||||
|
||||
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');
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||

|
||||
38
docs/tree.md
Normal 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.
|
||||
|
||||

|
||||
|
||||
## 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.
|
||||
|
||||

|
||||
2
docs/users.md
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
# Welcome to Murph FR
|
||||
|
||||
10
mkdocs.yml
Normal 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
|
||||