JohnCMS 7.1.0

Тема закрыта
8.01K
.
aNNiMON
Я у себя сейчас экспериментирую с переписыванием всего на контроллеры. Поделюсь мыслями, может натолкну на идею или вы мне подскажите, где можно улучшить.

Значит, в ядре грузится конфиг, создаётся и заполняется DI контейнер со всякими полезными штуками типа pdo и шаблонизатора. Из глобальных переменных доступны только $config и $container. Далее, на странице модуля (к примеру forum/index.php), создаётся объект контроллера, наследуемого от PageController. На нужной странице вызывается соответствующий метод action из этого контроллера (actionSay(), actionShowTopic()). Внутри такого метода происходит обработка и заполнение данных для шаблонизатора. В самом конце вызывается метод renderPage с указанием пути к шаблону и передаётся массив данных. Так выводится полноценная страница.

При этом хэдер и футер обрабатывается в PageController только если был вызван метод renderPage. Всё так же заполняем массив данных и объединяем с тем массивом из action'а, получаем данные, необходимые для вывода всей страницы вместе с хэдером и футером.

Получается так:
class ForumController extends \Core\Controllers\PageController {
    
    public function actionIndex() {
        $this->title = 'Форум'; // эти две переменные нужны только
        $this->module = 'forum'; // для регистрирования перемещений
        // логика
        $this->renderPage('forum/index.twig', [
            'sections' => $sections,
        ]);
    }
}

$controller = new ForumController();
$controller->actionIndex();

Пока что вызов ядра и вот этих action'ов приходится делать вручную. Единую точку входа в корневой index.php придётся потом сделать, когда у каждого модуля будет по одному контроллеру и одной точке входа.

Вот в джон шаблонизатор осталось только ввести и можно будет значительно улучшить архитектуру.
.
# aNNiMON (04.05.2017 / 11:51)
Из глобальных переменных доступны только $config и $container

. Далее, на странице модуля (к примеру forum/index.php), создаётся объект контроллера, наследуемого от PageController. На нужной страни
Достаточно одного $container, а еще лучше глобальных переменных не использовать, обернув инициализацию в какой нить Bootstrap или App::run() с внесением зависимостей.

"actionSay(), actionShowTopic()"
Придирки, но в англицком языке правильнее будет sayAction(), showTopicAction().

"В самом конце вызывается метод renderPage с указанием пути к шаблону и передаётся массив данных"
У этого подхода есть пачка потенциальных проблем, но он вполне рабочий и простой в использовании. Я бы обернул выхлоп контроллера в сервис шаблонизации, который будет отвечать за оборачивание html шапкой и ногами на основании конфигурации. Но ет так, сильно в сторону если уйти.

"Пока что вызов ядра и вот этих action'ов приходится делать вручную."
То есть на каждый Action создается свой класс-контроллер с одним методом?
.
# Delphinum (04.05.2017 / 12:03)
"actionSay(), actionShowTopic()"
Придирки, но в англицком языке правильнее будет sayAction(), showTopicAction().
http://www.yiiframework.com/do ... .html
.
Mi7teR, ну это конечно дело вкуса, но на мой взгляд более верным будет именно sayAction, actionSay как то больше по русским правилам сформировано )
.
Mi7teR
# Delphinum (04.05.2017 / 12:03)
"В самом конце вызывается метод renderPage с указанием пути к шаблону и передаётся массив данных"
У этого подхода есть пачка потенциальных проблем, но он вполне рабочий и простой в использовании. Я б
aNNiMON судя по всему использует твиг, там можно подключить базовый лэйаут
{% extends "base.html" %}

и в котором будет и шапка и футер
.
Mi7teR, ет хорошо, но в отношении джона (о котором тут речь), думаю не подойдет, альк не хочет смартю, твиг и другие, поддерживающие наследование шаблонизаторы
.
обернув инициализацию в какой нить Bootstrap или App::run() с внесением зависимостей
Пока не придумал, как это красиво сделать. Была бы одна точка входа, тогда ладно, передал бы в один единственных базовый контроллер эти данные и всё.

sayAction(), showTopicAction()

Смотрел по популярным фреймворкам, и так и эдак используют. В каком-то вообще без слова action, так и пишут say(), showTopic().

Я бы обернул выхлоп контроллера в сервис шаблонизации
По сути так и есть. В качестве DI контейнера используется Pimple, для вывода страниц шаблонизатор в контейнере расширяется и заполняется данными хэдера и футера:
$container->extend('twig', function ($twig, $c) {
    $data = ($this->headerData() + $this->footerData());
    foreach ($data as $key => $value) {
        $twig->addGlobal($key, $value);
    }
    return $twig;
});


То есть на каждый Action создается свой класс-контроллер с одним методом?

Нет, контроллер один на главной странице модуля, а уже на других страницах вызывается нужное действие. Это для тех страниц, которые не были связаны с index.php от модуля.
Там же некоторые страницы обрабатывались так:
require_once '../incfiles/head.php';
$actions = ['new', 'who', 'adfile', 'file', ...];
if (in_array($act, $actions)) {
    require_once ($act . '.php');
    require_once '../incfiles/end.php';
    exit;
}

а некоторые как самостоятельные страницы были. Вот для них такой подход, чтобы ничего не ломать.
.
(\/)____o_O____(\/)
aNNiMON, жирный контроллер получается, я так понимаю с базы тянет данные прям в нем и отдаёт шаблонизации
можно сказать классический mvc
я бы конечно каждый экшин в отдельный файл бы вынес, сделал бы роутер с конфигом контроллеров и экшинов, чтоб не плодить методы, а добавлять файлы. ну и можно конфигом отключать или менять сам урл
.
# aNNiMON (04.05.2017 / 11:51)
$controller = new ForumController();
$controller->actionIndex();
Пока что вызов ядра и вот этих action'ов приходится делать вручную. Единую точку входа в корневой index.php придётся потом сделать, к
используй роутинг - в зависимости от урл вызывай нужный контроллер и метод.
К примеру урл = http://site.ru/forum/index
Роутер берет из реквеста часть "forum/index"
Потом проверяет доступен ли класс ForumController, в нем уже проверяет наличие метода actionIndex(), далее выполняет его.
.
(\/)____o_O____(\/)
aNNiMON, я у тебя такое видел в ппм имэйдЖ
Всего: 332