Вообще, кеш смарти-шаблонов должен сбрасываться при общем сбросе сайта из админки, то есть стандартная кнопка в админке есть Управление -> Очистить кеш или горячими клавишами в админке Ctrl+Shift+U. На это плагин навешен соответствующий. В крайнем случае попробуйте жесткий метод - удалить папки cache и compiled в компоненте http://joxi.ru/v29OdyEiZONNRr. Жестче нет сброса. Если не поможет, то скорее всего это уже вопрос кеширования на уровне MODX. Вполне кто-нибудь мог собственную логику кеширования прописать.
Привет. Внес правки в шаблон smarty, но правки отображаются только под админом. Как скинуть кеш всех шаблонов?
Всем привет! В продолжение прошлого комментария публикую статью как добавлять свои собственные компоненты во фронт-редактор. Сразу скажу, что материал не будет особо сложным, если вы уже боле менее знакомы с react и graphql (хотя второе здесь скорее всего и не обязательно в понимании). Как развернуть у себя сайт на призме, подробно написано здесь, так что описание процесса установки я пропущу и сразу перейду к процессу кастомизации фронт-редактора, рассчитывая, что у вас уже сайт развернут. Далее открываем файл /src/components/Renderer/pages/Root/index.js. В нем на сегодня уже прописано 3 кастомных компонента, вот на них вы и можете ориентироваться в качестве примеров. Как наиболее простой, мы рассмотрим /src/components/Renderer/pages/Root/components/pages/Users/User/index.js. Разберем его подробней. static Name = "UserPage" Это очень важный момент: я изначально заложил декларативный подход в определении компонентов, чтобы их можно было переопределять, и определение их происходит именно по этому свойству. То есть можно посмотреть имеющиеся базовые компоненты в @prisma-cms/front-editor, в каждом компоненте прописан свой static Name. И если у вас уже есть оформленные шаблоны на базовых компонентах и в какой-то момент вы захотите какие-то из них переопределить, то вам достаточно просто знать их имя и добавить свой компонент с таким именем в CustomComponents. После этого вам с шаблонами делать ничего не надо будет, они будут рендериться уже с вашим компонентом вместо базового. renderPanelView() Это оформление кнопки в панели компонентов. Здесь можно как угодно переоформить кнопку, можно вообще что угодно вывести (включая подробное описание и т.п.). Только обязательно рендерьте через super.renderPanelView(), потому что там навешиваются события клика и т.п. Вообще здесь сразу имеет смысл упомянуть и метод renderSettingsView(), хоть его в примере и нет. Этот блок рендерится, когда вы выделяете какой-либо элемент в редакторе (там выводятся всякие параметры элемента и т.п.). Очень удобно, если вы захотите добавить какой-то кастомный вывод настроек для активного элемента. renderChildren() Выводит дочерние компоненты элемента на странице, то есть те, которые вы так же закидываете в режиме редактирования шаблона. В приведенном примере super.renderChildren() не вызывается, соответственно и дочерние компоненты накиданные выводиться не будут, даже если они есть. Здесь пара важных замечаний по поводу передаваемых параметров при рендеринге компонента: 1. Это отрендеренный родительский компонент. именно инстанс объекта, а не просто параметры. В данном случае я рассчитываю на то, что родительский элемент является роутером и передает условие с идентификатором запрошенного пользователя. Полный код: 2. Свойства самого компонента при рендеринге. Не знаю как долго будет использоваться этот костыль, но пока что по-другому просто не получилось. Чтобы получить не только входящие свойства компонента, передаваемые из родителя, но и те, что прописаны в настройках самого компонента, сохраняемых в базу данных, надо использовать не this.props, а this.getComponentProps(this), обязательно с передачей текущего инстанса this. Это сделано в том числе и для того, чтобы в панели настроек выводить параметры конкретного инстанса компонента, ведь исходный компонент один (к примеру, TextField), а инстансов на странице может быть несколько, и вот когда мы на странице кликаем конкретный элемент, то при рендеринге панели настроек мы должны получить входящие конкретного инстанса (тогда там передается не this, а activeItem, получаемый из this.getEditorContext()). Этот момент довольно запутанный, но сейчас можно и не разбираться особо, оставив до конкретного случая, если столкнетесь. В принципе, я думаю необходимый минимум я передал. Просто попробуйте сами и наверняка станет более понятно. В принципе, если вам более привычно писать в самостоятельных компонентах все, вы можете задать свои кастомные компоненты, разместить их на странице в нужных местах и забыть про фронт-редактор, программируя свои компоненты. Но лично я считаю, что фронт-редактор решает не мало проблем. Для примера вспомните, как происходит редактирование шаблонов в большинстве случаев: клиент говорит "мне надо на странице вот это изменить, сделайте, плиз". Программист идет в программный код, ищет шаблоны, чанки, сниппеты и т.п., пытается понять откуда что берется и т.п. В случае же использования фронт-редактора, вы сразу видите где что откуда берется и что надо подправить, чтобы изменить шаблонизацию. Так что я буду дальше развивать это направление.
Павел, для этого можно тогда просто свой фронт использовать, ведь здесь сервер и фронт живут своей жизнью. Но если хочется именно использовать призму, то вероятно наилучший способ - это использовать @prisma-cms/boilerplate и изменить метод renderWrapper(), прописав свою логику. Так будет и полностью свое оформление, и унаследована основная логика и контексты. Напомню, что @prisma-cms/boilerplate изначально планировалась как заготовка, используемая для старта проекта и дальнейшего его самостоятельного развития, так что в ней по идее можно делать что хочется. Но вообще, отказываться от фронт-редактора не стоит. На самом деле ты скорее всего пока не понял его основных фишек (в принципе, я их еще особо не раскрывал). Фронтовый редактор при правильном подходе должен решить ряд очень важных задач и быть в целом полезным. Но я согласен, что в нынешнем виде он не совсем удобен и проще писать свой код привычным способом. Но этот недостаток решается добавлением своих собственных компонентов в него (расширение списка используемых в нем модуле). Я сейчас напишу статейку про это.
Фактически, это что-то похожее на одноимённый компонент из React Native. То есть, он тоже выполняет ту же функцию вывода массива объектов. Николай, у меня вопрос по шаблонизации. Как-то можно шаблонизировать сайт на Призме не используя визуальный редактор шаблонов, а в идеале вообще отключив его? Об этом есть (будет) статья?
Всем привет! Сегодня я расскажу про еще несколько новых компонентов, а именно EditableObject и связанные с ним EditableView, DefaultView и TextField. EditableObject нужен для того, чтобы можно было создавать новые записи и редактировать существующие. Поясню: раньше front-editor был практически полностью "только на чтение", то есть можно было сформировать запросы и вывести полученные данные, но это касалось только существующих данных (пользователей, топиков и т.п.), но создавать новые или редактировать существующие было нельзя. Теперь же с новыми компонентами можно и создавать новые записи и редактировать существующие. Вот я записал довольно подробный видеоролик на 30+ минут: https://youtu.be/HDBLMVvbJmo (сорри, что он без озвучки, но в целом должно быть понятно что к чему). В нем подробно продемонстрировано не только создание/редактирование объектов, но и создание отдельного раздела сайта со своими УРЛами. Итак, основной принцип действия. В интерфейсах записи (объекты) могут находиться в двух состояниях: в режиме редактирования (Editable) и в обычном состоянии (Default). Вполне логично, что в этих двух состояниях интерфейсы могут отличаться (в режиме редактирования могут просто быть перечислены текстовые и прочие редактируемые поля, обновляющие те или иные свойства объекта), а в обычном состоянии у нас может быть индивидуально оформленный интерфейс. Вот для управления этими состояниями (и еще ряда сопутствующих задач) и служит EditableObject. Вообще этот компонент фронт-редактора выводит довольно старый и полезный компонент EditableView и бОльшая часть логики идет именно оттуда, поэтому если вы заходите больее подробно изучить функционал изнутри, смотреть надо будет именно его. И именно он используется практически во всех активных интерфейсах сайта, включая редактор топиков, форму авторизации, страницу профиля и т.д. и т.п. Если пользователю доступно редактирование объекта, появляется кнопка с иконкой карандашика. При клике по этой кнопке объект переходит из состояния Default в состояние Editable. Это очень важный момент, чтобы понимать как этот компонент оформляется. EditableObject при выводе прямых потомков руководствуется следующими правилами: - В режиме Default выводит всех потомков, кроме класса EditableView. - В режиме Editable выводит всех потомков, кроме класса DefaultView. - Классы Query использует для формирования API-запросов (можно добавить сразу два Query-объекта (create и update)). - Все остальные компоненты выводятся как есть в обоих состояниях. То есть классическая структура следующая: - EditableObject -- Query create -- Query update -- other components -- DefaultView -- EditableView -- other components Если объект изменен и есть что сохранять, то будет гореть красная кнопка "Сохранить". При клике по ней произойдет следующее: если есть объект и у него есть значение id, то считается, что объект уже существующий и надо отправить запрос на обновление его (update), иначе запрос будет на создание его (create). Откуда берутся эти create/update запросы? Они берутся из прямых потомков класса Query. Вот запрос на создание, используемый в примере: А вот запрос на обновление: Здесь есть три важных правила: 1. create/update запросы должны быть именно processor-based, чтобы они возвращали поля success, message и т.п. Просто create/update запрос тоже выполнится, но не будет тогда подсветки ошибок по отдельным полям, автоматического редиректа на заданный УРЛ при создании объекта и т.п. 2. Обязательно надо задавать имя запроса, то есть mutation create или mutation update. При попытке сохранить объект компонент EditableObject в запросах Query ищет именно по этому имени, и если не найдет, то запроса реального не будет. Вот здесь вот как раз есть эпизод, когда я забыл прописать запрос и что при этом происходило: https://youtu.be/HDBLMVvbJmo?t=1181 3. В запросе надо обязательно прописывать псевдоним response, иначе запрос будет выполняться и сохраняться все будет, но часть логики сломается, потому что компонент пытается в ответе найти объект response, а если не прописать алиас, то этого объекта не будет и компонент не сможет проверить полную успешность выполнения запроса, ошибки проверки полей и т.п. Ну вроде все основное описал. Если возникнут вопросы, спрашивайте. И обязательно изучите шаблоны в примере: https://front-editor.prisma-cms.com/components-demo/tests
Всем привет! Сегодня представляю экспериментальный компонент - Language Router, предназначенный для реализации мультиязычности на сайте. Вообще сама по себе реализация мультиязычности - очень сложная и неоднозначная штука, поэтому взять какую-то общепринятую практику или придумать что-то максимально универсальное здесь изначально мне не казалось реальной задачей, поэтому данный компонент изначально под большим вопросом. Тем не менее потребность в нем есть и мне хотелось его реализовать без каких-то отдельных языковых справочников, а именно в рамках уже намеченного визуального редактора, то есть по принципу "Где вижу, там и редактирую". Скажу честно, что над этой задачей, прежде чем приступить, я думал больше месяца (и до этого не раз задумывался). Мне хотелось, чтобы как-то все универсально было и удобно, и чтобы не ломать намеченной основы и поиск работал и т.д. и т.п., и признаться честно, я не смог придумать универсального решения, поэтому вычленил самое важное - редактировать где видишь, а вот SEO и т.п. придется пока игнорировать. В общем, это решение подходит для лендингов и т.п., где основной только один сайт и язык основной один, а дополнительные языки - это просто для удобства пользователей, но у них пока не будет отдельных УРЛов и т.п, то есть можно переключиться на другой язык, но УРЛ не поменяется, то есть поисковые машины не будут довольны. Тем не менее, для сайтов, продвигаемых только через рекламу, данный подход вполне годится, а мысли у меня кое-какие есть, и в дальнейшем скорее всего я и с УРЛами решу вопрос. Итак, как это работает? В нужном месте страницы, где надо менять вывод в зависимости от языка, размещаем компонент Language Router, а в него закидываем нужные для вывода компоненты и в его прямых потомках в настройках указываем для какого они языка (ru или en). Если у компонента не указывается какой язык, то он будет выводиться во всех языках. Language Router при выводе дочерних компонентов первого уровня фильтрует их по языку. Вот смотрите видео: https://youtu.be/WHkbPL6j8Ho. Вот демо-шаблон: https://front-editor.prisma-cms.com/templates/cjw2wn6wzi73v0a89cqsx6kin Важный момент: если в редакторе выделен Language Router или какой-либо из его прямых потомков, то выводятся все языковые потомки разом независимо от их указанного языка. Это сделано для удобства, чтобы в режиме редактирования было видно какие языковые элементы прописаны. Подсказка: Для локализации множества коротких текстовых элементов (например, пунктов меню) лучше использовать структуру Typography -> Language Router -> [HTML Tag1, HTML Tag2, ....], потому что в HTML Tag нельзя разместить никакой другой компонент, кроме как HTML Tag, а в Typography есть базовые стилистические наборы типа title, subheading, caption и т.п. Отдельно уточню, что для этого компонента дочерними могут быть любые другие компоненты, хоть Query, хоть Slider, хоть что.