Изменение дизайна в Discourse (Часть 2) - Темы

css
discourse
дизайн

(Евгений) #1

Продолжение: Изменение дизайна в Discourse (Часть 1)

Что нам надо, чтобы поменять полностью дизайн на сайте? Давайте рассмотрим, как это можно это сделать за 5 минут.

Например, нам надо такой вид:

  1. Идем по следующему адресу: мой-сайт/admin/customize/themes, выбираем или создаем новую тему и отрываем её. В нашем случае мы хотим добиться изменения в настольком устройстве (ПК). Для этого выбираем соотв. вкладку.

diz-toxu-edit

В моем случае, я использую дизайн - Светлый.

Все последующие изменения будут касаться двух вкладок CSS и </head>

  1. Вставляем приведенный ниже код в эти вкладки, и смотрим, что получилось.

CSS

Код для css
.avahome {
    float: left;
    margin-right: 15px;
    margin-top: 6px;
}

.avahome:hover {
    opacity: 0.7;
}

.topic-list .creator {
    display: block;
    margin-top: 1px;
    font-size: 13px;
}
div.pren, .categ, .otvet {
    display: inline-block;
}
a.pren, .topic-list span.badge-category .category-name {
    color: #919191;
    font-size: 13px;
}
.categ .badge-wrapper.bullet .badge-category-bg {
   display: none;   
}
.tegs {
    display: inline-block;
    float: right;
}
.discourse-tag.simple {
    color: #919191;
    position: relative;
    font-size: 13px;
    padding: 4px 8px;
    background: #f4f4fa;
    font-weight: 300;
    line-height: 1.2em;
    border-radius: 12px;
    cursor: pointer;
    margin-right: 3px;
}
.discourse-tag.simple:hover {
    color: #e45735;
    padding: 4px 8px;
    margin-right: 3px;
}

a.pren:hover, .topic-list span.badge-category .category-name:hover, 
.topic-list .main-link a.title:hover {
    color: #e45735 !important;  
}

/head

Код для /head
<script type='text/x-handlebars' data-template-name='list/topic-list-item.raw'>
<td class='main-link clearfix'>
<div class="avahome">
<a class="pren" href="/users/{{topic.creator.username}}" data-auto-route="true" data-user-card="{{topic.creator.username}}">{{avatar topic.creator imageSize="medium"}}</a> 
</div>
<div class="telohome">
 
 
<div class="title-t">

{{#if bulkSelectEnabled}}
<input type="checkbox" class="bulk-select">
{{/if}}

  {{topic-link topic}} 
  
{{#if topic.featured_link}}
    {{topic-featured-link topic}}
{{/if}}
    
{{#if showTopicPostBadges}}
    {{raw "topic-post-badges" unread=topic.unread newPosts=topic.displayNewPosts unseen=topic.unseen url=topic.lastUnreadUrl}}
{{/if}}
</div>

{{raw "list/topic-excerpt" topic=topic}}

<div class='creator'>
{{~#if topic.creator ~}}  
<span class="blzadalv"><a class="pren" href="/users/{{topic.creator.username}}" data-auto-route="true" data-user-card="{{topic.creator.username}}">
<div class="pren"> {{topic.creator.username}}</div></a> </span>
 
<div class="categ"><span class="no-no">in </span>{{category-link topic.category showParent="true" onlyStripe="true"}}</div>

 
<div class="otvet">

{{#if topic.replyCount}}
<span class="potv">   •  &nbsp; reply</span>
 
<a class="pren" href="/u/{{topic.last_poster_username}}" data-auto-route="true" data-user-card="{{topic.last_poster_username}}">
{{topic.last_poster_username}}</a>
 
{{else}} {{/if}}
</div>
 
<span class="tegs">{{discourse-tags topic mode="list" tagsForUser=tagsForUser}}</span>

{{~/if ~}}

{{raw "list/action-list" topic=topic postNumbers=topic.liked_post_numbers className="likes" icon="heart"}}
  
{{raw "topic-status" topic=topic}}
 
</div>
</div>
</td>


<td class="num likes {{topic.viewsHeat}}">
{{number topic.views numberKey="views_long"}}
</td>
 

{{raw "list/posts-count-column" topic=topic}}

<td class="num">
{{format-date topic.bumpedAt format="tiny"}}
</td>

</script>


<script type='text/x-handlebars' data-template-name='topic-list-header.raw'>

{{raw "topic-list-header-column" order='vopr' name='topic.title'}}

  {{#if showLikes}}
     {{raw "topic-list-header-column" sortable='true' order='likes' number='true' forceName='Likes'}}
  {{/if}}
  {{#if showOpLikes}}
     {{raw "topic-list-header-column" sortable='true' order='op_likes' number='true' forceName='Likes'}}
  {{/if}}
  
  
{{raw "topic-list-header-column" sortable='true' number='true' order='views' forceName='Views'}}
{{raw "topic-list-header-column" sortable='true' number='true' order='posts' status='open' forceName='Replies'}}
{{raw "topic-list-header-column" sortable='true' order='activity' forceName='Last Post'}}
</script>

Все, дизайн готов. Далее мы можем определить его для общего использования или даже сделать “по умолчанию”.

Давайте более детально посмотрим, что было сделано. Это поможет нам понять, как все это далее перенести в плагин если в этом будет необходимость.

CSS компонент я не беру, с этим все понятно. А вот с секцией /head, чуть подробнее.

Изначально мы видим тут 2 конструкции.

Первая:

 <script type='text/x-handlebars' data-template-name='list/topic-list-item.raw'>
 ... тут какой-то код ...
</script>

Вторая:

<script type='text/x-handlebars' data-template-name='topic-list-header.raw'>
... тут какой-то код ...
</script>

Этим мы переопределяем оригинальный код, который находится в следующем месте в ядре сайта:

и

Первый файл, это тело страницы, второй шапка.

Мы можем опираться на оригинальные файлы, чтобы использовать код для вставки у себя через админ интерфейс.

Общий подход такой:

script type='text/x-handlebars' data-template-name='тут имя файла.raw'

Найти файлы можно по пути:

app/assets/javascripts/discourse/templates/

P.S. выше приведенный код (css и head) вы можете использовать как образец для создания своего собственного дизайна. Этот код был составлен за несколько минут, и понятное дело нуждается в корректировке.


(Евгений) #2

Поехали дальше. Мы определили, по какому пути лежат файлы и как делать замену их в админ- интерфейсе. Но что делать, если мы хотим написать плагин и там заменить этот файл?

Давайте рассмотрим файл, который отвечает за вывод страницы Группы.

https://toxu.ru/groups

В Discourse этот файл находится от корня тут:

app/assets/javascripts/discourse/templates/groups/index.hbs

Создадим плагин и размести этот файл по следующему адресу (от корня плагина):

assets/javascripts/discourse/templates/groups/index.hbs

Все. Если файл корректен, то Discourse подхватит его и “заменит”. Меняя содержимое этого файла в своем плагине, мы будем менять и дизайн страницы, за который отвечает данный шаблон.

Однако необходимо учитывать один нюанс.

Мы должны смотреть изменения оригинального файла. Дело в том, что работая с Discourse, команда может что-то добавить или убрать там. И если у вас клонирован этот файл (или другой), то без внесения изменения (в случае перестройки Discourse) могут быть проблемы.

При наличие в файле конструкций вида:

{{plugin-outlet...

Напишу позже. Это дает возможность не менять целиком файлы, что очень подходит, чтобы не учитывать изменения оригинала.


(Герман) #3

Мы можем посмотреть пример, для внесении в “шапку” (header) произвольной иконки.

<script type="text/discourse-plugin" version="0.8">
    api.decorateWidget('header-icons:before', helper => {
        return helper.h('li', [
            helper.h('a#iconAndText.icon', {
                href: 'https://toxu.ru/',
                title: 'Discourse'
            }, [ 
                helper.h('i.fa.fa-home.home-button-icon.d-icon'), 
                helper.h('span', 'Главная')
            ])
        ]);
    });
</script>

Сохраняем, работает.

Возможно кто-то захочет пойти дальше и спросит, а что такое: header-icons?

Ответ ищем в оригинальных файлах платформы.

И смотрим в этом файле еще код ниже.


(Евгений) #4

Еще несколько способов. Если мы хотим изменить шаблон профиля по адресу:

discourse/app/assets/javascripts/discourse/templates/user.hbs

Мы можем конечно взять этот файл поместить его к себе в плагин по адресу:

ПЛАГИН/assets/javascripts/discourse/templates/user.hbs

И если там нет ошибок, то после перестройки плагина платформа будет использовать его. Но тут есть небольшая проблема.

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

Но есть и другой способ. Давайте посмотрим, что содержит этот файл?

В этом файле мы видим конструкции вида:

{{plugin-outlet name="user-profile-controls"  connectorTagName="li" 
args=(hash model=model)}}

и

{{plugin-outlet name="user-post-names" args=(hash model=model)}}

и т.д.

Вот это и можно использовать для внесения изменений.

Подключение к Plugin Outlet

После того, как вы нашли выход плагина , который вы хотите добавить, вы должны написать connector для него.

Например, если ваш шаблон имеет:

{{plugin-outlet name="user-post-names"}}

Тогда любые Handlebars файлы, созданные в connectors/user-post-names каталоге
будут автоматически добавляться. Так что если вы создали файл:

plugins/hello/assets/javascripts/discourse/templates/connectors/user-post-names/hello.hbs

С содержанием:

<b>Hello World</b>

Дискурс вставил бы <b>Hello World</b> в этот момент в шаблоне.

Таким способом мы можем вносить изменения на Github.

Но есть еще один способ. Через админ-интерфейс, секцию

Добавляем:


<script type="text/x-handlebars" data-template-name="/connectors/user-post-names/test">
<div class="tl">В карточку добавляет</div></script>

Получаем:

test-2

По большому счету, мы можем менять дизайн несколькими способами.

  1. Внося изменения внутри контейнера Docer (в сам файл).
  2. Клонируя файл целиком.
  3. Переопределяя весь файл через админ интерфейс.
  4. Вставляя в файл “куски” из шаблона.
  5. Вставляя “куски” через админ- интерфейс.

Это самые простые способы. Кто-то вначале тестирует это дело через админ- интерфейс, и лишь далее создает файл и размещает его на Github. Если конечно вы не используете локальную установку. Что я собственно всем рекомендую.

P.S. Я попробовал лишь пофантазировать по поводу этих изменений. Некоторые просто глупы (но они будут работать). ИМХО, на самом деле необходимо потратить немного времени и изучить локальную установку, и далее многие вопросы снимаются сами.


(Виталий) #5

Мы можем использовать сторонние плагины

Custom Layouts Plugin

Topic List Previews

Плюсы:

  1. Плагины имеют множественные настройки.
  2. Вам ничего не надо делать (только установить плагин).

Минусы:

  1. Вы не контролируете плагин, и он может быть сломан.
  2. Как с любым плагином вы ограничены в выборе вариантов.
  3. Скорость работы сайта возможно уменьшится.

Плагины на GitHub:

  1. GitHub - angusmcleod/discourse-topic-previews
  2. GitHub - angusmcleod/discourse-layouts

Темы на Discourse Meta:

  1. Topic List Previews
  2. Custom Layouts Plugin

(Евгений) #6

Вот еще одни из способов добавлять разные куски, не спец. для стандартного вывода.

Добавляем файл:

PLAGIN/assets/javascripts/discourse/helpers/catid-img.js.es6

Со следующим содержанием:

import { registerUnbound } from 'discourse-common/lib/helpers';

var get = Em.get,
    escapeExpression = Handlebars.Utils.escapeExpression;

export function categoryBadgeHTML(category, opts) {
  opts = opts || {};

  let categoryID = escapeExpression(get(category, 'id'));
  let img = Discourse.Category.findById(categoryID).uploaded_logo.url;
  let categoryName = escapeExpression(get(category, 'name'));
  let url = opts.url ? opts.url : Discourse.getURL("/c/") + Discourse.Category.slugFor(category); 
 
  return `<a class="catid-url" title="${categoryName}" href="${url}"><img src="${img}" alt="${categoryName}" class="catid-logo"></a>`;
}

export function categoryLinkHTML(category, options) {
  var categoryOptions = {};
  return new Handlebars.SafeString(categoryBadgeHTML(category, categoryOptions));
}

registerUnbound('catid-img', categoryLinkHTML);

Добавить данный код в админ- панель для конкретного дизайна:

Toxu-cat

Код:

{{catid-img topic.category}}

Вот и все. Что мы видим?

Добавление иконок раздела на ленты…

Думаю хороший пример, если кто-то решил изменить более “кардинально” дизайн на своем сайте.


(Андрей Белов) #7

В ядро сегодня было добавлено:

Теперь поддерживает добавление, скажем ВКонтакте:

<script type="text/discourse-plugin" version="0.8.23">
  api.addSharingSource({
    id: "vk",
    icon: "vk",
    generateUrl: function(link, title) {
      return "http://vk.com/share.php?url=" + encodeURIComponent(link)  + "&title=" + 
encodeURIComponent(title);
    },
    shouldOpenInPopup: true,
    popupHeight: 265
  })
</script>

Результат:

P.S. На этом сайте мы не пользуемся, в таких случаях, админ- интерфейсом. Мы непосредственно добавляем это в плагин, чтобы изменения коснулись всех вариантов дизайна.