Добро пожаловать на сайт SEDBY

С чего начать создание темы Cotonti

Популярные запросы: тема Omnis, плагин Pagelist, Cotonti 0.9.24.2, ЧПУ, Font Face

  • 523 просмотра
  • 20 января, 2023
  • Обновлено: 16 октября, 2023
  • admin
  • Время чтения: 11 минут

После того, как вы развернули на удаленном или локальном сервере дистрибутив Cotonti, необходимо создать новую тему оформления. В эпоху Seditio ее называли скин (skin).

Как правило, тема для Котонти создается "с нуля". Для этого необходимо использовать коробочную тему Nemesis и произвести над ней некоторые действия, чтобы уникализировать ее и добавить немного необходимого функционала. Если в дальнейшем планируется разработка новых тем, рекомендую сохранить созданный каркас, например, на Github для того, чтобы дальнейшие процедуры клонирования занимали меньше времени и усилий.

Копирование и переименование

Откроем папку /themes. Здесь находятся две темы: Nemesis и Sumisun. Последнюю сразу удаляем -- это модельная тема давно не обновлялась и уже потеряла свою актуальность. Работать мы будем с темой Nemesis.

Прежде всего, придумаем название новой темы и соответствующим образом переименуем папку. Например, nemesis -> kudos. Аналогичным образом поступим с четырьмя "именными" файлами в папке:

  • nemesis.php -> kudos.php
  • nemesis.en.lang.php -> kudos.en.lang.php
  • nemesis.rc.php -> kudos.rc.php
  • nemesis.ru.lang.php -> kudos.ru.lang.php

Откроем файл kudos.php и отредактируем "шапку":

PHP
1
2
3
4
5
6
7
/* ====================
[BEGIN_COT_THEME]
Name=Kudos
Version=1.00b
Schemes=default:Default
[END_COT_THEME]
==================== */

Аналогичным образом поступим с файлами локализаций:

PHP
1
2
3
4
5
6
7
/**
 * User English Language File for Kudos theme
 *
 * @package Cotonti
 * @copyright (c) Cotonti Team
 * @license https://github.com/Cotonti/Cotonti/blob/master/License.txt
 */

и

1
2
3
4
5
6
7
/**
 * User Russian Language File for Kudos theme
 *
 * @package Cotonti
 * @copyright (c) Cotonti Team
 * @license https://github.com/Cotonti/Cotonti/blob/master/License.txt
 */

Также исправим header файла-загрузчика:

PHP
1
2
3
4
5
6
7
/**
 * JavaScript and CSS loader for Kudos theme
 *
 * @package Cotonti
 * @copyright (c) Cotonti Team
 * @license https://github.com/Cotonti/Cotonti/blob/master/License.txt
 */

Редактирование основных файлов

Очистим основные файлы для дальнейшей работы с ними. В первую очередь нас интересуют файлы TPL-шаблонов.

Правка файлов-шаблонов

Откроем header.tpl и удалим верстку ниже открывающего тега body. Тег HEADER_META_KEYWORDS нам тоже уже не понадобится. В итоге получим:

XML/XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<!-- BEGIN: HEADER -->
<!DOCTYPE html>
<html lang="{PHP.cfg.defaultlang}">
<head>
<title>{HEADER_TITLE}</title>
<!-- IF {HEADER_META_DESCRIPTION} -->
<meta name="description" content="{HEADER_META_DESCRIPTION}" />
<!-- ENDIF -->
<!-- IF {HEADER_META_KEYWORDS} -->
<meta name="keywords" content="{HEADER_META_KEYWORDS}" />
<!-- ENDIF -->
<meta http-equiv="content-type" content="{HEADER_META_CONTENTTYPE}; charset=UTF-8" />
<meta name="generator" content="Cotonti https://www.cotonti.com" />
<link rel="canonical" href="{HEADER_CANONICAL_URL}" />
{HEADER_BASEHREF}
{HEADER_HEAD}
<link rel="shortcut icon" href="favicon.ico" />
<link rel="apple-touch-icon" href="apple-touch-icon.png" />
</head>
 
<body>
 
  <header class="py-3 bg-secondary-subtle">
    <div class="container">
      <div class="row">
        <div class="col">
          <p class="text-center mb-0">
            This is header <a href="{PHP.cfg.mainurl}">Back Home</a>
          </p>
        </div>
      </div>
    </div>
  </header>
 
<!-- END: HEADER -->

Так же поступим с шаблоном footer.tpl:

XML/XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!-- BEGIN: FOOTER -->
 
  <footer class="py-3 bg-secondary-subtle">
    <div class="container">
      <div class="row">
        <div class="col">
          <p class="text-center mb-0">
            This is footer
          </p>
        </div>
      </div>
    </div>
  </footer>
 
{FOOTER_RC}
</body>
</html>
<!-- END: FOOTER -->

Шаблон index.tpl очищаем полностью:

XML/XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- BEGIN: MAIN -->
  <main id="home" class="my-4">
    <div class="container">
    <div class="row">
      <div class="col">
        <p class="text-center mb-0">
          This is index
        </p>
      </div>
    </div>
    </div>
  </main>
<!-- END: MAIN -->

Пройдемся по остальным шаблонам. Самым трудоемким будет login.tpl. Будем считать, что в качестве CSS-фреймворка используется Bootstrap:

XML/XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<!-- BEGIN: MAIN -->
<main id="login" class="my-4">
    <div class="container">
        <div class="row">
            <div class="mx-auto col col-lg-7 col-xl-6 col-xxl-5">
{FILE "{PHP.cfg.themes_dir}/{PHP.theme}/warnings.tpl"}
                <div class="title mb-3">
                    <ul class="breadcrumb">
                        <li class="breadcrumb-item">
                            <a href="{PHP.cfg.mainurl}" title="{PHP.L.Home}">{PHP.L.Home}</a>
                        </li>
                        <li class="breadcrumb-item">{PHP.L.Login}</li>
                    </ul>
                    <h1 class="display-6 lh-1">{USERS_AUTH_TITLE}</h1>
                </div>
<!-- IF {PHP.usr.id} -->
                <div class="alert alert-info">
                    <p class="mb-0">
                        {PHP.L.users_loggedinas} <strong>{PHP.usr.name}</strong>. {PHP.L.users_logoutfirst}
                    </p>
                </div>
                <div class="btn-group w-100">
<!-- IF {PHP.usr.maingrp} == 5 OR {PHP.usr.maingrp} == 6 -->
                    <a class="btn btn-danger btn flex-fill" href="{PHP|cot_url('admin')}">{PHP.L.Adminpanel}</a>
<!-- ENDIF -->
                    <a class="btn btn-success btn flex-fill" href="{PHP|cot_url('users', 'm=profile')}">{PHP.L.Profile}</a>
                    <a class="btn btn-success btn flex-fill" href="{PHP.sys.xk|cot_url('login','out=1&x=$this', '', 0, 1)}">{PHP.L.Logout}</a>
                </div>
<!-- ELSE -->
                <form name="login" action="{USERS_AUTH_SEND}" method="post">
                    <div class="input-group mb-3">
                        <span class="input-group-text small w-25">{PHP.L.Name}:</span>
                        {USERS_AUTH_USER}
                    </div>
                    <div class="input-group mb-3">
                        <span class="input-group-text small w-25">{PHP.L.Password}:</span>
                        {USERS_AUTH_PASSWORD}
                        <div class="input-group-text">
                            {USERS_AUTH_REMEMBER}
                        </div>
                    </div>
                    <div class="btn-group w-100">
                        <button type="submit" name="rlogin" value="0" class="btn btn-success btn flex-fill">{PHP.L.Login}</button>
<!-- IF !{PHP.cfg.users.disablereg} -->
                        <a href="{PHP|cot_url('users','m=register')}" class="btn btn-primary btn flex-fill">{PHP.L.Registration}</a>
<!-- ENDIF -->
                        <a href="{PHP|cot_url('users','m=passrecover')}" class="btn btn-primary btn flex-fill">{PHP.L.users_lostpass}</a>
                    </div>
                </form>
<!-- ENDIF -->
 
<!-- BEGIN: USERS_AUTH_MAINTENANCE -->
                <div class="alert alert-warning mb-0" role="alert">
                    <h4>
                        {PHP.L.users_maintenance1}
<!-- IF {PHP.cfg.maintenancereason} -->
                        ({PHP.cfg.maintenancereason})
<!-- ENDIF -->
                    </h4>
                    <p class="mb-0">
                        {PHP.L.users_maintenance2}
                    </p>
                </div>
<!-- END: USERS_AUTH_MAINTENANCE -->
 
            </div>
        </div>
    </div>
</main>
<!-- END: MAIN -->

Следующий в очереди error.tpl:

XML/XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<!-- BEGIN: MAIN -->
<!DOCTYPE html>
<html lang="{PHP.cfg.defaultlang}">
    <head>
        <title>{MESSAGE_TITLE}</title>
        <meta http-equiv="content-type" content="text/html; charset=utf-8" />
        <meta name="generator" content="Cotonti http://www.cotonti.com" />
        {MESSAGE_BASEHREF}
        {MESSAGE_STYLESHEET}
        {MESSAGE_REDIRECT}
    </head>
    <body>
        <main id="error">
            <div class="container">
                <div class="row">
                    <div class="col">
                        <h1>{MESSAGE_TITLE}</h1>
                        <div>
                            {MESSAGE_BODY}
                        </div>
                    </div>
                </div>
            </div>
        </main>
    </body>
</html>
<!-- END: MAIN -->

За ним message.tpl:

XML/XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!-- BEGIN: MAIN -->
<!-- IF !{AJAX_MODE} -->
<main id="message" class="my-4">
    <div class="container">
        <div class="row">
            <div class="col">
                <div class="title p-0">
                    <h1 class="lh-1 text-center mb-3">{MESSAGE_TITLE}</h1>
                </div>
<!-- ENDIF -->
                <div class="alert alert-warning mb-0" role="alert">
                    <p class="text-center mb-0">
                        {MESSAGE_BODY}
                    </p>
                    <div class="d-flex justify-content-center">
<!-- BEGIN: MESSAGE_CONFIRM -->
                        <a id="confirmYes" href="{MESSAGE_CONFIRM_YES}" class="confirmButton btn btn-success btn-sm fw-bold mx-2 text-uppercase w-25">{PHP.L.Yes}</a>
                        <a id="confirmNo" href="{MESSAGE_CONFIRM_NO}" class="confirmButton btn btn-danger btn-sm bold fw-bold text-uppercase mx-2 w-25">{PHP.L.No}</a>
<!-- END: MESSAGE_CONFIRM -->
                    </div>
                </div>
<!-- IF !{AJAX_MODE} -->
            </div>
        </div>
    </div>
</main>
<!-- ENDIF -->
 
<!-- END: MAIN -->

За ним plugin.tpl:

XML/XHTML
1
2
3
4
5
6
7
8
9
10
11
12
<!-- BEGIN: MAIN -->
<div class="container">
    <div class="row">
        <div class="col">
            <h1>{PLUGIN_TITLE}</h1>
            <div>
                {PLUGIN_BODY}
            </div>
        </div>
    </div>
</div>
<!-- END: MAIN -->

Далее poput.tpl:

XML/XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!-- BEGIN: MAIN -->
<!DOCTYPE html>
<html lang="{PHP.cfg.defaultlang}">
    <head>
        {POPUP_METAS}
        {POPUP_JAVASCRIPT}
        <base href="{PHP.cfg.mainurl}/" />
        <script type="text/javascript">
            //<![CDATA[
            function add(text) {
                insertText(document, "{POPUP_C2}", text);
            }
            //]]>
        </script>
        <link href="themes/{PHP.theme}/css/{PHP.scheme}.css" type="text/css" rel="stylesheet" />
    </head>
<body>
    {POPUP_BODY}
</body>
</html>
<!-- END: MAIN -->

И в завершение warnings.tpl:

XML/XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<!-- BEGIN: ERROR -->
<div class="alert alert-danger" role="alert">
    <h4>{PHP.L.Error}</h4>
    <p class="m-0">
<!-- BEGIN: ERROR_ROW -->
        <span>{ERROR_ROW_MSG}</span>
<!-- END: ERROR_ROW -->
    </p>
</div>
<!-- END: ERROR -->
 
<!-- BEGIN: WARNING -->
<div class="alert alert-warning" role="alert">
    <h4>{PHP.L.Warning}</h4>
    <p class="m-0">
<!-- BEGIN: WARNING_ROW -->
        <span>{WARNING_ROW_MSG}</span>
<!-- END: WARNING_ROW -->
    </p>
</div>
<!-- END: WARNING -->
 
<!-- BEGIN: DONE -->
<div class="alert alert-success" role="alert">
    <h4>{PHP.L.Done}</h4>
    <p class="m-0">
<!-- BEGIN: DONE_ROW -->
        <span>{DONE_ROW_MSG}</span>
<!-- END: DONE_ROW -->
    </p>
</div>
<!-- END: DONE -->

Папки img и inc очищаем полностью, за исключением блокирующих просмотр файлов index.html.

Правка файлов стилей

Здесь будет немного радикальных перестановок. Настраивать стили будем под использование LESS -- динамического языка стилей, с помощью которого можно более гибко и просто работать со стилями нашего будущего веб-сайта:

  1. переименуем папку css в папку less,
  2. удалим файл reset.css (его функционал уже реализован в библиотеке Bootstrap),
  3. файл default.css очистим и переименуем в default.less,
  4. файл extras.css очистим и переименуем в responsive.css,
  5. файл modalbox.css переименуем в modalbox.less,
  6. создадим пустую папку css, в которой будут размещаться скомпилированные и минифицированные файлы стилей.

Настроим компилятор LESS и отразим наши исправления в файле-загрузчике:

XML/XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
/**
 * JavaScript and CSS loader for Kudos Theme
 *
 * @package Kudos
 * @copyright (c) Cotonti Team
 * @license https://github.com/Cotonti/Cotonti/blob/master/License.txt
 */
 
defined('COT_CODE') or die('Wrong URL.');
 
$R['theme-version'] = 1;
 
Resources::linkFileFooter($cfg['themes_dir'].'/'.$usr['theme'].'/css/modalbox.css');
 
Resources::linkFileFooter($cfg['themes_dir'].'/'.$usr['theme'].'/css/default.css?v='.$R['theme-version']);
Resources::linkFileFooter($cfg['themes_dir'].'/'.$usr['theme'].'/css/responsive.css?v='.$R['theme-version']);
 
Resources::linkFileFooter($cfg['themes_dir'].'/'.$usr['theme'].'/js/js.js');

Поясним такой выбор: стили в default.less прописываются м грузятся в первую очередь (mobile first), а в responsive.less мы будем списывать стили, использующие медиа-запросы (media queries). Переменная theme-version в загрузчике используется для кэширования стилей.

Чтобы использовать все возможности LESS и сделать работу со стилями еще более комфортной и продуктивной, создадим в папке less файл с переменными vars.less и подключим его в default.less и responsive.less директивой @import:

CSS
1
@import "vars.less";

Добавляем шаблоны модулей и плагинов

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

Шаблон page.tpl:

XML/XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!-- BEGIN: MAIN -->
<main id="page_{PAGE_ID}" class="my-4">
    <div class="container">
        <div class="row">
            <div class="col">
                <div class="title mb-3">
                    <h1 class="lh-1">{PAGE_SHORTTITLE}</h1>
                    {PAGE_CRUMBS}
                </div>
            </div>
        </div>
        <div class="row">
            <div class="col">
                <div class="textbox">
                    {PAGE_TEXT}
                </div>
{PAGE_COMMENTS_DISPLAY}
            </div>
        </div>
<!-- IF {PHP.usr.isadmin} -->
{FILE "{PHP.cfg.themes_dir}/{PHP.theme}/inc/admin-page.tpl"}
<!-- ENDIF -->
    </div>
</main>
<!-- END: MAIN -->

Шаблон page.add.tpl:

XML/XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
<!-- BEGIN: MAIN -->
<main id="page_add" class="my-4">
    <div class="container">
        <div class="row">
            <div class="col">
{FILE "themes/{PHP.theme}/warnings.tpl"}
                <h1 class="lh-1 mb-3">{PAGEADD_PAGETITLE}</h1>
                <form action="{PAGEADD_FORM_SEND}" enctype="multipart/form-data" method="post" name="pageform" class="mb-3">
                <div class="table-responsive">
                    <table class="table table-striped m-0">
                        <tr>
                            <td class="w-25">{PHP.L.Category}:</td>
                            <td class="w-75">{PAGEADD_FORM_CAT}</td>
                        </tr>
                        <tr>
                            <td>{PHP.L.Title}:</td>
                            <td>{PAGEADD_FORM_TITLE}</td>
                        </tr>
                        <tr>
                            <td>{PHP.L.Description}:</td>
                            <td>{PAGEADD_FORM_DESC}</td>
                        </tr>
                        <tr>
                            <td>{PHP.L.Author}:</td>
                            <td>{PAGEADD_FORM_AUTHOR}</td>
                        </tr>
                        <tr>
                            <td>{PHP.L.Begin}:</td>
                            <td>{PAGEADD_FORM_BEGIN}</td>
                        </tr>
                        <tr>
                            <td>{PHP.L.Expire}:</td>
                            <td>{PAGEADD_FORM_EXPIRE}</td>
                        </tr>
                        <tr>
                            <td>{PHP.L.Alias}:</td>
                            <td>{PAGEADD_FORM_ALIAS}</td>
                        </tr>
                        <tr>
                            <td>{PHP.L.page_metatitle}:</td>
                            <td>{PAGEADD_FORM_METATITLE}</td>
                        </tr>
                        <tr>
                            <td>{PHP.L.page_metadesc}:</td>
                            <td>{PAGEADD_FORM_METADESC}</td>
                        </tr>
<!-- BEGIN: TAGS -->
                        <tr>
                            <td>{PAGEADD_TOP_TAGS}:</td>
                            <td>{PAGEADD_FORM_TAGS} ({PAGEADD_TOP_TAGS_HINT})</td>
                        </tr>
<!-- END: TAGS -->
                        <tr>
                            <td>{PHP.L.Owner}:</td>
                            <td>{PAGEADD_FORM_OWNER}</td>
                        </tr>
                        <tr>
                            <td>{PHP.L.Parser}:</td>
                            <td>{PAGEADD_FORM_PARSER}</td>
                        </tr>
                        <tr>
                            <td colspan="2">
                                {PAGEADD_FORM_TEXT}
                            </td>
                        </tr>
                        <tr>
                            <td colspan="2">
<!-- IF {PHP.usr_can_publish} -->
                                <button type="submit" name="rpagestate" value="0" class="btn btn-success btn-sm">{PHP.L.Publish}</button>
<!-- ENDIF -->
                                <button type="submit" name="rpagestate" value="2" class="submit btn btn-warning btn-sm">{PHP.L.Saveasdraft}</button>
                                <button type="submit" name="rpagestate" value="1" class="btn btn-danger btn-sm">{PHP.L.Submitforapproval}</button>
                            </td>
                        </tr>
                    </table>
                </div>
                </form>
            </div>
        </div>
    </div>
</main>

Шаблон page.edit.tpl:

XML/XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
<!-- BEGIN: MAIN -->
<main id="page_edit" class="my-4">
    <div class="container">
        <div class="row">
            <div class="col">
{FILE "themes/{PHP.theme}/warnings.tpl"}
                <h1 class="lh-1 mb-3">{PAGEEDIT_PAGETITLE} #{PAGEEDIT_FORM_ID} ({PAGEEDIT_FORM_LOCALSTATUS})</h1>
                <form action="{PAGEEDIT_FORM_SEND}" enctype="multipart/form-data" method="post" name="pageform">
                <div class="table-responsive">
                    <table class="table table-striped m-0">
                        <tr>
                            <td class="w-25">{PHP.L.Category}:</td>
                            <td class="w-75">{PAGEEDIT_FORM_CAT}</td>
                        </tr>
                        <tr>
                            <td>{PHP.L.Title}:</td>
                            <td>{PAGEEDIT_FORM_TITLE}</td>
                        </tr>
                        <tr>
                            <td>{PHP.L.Description}:</td>
                            <td>{PAGEEDIT_FORM_DESC}</td>
                        </tr>
                        <tr>
                            <td>{PHP.L.Author}:</td>
                            <td>{PAGEEDIT_FORM_AUTHOR}</td>
                        </tr>
                        <tr>
                            <td>{PHP.L.Date}:</td>
                            <td>
                                {PAGEEDIT_FORM_DATE}
                                <div class="form-group m0">
                                    <div class="checkbox mb0">
                                        <label class="checkbox">
                                            <span class="title pt-1">
                                                <input type="checkbox" value="1" name="rpagedatenow" class="me-2">{PHP.L.page_date_now}
                                            </span>
                                        </label>
                                    </div>
                                </div>
                            </td>
                        </tr>
                        <tr>
                            <td>{PHP.L.Begin}:</td>
                            <td>{PAGEEDIT_FORM_BEGIN}</td>
                        </tr>
                        <tr>
                            <td>{PHP.L.Expire}:</td>
                            <td>{PAGEEDIT_FORM_EXPIRE}</td>
                        </tr>
                        <tr>
                            <td>{PHP.L.Alias}:</td>
                            <td>{PAGEEDIT_FORM_ALIAS}</td>
                        </tr>
                        <tr>
                            <td>{PHP.L.page_metatitle}:</td>
                            <td>{PAGEEDIT_FORM_METATITLE}</td>
                        </tr>
                        <tr>
                            <td>{PHP.L.page_metadesc}:</td>
                            <td>{PAGEEDIT_FORM_METADESC}</td>
                        </tr>
<!-- BEGIN: TAGS -->
                        <tr>
                            <td>{PAGEEDIT_TOP_TAGS}:</td>
                            <td>{PAGEEDIT_FORM_TAGS} ({PAGEEDIT_TOP_TAGS_HINT})</td>
                        </tr>
<!-- END: TAGS -->
<!-- BEGIN: ADMIN -->
                        <tr>
                            <td>{PHP.L.Hits}:</td>
                            <td>{PAGEEDIT_FORM_PAGECOUNT}</td>
                        </tr>
                        <tr>
                            <td>{PHP.L.Owner}:</td>
                            <td>{PAGEEDIT_FORM_OWNERID}</td>
                        </tr>
<!-- END: ADMIN -->
                        <tr>
                            <td>{PHP.L.Parser}:</td>
                            <td>{PAGEEDIT_FORM_PARSER}</td>
                        </tr>
                        <tr>
                            <td colspan="2">
                                {PAGEEDIT_FORM_TEXT}
                            </td>
                        </tr>
                        <tr>
                            <td>{PHP.L.page_deletepage}:</td>
                            <td>{PAGEEDIT_FORM_DELETE}</td>
                        </tr>
                        <tr>
                            <td colspan="2">
<!-- IF {PHP.usr_can_publish} -->
                                <button type="submit" name="rpagestate" value="0" class="btn btn-success btn-sm">{PHP.L.Publish}</button>
<!-- ENDIF -->
                                <button type="submit" name="rpagestate" value="2" class="submit btn btn-warning btn-sm">{PHP.L.Saveasdraft}</button>
                                <button type="submit" name="rpagestate" value="1" class="btn btn-danger btn-sm">{PHP.L.Submitforapproval}</button>
                            </td>
                        </tr>
                    </table>
                </div>
                </form>
            </div>
        </div>
    </div>
</main>
<!-- END: MAIN -->

Шаблон page.list.tpl:

XML/XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<!-- BEGIN: MAIN -->
<main id="list_{PHP.cat.id}" class="my-4">
    <div class="container">
        <div class="row">
            <div class="col">
                <div class="title mb-3">
                    <h1 class="lh-1">{LIST_CATTITLE}</h1>
                    {LIST_CRUMBS}
                </div>
            </div>
        </div>
        <div class="row">
            <div class="col">
<!-- IF {LIST_ROW_NUM} -->
<!-- BEGIN: LIST_ROW -->
                    <article class="card py-2 px-3">
                        <a href="{LIST_ROW_URL}">{LIST_ROW_SHORTTITLE}</a>
                            <ul class="list-inline mb-0">
                                <li class="list-inline-item">
                                    {PHP.L.Views}: {LIST_ROW_COUNT}
                                </li>
                                <li class="list-inline-item">
                                    {PHP.L.Date}: {LIST_ROW_DATE}
                                </li>
                            </ul>
<!-- IF {LIST_ROW_DESC} -->
                            <p class="mb-0">
                                {LIST_ROW_DESC}
                            </p>
<!-- ENDIF -->
                    </article>
<!-- END: LIST_ROW -->
<!-- IF {LIST_TOP_PAGINATION} -->
                <nav id="pagination-container">
                    <ul class="pagination">
                        {LIST_TOP_PAGEPREV}{LIST_TOP_PAGINATION}{LIST_TOP_PAGENEXT}
                    </ul>
                </nav>
<!-- ENDIF -->
<!-- ENDIF -->
            </div>
        </div>
<!-- IF {PHP.usr.isadmin} -->
{FILE "{PHP.cfg.themes_dir}/{PHP.theme}/inc/admin-list.tpl"}
<!-- ENDIF -->
    </div>
</main>
<!-- END: MAIN -->

Чтобы задействовать функционал "хлебных крошек", загрузим и установим плагин Crumbs. В админке (раздел Конфигурация / Темы) включим опцию "Ссылка на главную страницу в навигационной цепочке".

В папке inc разместим файлы подгрузки блоков администрирования страниц и разделов:

admin-page.tpl:

XML/XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<div id="adminblock" class="row">
    <div class="col">
        <ul class="list-inline mt-3 mb-0">
            <li class="list-inline-item">
                <a href="{PHP|cot_url('admin')}">{PHP.L.Adminpanel}</a>
            </li>
            <li class="list-inline-item">{PAGE_ADMIN_UNVALIDATE}</li>
            <li class="list-inline-item">
                <a href="{PAGE_CAT|cot_url('page','m=add&c=$this')}">{PHP.L.page_addtitle}</a>
            </li>
            <li class="list-inline-item">
                {PAGE_ADMIN_EDIT}
            </li>
            <li class="list-inline-item">
                {PAGE_ADMIN_CLONE}
            </li>
            <li class="list-inline-item">
                {PAGE_ADMIN_DELETE}
            </li>
<!-- IF {PHP|cot_auth('plug', 'attach2', 'W')} -->
            <li class="list-inline-item">
                {PAGE_ID|att_widget('page', $this, 'attach2.link')}
            </li>
<!-- ENDIF -->
            <li class="list-inline-item">
                {PHP.out.loginout}
            </li>
        </ul>
    </div>
</div>

admin-list.tpl:

XML/XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<div id="adminblock" class="row">
    <div class="col">
        <ul class="list-inline mt-3 mb-0">
            <li class="list-inline-item">
                <a href="{PHP|cot_url('admin')}">{PHP.L.Adminpanel}</a>
            </li>
            <li class="list-inline-item">
                <a href="admin.php?m=structure&n=page&id={PHP.cat.id}&x={PHP.sys.xk}">Настройки раздела</a>
            </li>
            <li class="list-inline-item">
                {LIST_SUBMITNEWPAGE}
            </li>
<!-- IF {PHP|cot_auth('plug', 'attach2', 'W')} -->
            <li class="list-inline-item">
                {PHP.cat.id|att_widget('list',$this,'attach2.link')}
            </li>
<!-- ENDIF -->
            <li class="list-inline-item">{PHP.out.loginout}</li>
        </ul>
    </div>
</div>

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

JavaScript
1
2
3
4
5
6
7
8
9
$().ready(function() {
 
    if ($('div#adminblock').length) {
        $('div#adminblock ul > li > a').each(function() {
            $(this).addClass('btn btn-primary btn-sm');
        })
    }
 
});

Теперь займемся шаблонами модуля users.

users.details.tpl:

XML/XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
<!-- BEGIN: MAIN -->
<main id="users_details" class="my-4">
    <div class="container">
        <div class="row">
            <div class="col">
{FILE "{PHP.cfg.themes_dir}/{PHP.cfg.defaulttheme}/warnings.tpl"}
                <div class="title mb-3">
                    <h1 class="lh-1">
                        {PHP.L.User} {USERS_DETAILS_NICKNAME}
<!-- BEGIN: USERS_DETAILS_ADMIN -->
                        [ {USERS_DETAILS_ADMIN_EDIT} ]
<!-- END: USERS_DETAILS_ADMIN -->
                    </h1>
                    <ul class="breadcrumb">
                        <li class="breadcrumb-item">
                            <a href="{PHP.cfg.mainurl}" title="{PHP.L.Home}">{PHP.L.Home}</a>
                        </li>
                        <li class="breadcrumb-item">
                            <a href="{PHP|cot_url('users')}">{PHP.L.Users}</a>
                        </li>
                        <li class="breadcrumb-item">
                            {USERS_DETAILS_NICKNAME}
                        </li>
                    </ul>
                </div>
                <div class="table-responsive">
                    <table class="table table-striped table-hover mb-0">
<!-- IF {PHP.cot_modules.pm} -->
                        <tr>
                            <td>{PHP.L.users_sendpm}:</td>
                            <td>{USERS_DETAILS_PM}</td>
                        </tr>
<!-- ENDIF -->
                        <tr>
                            <td class="w-25">{PHP.L.Maingroup}:</td>
                            <td class="w-75">{USERS_DETAILS_MAINGRP}</td>
                        </tr>
                        <tr>
                            <td>{PHP.L.Groupsmembership}:</td>
                            <td>{USERS_DETAILS_GROUPS}</td>
                        </tr>
                        <tr>
                            <td>{PHP.L.Country}:</td>
                            <td>{USERS_DETAILS_COUNTRYFLAG} {USERS_DETAILS_COUNTRY}</td>
                        </tr>
                        <tr>
                            <td>{PHP.L.Timezone}:</td>
                            <td>{USERS_DETAILS_TIMEZONE}</td>
                        </tr>
                        <tr>
                            <td>{PHP.L.Birthdate}:</td>
                            <td>{USERS_DETAILS_BIRTHDATE}</td>
                        </tr>
                        <tr>
                            <td>{PHP.L.Age}:</td>
                            <td>{USERS_DETAILS_AGE}</td>
                        </tr>
                        <tr>
                            <td>{PHP.L.Gender}:</td>
                            <td>{USERS_DETAILS_GENDER}</td>
                        </tr>
                        <tr>
                            <td>{PHP.L.Signature}:</td>
                            <td>{USERS_DETAILS_TEXT}</td>
                        </tr>
                        <tr>
                            <td>{PHP.L.Registered}:</td>
                            <td>{USERS_DETAILS_REGDATE}</td>
                        </tr>
<!-- IF {PHP.usr.isadmin} -->
                        <tr>
                            <td>
                                Last seen:
                            </td>
                            <td>
                                {USERS_DETAILS_LASTLOG_STAMP|cot_date('H:i j F Y', $this)}
                            </td>
                        </tr>
<!-- ENDIF -->
<!-- IF {USERS_DETAILS_AVATAR} -->
                        <tr>
                            <td>{PHP.L.Avatar}:</td>
                            <td>{USERS_DETAILS_AVATAR}</td>
                        </tr>
<!-- ENDIF -->
<!-- IF {USERS_DETAILS_PHOTO} -->
                        <tr>
                            <td>{PHP.L.Photo}:</td>
                            <td>{USERS_DETAILS_PHOTO}</td>
                        </tr>
<!-- ENDIF -->
                    </table>
                </div>
            </div>
        </div>
    </div>
</main>
<!-- END: MAIN -->

users.edit.tpl:

XML/XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
<!-- BEGIN: MAIN -->
<main id="users_edit" class="my-4">
    <div class="container">
        <div class="row">
            <div class="col">
{FILE "{PHP.cfg.themes_dir}/{PHP.cfg.defaulttheme}/warnings.tpl"}
                <div class="title mb-3">
                    <h1 class="lh-1">{PHP.L.Edit} {PHP.urr.user_name}</h1>
                    <ul class="breadcrumb">
                        <li class="breadcrumb-item">
                            <a href="{PHP.cfg.mainurl}" title="{PHP.L.Home}">{PHP.L.Home}</a>
                        </li>
                        <li class="breadcrumb-item">
                            <a href="{PHP|cot_url('users')}">{PHP.L.Users}</a>
                        </li>
                        <li class="breadcrumb-item">
                            {PHP.urr.user_name}
                        </li>
                    </ul>
                </div>
                <form action="{USERS_EDIT_SEND}" method="post" name="useredit" enctype="multipart/form-data">
                    <input type="hidden" name="id" value="{USERS_EDIT_ID}" />
                    <div class="table-responsive">
                        <table class="table table-striped table-hover mb-0">
                            <tr>
                                <td class="w-25">{PHP.L.users_id}:</td>
                                <td class="w-75">#{USERS_EDIT_ID}</td>
                            </tr>
                            <tr>
                                <td>{PHP.L.Username}:</td>
                                <td>{USERS_EDIT_NAME}</td>
                            </tr>
                            <tr>
                                <td>{PHP.L.Groupsmembership}:</td>
                                <td>
                                    {PHP.L.Maingroup}:
                                    {USERS_EDIT_GROUPS}
                                </td>
                            </tr>
                            <tr>
                                <td>{PHP.L.Country}:</td>
                                <td>{USERS_EDIT_COUNTRY}</td>
                            </tr>
                            <tr>
                                <td>{PHP.L.Timezone}:</td>
                                <td>{USERS_EDIT_TIMEZONE}</td>
                            </tr>
                            <tr>
                                <td>{PHP.L.Theme}:</td>
                                <td>{USERS_EDIT_THEME}</td>
                            </tr>
                            <tr>
                                <td>{PHP.L.Language}:</td>
                                <td>{USERS_EDIT_LANG}</td>
                            </tr>
<!-- IF {USERS_EDIT_AVATAR} -->
                            <tr>
                                <td>{PHP.L.Avatar}:</td>
                                <td>{USERS_EDIT_AVATAR}</td>
                            </tr>
<!-- ENDIF -->
<!-- IF {USERS_EDIT_SIGNATURE} -->
                            <tr>
                                <td>{PHP.L.Signature}:</td>
                                <td>{USERS_EDIT_SIGNATURE}</td>
                            </tr>
<!-- ENDIF -->
<!-- IF {USERS_EDIT_PHOTO} -->
                            <tr>
                                <td>{PHP.L.Photo}:</td>
                                <td>{USERS_EDIT_PHOTO}</td>
                            </tr>
<!-- ENDIF -->
                            <tr>
                                <td>{PHP.L.users_newpass}:</td>
                                <td>
                                    {USERS_EDIT_NEWPASS}
                                    <p class="small">{PHP.L.users_newpasshint1}</p>
                                </td>
                            </tr>
                            <tr>
                                <td>{PHP.L.Email}:</td>
                                <td>{USERS_EDIT_EMAIL}</td>
                            </tr>
                            <tr>
                                <td>{PHP.L.users_hideemail}:</td>
                                <td>{USERS_EDIT_HIDEEMAIL}</td>
                            </tr>
<!-- IF {PHP.cot_modules.pm} -->
                            <tr>
                                <td>{PHP.L.users_pmnotify}:</td>
                                <td>{USERS_EDIT_PMNOTIFY}<br />{PHP.themelang.usersedit.PMnotifyhint}</td>
                            </tr>
<!-- ENDIF -->
                            <tr>
                                <td>{PHP.L.Birthdate}:</td>
                                <td>{USERS_EDIT_BIRTHDATE}</td>
                            </tr>
                            <tr>
                                <td>{PHP.L.Gender}:</td>
                                <td>{USERS_EDIT_GENDER}</td>
                            </tr>
                            <tr>
                                <td>{PHP.L.Signature}:</td>
                                <td>{USERS_EDIT_TEXT}</td>
                            </tr>
                            <tr>
                                <td>{PHP.L.Registered}:</td>
                                <td>{USERS_EDIT_REGDATE}</td>
                            </tr>
                            <tr>
                                <td>{PHP.L.Lastlogged}:</td>
                                <td>{USERS_EDIT_LASTLOG}</td>
                            </tr>
                            <tr>
                                <td>{PHP.L.users_lastip}:</td>
                                <td>{USERS_EDIT_LASTIP}</td>
                            </tr>
                            <tr>
                                <td>{PHP.L.users_logcounter}:</td>
                                <td>{USERS_EDIT_LOGCOUNT}</td>
                            </tr>
                            <tr>
                                <td>{PHP.L.users_deleteuser}:</td>
                                <td>{USERS_EDIT_DELETE}</td>
                            </tr>
                            <tr>
                                <td colspan="2">
                                    <button type="submit" class="btn btn-primary">{PHP.L.Update}</button>
                                </td>
                            </tr>
                        </table>
                    </div>
                </form>
            </div>
        </div>
    </div>
</main>
<!-- END: MAIN -->

users.passrecover.tpl:

XML/XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<!-- BEGIN: MAIN -->
<main id="users_passrecover" class="my-4">
    <div class="container">
        <div class="row">
            <div class="mx-auto col col-lg-7 col-xl-6 col-xxl-5">
{FILE "{PHP.cfg.themes_dir}/{PHP.theme}/warnings.tpl"}
                <div class="title mb-3">
                    <h1 class="lh-1">{PHP.L.pasrec_title}</h1>
                    <ul class="breadcrumb">
                        <li class="breadcrumb-item">
                            <a href="{PHP.cfg.mainurl}">{PHP.cfg.maintitle}</a>
                        </li>
                        <li class="breadcrumb-item">{PHP.L.pasrec_title}</li>
                    </ul>
                </div>
<!-- IF {PHP.msg} == 'request' -->
                <div class="alert alert-info mb-0">
                    <p class="mb-0">
                        {PHP.L.pasrec_mailsent}
                    </p>
                </div>
<!-- ENDIF -->
<!-- IF {PHP.msg} == 'auth' -->
                <div class="alert alert-info mb-0">
                    <p class="mb-0">
                        {PHP.L.pasrec_mailsent2}
                    </p>
                </div>
<!-- ENDIF -->
<!-- IF !{PHP.msg} -->
                <form role="form" name="reqauth" action="{PASSRECOVER_URL_FORM}" method="post" class="">
                    <ol>
                        <li>{PHP.L.pasrec_explain1}</li>
                        <li>{PHP.L.pasrec_explain2}</li>
                        <li>{PHP.L.pasrec_explain3}</li>
                    </ol>
                    <div class="input-group mb-3">
                        <input type="text" class="form-control" name="email" />
                        <button type="submit" class="btn btn-primary">{PHP.L.pasrec_request}</button>
                    </div>
                    <div class="alert alert-info mb-0">
                        {PHP.L.pasrec_explain4}
                    </div>
                </form>
<!-- ENDIF -->
            </div>
        </div>
    </div>
</main>
<!-- END: MAIN -->

users.profile.tpl:

XML/XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
<!-- BEGIN: MAIN -->
<main id="users_profile" class="mb-4">
    <div class="container">
        <div class="row">
            <div class="col">
{FILE "{PHP.cfg.themes_dir}/{PHP.theme}/warnings.tpl"}
                <div class="title mb-3">
                    <h1 class="lh-1">{PHP.L.Profile}</h1>
                    <ul class="breadcrumb">
                        <li class="breadcrumb-item">
                            <a href="{PHP.cfg.mainurl}" title="{PHP.L.Home}">{PHP.L.Home}</a>
                        </li>
                        <li class="breadcrumb-item">
                            {USERS_PROFILE_TITLE}
                        </li>
                    </ul>
                </div>
                <form action="{USERS_PROFILE_FORM_SEND}" method="post" enctype="multipart/form-data" name="profile">
                    <input type="hidden" name="userid" value="{USERS_PROFILE_ID}" />
                    <div class="table-responsive">
                        <table class="table table-striped table-hover mb-0">
                            <tr>
                                <td class="w-25">{PHP.L.Username}:</td>
                                <td class="w-75">{USERS_PROFILE_NAME}</td>
                            </tr>
                            <tr>
                                <td>{PHP.L.Groupsmembership}:</td>
                                <td>{USERS_PROFILE_GROUPS}</td>
                            </tr>
                            <tr>
                                <td>{PHP.L.Registered}:</td>
                                <td>{USERS_PROFILE_REGDATE}</td>
                            </tr>
<!-- BEGIN: USERS_PROFILE_EMAILCHANGE -->
                            <tr>
                                <td>{PHP.L.Email}:</td>
                                <td>
                                    {PHP.L.Email}:<br />{USERS_PROFILE_EMAIL}
<!-- BEGIN: USERS_PROFILE_EMAILPROTECTION -->
                                    <script type="text/javascript">
                                        $(document).ready(function(){
                                            $("#emailnotes").hide();
                                            $("#emailtd").click(function(){$("#emailnotes").slideDown();});
                                        });
                                    </script>
                                    <div>
                                        {PHP.themelang.usersprofile.Emailpassword}:<br />{USERS_PROFILE_EMAILPASS}
                                    </div>
                                    <div>{PHP.themelang.usersprofile.Emailnotes}</div>
<!-- END: USERS_PROFILE_EMAILPROTECTION -->
                                </td>
                            </tr>
<!-- END: USERS_PROFILE_EMAILCHANGE -->
                            <tr>
                                <td>{PHP.L.users_hideemail}:</td>
                                <td>{USERS_PROFILE_HIDEEMAIL}</td>
                            </tr>
<!-- IF {PHP.cot_modules.pm} -->
                            <tr>
                                <td>{PHP.L.users_pmnotify}:</td>
                                <td>
                                    {USERS_PROFILE_PMNOTIFY}
                                    <p class="small mb-0">{PHP.L.users_pmnotifyhint}</p>
                                </td>
                            </tr>
<!-- ENDIF -->
                            <tr>
                                <td>{PHP.L.Theme}:</td>
                                <td>{USERS_PROFILE_THEME}</td>
                            </tr>
                            <tr>
                                <td>{PHP.L.Language}:</td>
                                <td>{USERS_PROFILE_LANG}</td>
                            </tr>
                            <tr>
                                <td>{PHP.L.Country}:</td>
                                <td>{USERS_PROFILE_COUNTRY}</td>
                            </tr>
                            <tr>
                                <td>{PHP.L.Timezone}:</td>
                                <td>{USERS_PROFILE_TIMEZONE}</td>
                            </tr>
                            <tr>
                                <td>{PHP.L.Birthdate}:</td>
                                <td>{USERS_PROFILE_BIRTHDATE}
                                </td>
                            </tr>
                            <tr>
                                <td>{PHP.L.Gender}:</td>
                                <td>{USERS_PROFILE_GENDER}</td>
                            </tr>
<!-- IF {USERS_PROFILE_AVATAR} -->
                            <tr>
                                <td>{PHP.L.Avatar}:</td>
                                <td>{USERS_PROFILE_AVATAR}</td>
                            </tr>
<!-- ENDIF -->
<!-- IF {USERS_PROFILE_PHOTO} -->
                            <tr>
                                <td>{PHP.L.Photo}:</td>
                                <td>{USERS_PROFILE_PHOTO}</td>
                            </tr>
<!-- ENDIF -->
                            <tr>
                                <td>{PHP.L.Signature}:</td>
                                <td>{USERS_PROFILE_TEXT}</td>
                            </tr>
                            <tr>
                                <td>
                                    {PHP.L.users_newpass}:
                                    <p class="small">{PHP.L.users_newpasshint1}</p>
                                </td>
                                <td>
                                    {USERS_PROFILE_OLDPASS}
                                    <p class="small mb-2">{PHP.L.users_oldpasshint}</p>
                                    {USERS_PROFILE_NEWPASS1} {USERS_PROFILE_NEWPASS2}
                                    <p class="small m-0">{PHP.L.users_newpasshint2}</p>
                                </td>
                            </tr>
                            <tr>
                                <td colspan="2">
                                    <button type="submit" class="btn btn-primary">{PHP.L.Update}</button>
                                </td>
                            </tr>
                        </table>
                    </div>
                </form>
            </div>
        </div>
    </div>
</main>
<!-- END: MAIN -->

users.register.tpl:

XML/XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<!-- BEGIN: MAIN -->
<main id="users_register" class="my-4">
    <div class="container">
        <div class="row">
            <div class="mx-auto col col-lg-7 col-xl-6 col-xxl-5">
{FILE "{PHP.cfg.themes_dir}/{PHP.theme}/warnings.tpl"}
                <div class="title mb-3">
                    <h1 class="lh-1">{USERS_REGISTER_TITLE}</h1>
                    <ul class="breadcrumb">
                        <li class="breadcrumb-item">
                            <a href="{PHP.cfg.mainurl}">{PHP.cfg.maintitle}</a>
                        </li>
                        <li class="breadcrumb-item">
                            {PHP.L.Register}
                        </li>
                    </ul>
                </div>
                <form name="login" action="{USERS_REGISTER_SEND}" method="post" enctype="multipart/form-data">
                    <div class="mb-3">
                        <label class="control-label" for="">{PHP.L.Username}</label>
                        {USERS_REGISTER_USER}
                    </div>
                    <div class="mb-3">
                        <label class="control-label" for="">{PHP.L.users_validemail} {PHP.L.users_validemailhint}</label>
                        {USERS_REGISTER_EMAIL}
                    </div>
                    <div class="mb-3">
                        <label class="control-label" for="">{PHP.L.Password}</label>
                        {USERS_REGISTER_PASSWORD}
                    </div>
                    <div class="mb-3">
                        <label class="control-label" for="">{PHP.L.users_confirmpass}</label>
                        {USERS_REGISTER_PASSWORDREPEAT}
                    </div>
                    <div class="mb-3">
                        <label class="control-label" for="">{USERS_REGISTER_VERIFYIMG}</label>
                        {USERS_REGISTER_VERIFYINPUT}
                    </div>
                    <div class="btn-group w-100">
                        <button type="submit" class="btn btn-success btn flex-fill">{PHP.L.Registration}</button>
                        <a href="{PHP|cot_url('login')}" class="btn btn-primary btn flex-fill">{PHP.L.Login}</a>
                        <a href="{PHP|cot_url('users','m=passrecover')}" class="btn btn-primary btn flex-fill">{PHP.L.users_lostpass}</a>
                    </div>
                </form>
            </div>
        </div>
    </div>
</main>
<!-- END: MAIN -->

users.tpl:

XML/XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<!-- BEGIN: MAIN -->
<main id="users" class="my-4">
    <div class="container">
        <div class="row">
            <div class="col">
{FILE "{PHP.cfg.themes_dir}/{PHP.cfg.defaulttheme}/warnings.tpl"}
                <div class="title mb-3">
                    <h1 class="lh-1">{PHP.L.Users}</h1>
                    <ul class="breadcrumb">
                        <li class="breadcrumb-item">
                            <a href="{PHP.cfg.mainurl}" title="{PHP.L.Home}">{PHP.L.Home}</a>
                        </li>
                        <li class="breadcrumb-item">
                            {PHP.L.Users}
                        </li>
                    </ul>
                </div>
                <div class="table-responsive">
                    <table class="table table-striped table-hover">
                        <thead>
                            <tr class="text-center">
                                <th class="w-5">{USERS_TOP_PM}</th>
                                <th class="w-25">{USERS_TOP_NAME}</th>
                                <th class="w-25">{USERS_TOP_GRPTITLE}</th>
                                <th class="w-20">{USERS_TOP_GRPLEVEL}</th>
                                <th class="w-25">{USERS_TOP_REGDATE}</th>
                            </tr>
                        </thead>
                        <tbody>
<!-- BEGIN: USERS_ROW -->
                            <tr class="text-center">
                                <td>{USERS_ROW_PM}</td>
                                <td>{USERS_ROW_NAME}&nbsp;{USERS_ROW_TAG}</td>
                                <td>{USERS_ROW_MAINGRP}</td>
                                <td>{USERS_ROW_MAINGRPSTARS}</td>
                                <td>{USERS_ROW_REGDATE}</td>
                            </tr>
<!-- END: USERS_ROW -->
                        </tbody>
                    </table>
                    <p class="text-center mb-0">
                        {PHP.L.users_usersperpage}: {USERS_TOP_MAXPERPAGE} | {PHP.L.users_usersinthissection}: {USERS_TOP_TOTALUSERS}
                    </p>
    <!-- IF {USERS_TOP_PAGNAV} -->
                    <nav id="pagination-container">
                        <ul class="pagination">
                            {USERS_TOP_PAGEPREV}{USERS_TOP_PAGNAV}{USERS_TOP_PAGENEXT}
                        </ul>
                    </nav>
    <!-- ENDIF -->
                </div>
            </div>
        </div>
    </div>
</main>
<!-- END: MAIN -->

Для того, чтобы вся эта история заработала, подключим Bootstrap. Например, при помощи нашего плагина Bootstrap.

Практически все стало красиво. Исключение -- некоторые локации модуля users:

  1. users.details, users.edit, users.profile -- список групп пользователя выводится в контейнере ul;
  2. login -- теги USERS_AUTH_USER, USERS_AUTH_PASSWORD и USERS_AUTH_REMEMBER не имеют классов Bootstrap;
  3. register -- теги USERS_REGISTER_USER, USERS_REGISTER_EMAIL, USERS_REGISTER_PASSWORD, USERS_REGISTER_PASSWORDREPEAT, USERS_REGISTER_VERIFYINPUT не имеют классов Bootstrap.

Можно исправить эти проблемы двумя способами:

  1. используя jQuery;
  2. переназначив соответствующие ресурсы миниплагином.

Поскольку jQuery мы уже использовали выше, выберем второй способ и создадим плагин Kudos с тремя частями и кастомным файлом ресурсов:

kudos.resources.php:

PHP
1
2
3
4
5
6
7
8
9
<?php
/*
 * Redefine some Users module resources
 */
 
$R['users_code_grplist_begin'] = '<ul class="list-unstyled mb-0">';
 
$R['form_guest_remember'] = '<input type="checkbox" name="rremember" class="form-check-input" title="'.$L['users_rememberme'].'" />';
$R['form_guest_remember_forced'] = '<input type="checkbox" name="rremember" class="form-check-input" title="'.$L['users_rememberme'].'" checked="checked" disabled="disabled" />';

kudos.login.php:

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
/* ====================
[BEGIN_COT_EXT]
Hooks=users.auth.tags
[END_COT_EXT]
==================== */
 
/**
 * Customization for Kudos theme
 *
 * @package Kudos
 * @copyright (c) Cotonti Team
 * @license https://github.com/Cotonti/Cotonti/blob/master/License.txt
 */
 
defined('COT_CODE') or die('Wrong URL');
 
require_once cot_incfile('kudos', 'plug', 'resources');
 
$t->assign(array(
    'USERS_AUTH_USER' => cot_inputbox('text', 'rusername', $rusername, array('size' => '12', 'maxlength' => '100', 'class' => 'form-control')),
    'USERS_AUTH_PASSWORD' => cot_inputbox('password', 'rpassword', '', array('size' => '12', 'maxlength' => '32', 'class' => 'form-control')),
    'USERS_AUTH_REMEMBER' => Cot::$cfg['forcerememberme'] ? Cot::$R['form_guest_remember_forced'] : Cot::$R['form_guest_remember']
));

kudos.register.php:

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
/* ====================
[BEGIN_COT_EXT]
Hooks=users.register.tags
[END_COT_EXT]
==================== */
 
/**
 * Customization for Kudos theme
 *
 * @package Kudos
 * @copyright (c) Cotonti Team
 * @license https://github.com/Cotonti/Cotonti/blob/master/License.txt
 */
 
defined('COT_CODE') or die('Wrong URL');
 
$t->assign(array(
    'USERS_REGISTER_USER' => cot_inputbox('text', 'rusername', $ruser['user_name'], array('size' => 24, 'maxlength' => 100, 'class' => 'form-control')),
    'USERS_REGISTER_EMAIL' => cot_inputbox('text', 'ruseremail', $ruser['user_email'], array('size' => 24, 'maxlength' => 64, 'class' => 'form-control')),
    'USERS_REGISTER_PASSWORD' => cot_inputbox('password', 'rpassword1', '', array('size' => 12, 'maxlength' => 32, 'class' => 'form-control')),
    'USERS_REGISTER_PASSWORDREPEAT' => cot_inputbox('password', 'rpassword2', '', array('size' => 12, 'maxlength' => 32, 'class' => 'form-control')),
    'USERS_REGISTER_VERIFYINPUT' => cot_inputbox('text', 'rverify', '', array('size' => 10, 'maxlength' => 20, 'class' => 'form-control')),
));

kudos.users.php:

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
/* ====================
[BEGIN_COT_EXT]
Hooks=users.edit.first,users.details.first,users.profile.first
[END_COT_EXT]
==================== */
 
/**
 * Customization for Kudos theme
 *
 * @package Kudos
 * @copyright (c) Cotonti Team
 * @license https://github.com/Cotonti/Cotonti/blob/master/License.txt
 */
 
defined('COT_CODE') or die('Wrong URL');
 
require_once cot_incfile('kudos', 'plug', 'resources');

Ничего сверхъестественного плагин не делает, всего лишь переназначает необходимые нам ресурсные строки, добавляя им необходимые CSS-классы.

Заключение

Мы создали стартовую (модельную) тему для движка Cotonti. Фактически, это тема-пустышка, адаптированная под Bootstrap, в которой проработаны все служебные шаблоны. Добавьте к ней тему админки Yukon, и у Вас будет готовая сборка для создания нового проекта "с нуля".

Для кастомизации данной стартовой темы нам понадобилось написать небольшой плагин Kudos и установить готовые плагины для загрузки Bootstrap и генерации "хлебных крошек". Дальнейшая разработка сайта, возможно, потребует большего их количества, однако этого не стоит опасаться: Cotonti именно так и создана. Тема универсальной "заготовки" будет развиваться и дальше.

Аватар
  • 1. Sergeich
  • 29.03.2024 12:43

Спасибо за статью. Берём на вооружение :)

Новый комментарий

Имя:
Для редактирования комментария осталось 10 минут
Блок пользователя
Регистрация на нашем сайте позволит вам общаться на форумах и получить доступ к другому полезному функционалу
Вы вошли как Гость