Как из любого ЭКШЕНА получить данные в любой ШАБЛОН?

InstantCMS 2.X
#1 10 декабря 2024 в 15:16

Не могу никак разобраться... 
Сделал тестовый экшен
content/actions/subcats_view.php

  1. <?php
  2. class actionContentSubcatsView extends cmsAction {
  3.  
  4. public function run() {
  5.  
  6. return $this->cms_template->renderJSON([
  7.  
  8. 'test' => 'Ok Ok Ok'
  9.  
  10. ]);
  11. }
  12. }

Далее написал пустой тестовый виджет, в шаблоне которого

  1. <script>
  2. ;(async function(){
  3. let resp = await fetch('/content/subcats_view');
  4. let json = await resp.json();
  5. console.log(json.test);
  6. }());
  7. </script>

В консоли как и полагается выводится 'Ok Ok Ok'. Работает.
Данные можно отрендерить JS-ом и вывести где-то на странице.

Теперь вопрос.

Как мне запросить и получить данные того же экшена, но без JS?
То есть может есть метод, который сможет вернуть данные экшена прямо в шаблон (например в шаблон любого виджета), чтобы отрендерить с помощью php?

Очень буду признателен за совет.

#2 10 декабря 2024 в 15:30

Если я правильно понял, то вроде вот:

  1. return $this->cms_template->render('шаблон_из_папки_тэмплэйт', [
  2. 'test' => 'Ok Ok Ok'
  3. ]);

и в шаблоне будет доступно $test

#3 10 декабря 2024 в 16:19

 Andrew Lutz, экшн может вызвать только контроллер, поэтому примерно так 

  1. $controller = cmsCore::getController('content');
  2. dump($controller->runAction('subcats_view'));

Этим методом github.com/instantsoft/icms2/blob/1bc44cd4bc7e31ea501646b9121b9a0810ca9c57/system/core/controller.php#L444

Но имхо так делать не стоит. Сделайте отдельный компонент, в нем нужный метод для отдачи данных массива 

  1. public function returnSubcats() {
  2. return [
  3. 'test' => 'Ok Ok Ok'
  4. ];
  5. }

и уже в виджете получите эти категории примерно так

  1. $controller = cmsCore::getController('ваш_контроллер');
  2. dump($controller->returnSubcats());

минуя рендер в шаблон

О том как устроены контроллеры в движке можно посмотреть в документации docs.instantcms.ru/dev/controllers

#4 10 декабря 2024 в 17:20

Если я правильно понял, то вроде вот:

  1. return $this->cms_template->render('шаблон_из_папки_тэмплэйт', [
  2. 'test' => 'Ok Ok Ok'
  3. ]);

и в шаблоне будет доступно $test

maxxux

Да, если создать в папке шаблона файл например /content/get_action.tpl.php то можно вывести в нем  $test.
Но как это сделать в шаблоне виджета? или это надо как-то сделать потом уже?
Я смотрел на примере стандартного файла category_view.tpl.php в папке контроллера content. В него тоже данные попадают из одноименного экшена.
Вот только как они потом передаются в общий виджет /content/widget/template.tpl.php — для меня загадка.

Добавлено спустя 8 минут
  1. $controller = cmsCore::getController('content');
  2. dump($controller->runAction('subcats_view'));

Действительно работает! это даже радует )
Только теперь не понятны предостережения — «имхо так делать не стоит. Сделайте отдельный компонент, в нем нужный метод для отдачи данных массива ». Это действительно важно?
А то в будущем фантазирую движок превратить в подобие SPA. Для этого думаю всю логику можно переваривать в экшенах, отдавая чистый JSON либо внутрь, либо аяксу. В зависимости кому нужно отдать страницу — пользователю или поисковику.

Zau4man
#5 10 декабря 2024 в 17:40

 Andrew Lutz, так экшн, по факту, такой же метод контроллер. Вам необязательно его выносить в отдельный файл, можно прямо внутри контроллера писать его как 

  1. public function actionSubcatsView(){
  2. dump('Список категорий');
  3. }

Вот про это в документации docs.instantcms.ru/dev/controllers/actions

Просто вы же в виджете хотите потом эту json строку разбирать, подготавливать и отправлять в шаблон виджета.

Вынесите подготовку чистых данных в сам контроллер. В виджет отдавайте чистые данные, а экшном — в формате json… Кода в сравнении с вашим вариантом почти не добавится, зато поддерживать такой вариант в дальнейшем будет сильно проще.

Но я не настаиваю. Просто делюсь мнением.

#6 10 декабря 2024 в 17:48

 Andrew Lutz, так экшн, по факту, такой же метод контроллер. Вам необязательно его выносить в отдельный файл, можно прямо внутри контроллера писать его как 

  1. public function actionSubcatsView(){
  2. dump('Список категорий');
  3. }

Вот про это в документации docs.instantcms.ru/dev/controllers/actions

Просто вы же в виджете хотите потом эту json строку разбирать, подготавливать и отправлять в шаблон виджета.

Вынесите подготовку чистых данных в сам контроллер. В виджет отдавайте чистые данные, а экшном — в формате json… Кода в сравнении с вашим вариантом почти не добавится, зато поддерживать такой вариант в дальнейшем будет сильно проще.

Но я не настаиваю. Просто делюсь мнением.

Zau4man

Хм… а ведь да, точно )
Благодарю за мудрый совет )
Мне еще многому тут учиться.

Вы не можете отвечать в этой теме.
Войдите или зарегистрируйтесь, чтобы писать на форуме.
Используя этот сайт, вы соглашаетесь с тем, что мы используем файлы cookie.