Страница пользователя как на modx.pro

1 1 000
Реализация страницы пользователя как на mоdx.pro (https://modx.pro/users/bezumkin/). Не используются дополнения virtualPage и userProfile\userProfile2 из-за их глючности и конфликтов с другими дополнениями. Все протестировано на рабочем проекте.

1. Создаем ресурс с алиасом user

2. Для примера добавим на созданный ресурс этот контент:

<h3>[[!+fullname]]</h3>
<big>Информация</big>
<table class="table">
	<tbody>
		<tr>
			<td>Веб-сайт</td>
			<td><a href="[[!+website]]" target="_blank">[[!+website]]</a></td>
		</tr>
		<tr>
			<td>Город</td>
			<td>[[!+city]]</td>
		</tr>
	</tbody>
</table>
Плейсхолдеры названы так же, как поля у пользователя (fullname? email, city и т.д.). Вызывать некешируемыми, т.е. с восклицательным знаком [[!+fullname]]

3. Создаем плагин и вешаем его на событие joxi.ru/12MYMYPI41BEQ2

<?php
if ($modx->event->name != 'OnPageNotFound') {return false;}
$alias = $modx->context->getOption('request_param_alias', 'q');
if (!isset($_REQUEST[$alias])) {return false;}

$request = $_REQUEST[$alias];
$tmp = explode('/', $request);
// Ссылка подходит под заданный формат: user/username
if ($tmp[0] == 'user' && count($tmp) >= 2) {
	// Определяем id раздела /user/.
	// Конечно, можно его и руками прописать - но так гибче
	if (!$section = $modx->findResource($tmp[0] . '/')) {
		// Если вдруг раздел куда-то делся - выходим.
		return false;
	}
	// Теперь очищаем имя пользователя от возможного расширения
	$name = str_replace('.html', '', $tmp[1]);
	// Если очищенное имя не равно запрошенному - то можно отредиректить юзера
	// Также возможен вариант с косой на конце имени бренда - его тоже учитываем
	// SEOшники должны оценить =)
	if ($tmp[1] != $name || (isset($tmp[2]) && $tmp[2] == '')) {
		$modx->sendRedirect($tmp[0] . '/' . $name);
	}
	
	// Люди с неправильной ссылкой ушли на правильную и дошли до этого момента со второго раза
	// Дальше проверяем наличие запрошенного пользователя
	if ($user= $modx->getObject('modUser', array('username' => $name))) {
		// Круто, такой пользователь есть, получаем его id
		$id = $user->get('id');
		$modx->setPlaceholder('id', $id);
		$modx->setPlaceholders($user->Profile->toArray());
		// А теперь подсовывем юзеру страницу юзеров, а дальше сниппет на ней сам разберётся
		$modx->sendForward($section);
	}
}
// Иначе ничего не делаем и юзер получает 404 или его перехватывает другой плагин.
4. Теперь страницы доступны по адресу site.ru/user/username

Если что-то пошло не так и по этому адресу не отображается страница пользователя, смотрите какие у вас есть еще плагины. У меня был плагин для подставления в конец url слеша.

<?php
if ($modx->event->name == 'OnLoadWebDocument') {
	$uri = $_SERVER['REQUEST_URI'];
	if ($modx->resource->isfolder && substr($uri, -1) != '/' && !$_GET['page']) {
		$modx->sendRedirect($modx->makeUrl($modx->resource->id),array('responseCode' => 'HTTP/1.1 301 Moved Permanently'));
	}
}
Поэтому пришлось изменить плагин:

Вот этот блок

if ($tmp[1] != $name || (isset($tmp[2]) && $tmp[2] == '')) {
   $modx->sendRedirect($tmp[0] . '/' . $name);
}
Поменял на этот

if ($tmp[1] != $name || (!isset($tmp[2]) || $tmp[2] != '')) {
   $modx->sendRedirect($tmp[0] . '/' . $name . '/');
}
И все заработало.

Всем удачи. Мне этот функционал долго был недоступен. Спасибо Илье Уткину modx.pro/users/ilyautkin/ за помощь.

Предложить вариант реализации страниц пользователей как на modx.pro. Без использования virtualPage и userProfile. Первый рабочий вариант (рабочий вариант, это когда я скопировал ваш код или пакет и у меня на проекте заработали страницы пользователей) получит 1000 рублей. Варианты предлагать в комментариях.

Отличие моего проекта от modx.pro (если это на что-то влияет) — страницы пользователей на поддомене (уже настроен). Примерно так — subdomain.site.ru/user_name
Wassi Wassinen
14 февраля 2016, 17:03
modx.pro
37
7 559
0

Комментарии: 56

Илья Уткин
14 февраля 2016, 21:04
0
Я предлагаю вот такое решение: bezumkin.ru/sections/tips_and_tricks/2918/
    Wassi Wassinen
    14 февраля 2016, 21:20
    0
    Илья, спасибо за ответ. Эту страничку видел. Мне нужно готовое решение. Чтобы я копипастом получил работающие страницы пользователей.
      Илья Уткин
      14 февраля 2016, 21:33
      +1
      Создаём страницу «Пользователь» (user).
      <h3>[[+fullname]]</h3>
      <big>Информация</big>
      <table class="table">
      	<tbody>
      		<tr>
      			<td>Веб-сайт</td>
      			<td><a href="[[+website]]" target="_blank">[[+website]]</a></td>
      		</tr>
      		<tr>
      			<td>Город</td>
      			<td>[[+city]]</td>
      		</tr>
      	</tbody>
      </table>

      Создаём плагин на событие OnPageNotFound
      <?php
      if ($modx->event->name != 'OnPageNotFound') {return false;}
      $alias = $modx->context->getOption('request_param_alias', 'q');
      if (!isset($_REQUEST[$alias])) {return false;}
      
      $request = $_REQUEST[$alias];
      $tmp = explode('/', $request);
      // Ссылка подходит под заданный формат: user/username
      if ($tmp[0] == 'user' && count($tmp) >= 2) {
      	// Определяем id раздела /user/.
      	// Конечно, можно его и руками прописать - но так гибче
      	if (!$section = $modx->findResource($tmp[0] . '/')) {
      		// Если вдруг раздел куда-то делся - выходим.
      		return false;
      	}
      	// Теперь очищаем имя пользователя от возможного расширения
      	$name = str_replace('.html', '', $tmp[1]);
      	// Если очищенное имя не равно запрошенному - то можно отредиректить юзера
      	// Также возможен вариант с косой на конце имени бренда - его тоже учитываем
      	// SEOшники должны оценить =)
      	if ($tmp[1] != $name || (isset($tmp[2]) && $tmp[2] == '')) {
      		$modx->sendRedirect($tmp[0] . '/' . $name);
      	}
      	
      	// Люди с неправильной ссылкой ушли на правильную и дошли до этого момента со второго раза
      	// Дальше проверяем наличие запрошенного пользователя
      	if ($user= $modx->getObject('modUserProfile', array('username' => $name))) {
      		// Круто, такой пользователь есть, получаем его id
      		$id = $user->get('internalKey');
      		$modx->setPlaceholder('id', $id);
      		$modx->setPlaceholders($user->toArray());
      		// А теперь подсовывем юзеру страницу юзеров, а дальше сниппет на ней сам разберётся
      		$modx->sendForward($section);
      	}
      }
      // Иначе ничего не делаем и юзер получает 404 или его перехватывает другой плагин.
        Wassi Wassinen
        14 февраля 2016, 22:20
        0
        Написал в скайп.
          Илья Уткин
          14 февраля 2016, 23:24
          +1
          Э-э-э, не… Я думал, надо в комментах предложить рабочее решение — и будет шанс получить 1000 руб.

          А так — если не подходит, значит, ждем других кандидатов. =))
            Wassi Wassinen
            15 февраля 2016, 00:46
            0
            Копипастом не работает.
              Илья Уткин
              15 февраля 2016, 00:48
              0
              Да, я понял, жаль…
                Wassi Wassinen
                15 февраля 2016, 00:50
                0
                А ты на каком-нибудь тестовом сайте пробовал это реализовать или без теста сюда написал? :)
                  Илья Уткин
                  15 февраля 2016, 00:54
                  0
                  Без теста, сегодня весь день с женой провожу, поэтому только по-быстрому накидал и без проверки.

                  Наверняка, еще кто-нибудь поправит или другое решение предложит
                    Wassi Wassinen
                    15 февраля 2016, 00:57
                    0
                    Понял :) Все равно, спасибо за участие!
                    Илья Уткин
                    15 февраля 2016, 23:34
                    +1
                    Вот, вроде, рабочее решение
                    <?php
                    if ($modx->event->name != 'OnPageNotFound') {return false;}
                    $alias = $modx->context->getOption('request_param_alias', 'q');
                    if (!isset($_REQUEST[$alias])) {return false;}
                    
                    $request = $_REQUEST[$alias];
                    $tmp = explode('/', $request);
                    // Ссылка подходит под заданный формат: user/username
                    if ($tmp[0] == 'user' && count($tmp) >= 2) {
                    	// Определяем id раздела /user/.
                    	// Конечно, можно его и руками прописать - но так гибче
                    	if (!$section = $modx->findResource($tmp[0] . '/')) {
                    		// Если вдруг раздел куда-то делся - выходим.
                    		return false;
                    	}
                    	// Теперь очищаем имя пользователя от возможного расширения
                    	$name = str_replace('.html', '', $tmp[1]);
                    	// Если очищенное имя не равно запрошенному - то можно отредиректить юзера
                    	// Также возможен вариант с косой на конце имени бренда - его тоже учитываем
                    	// SEOшники должны оценить =)
                    	if ($tmp[1] != $name || (isset($tmp[2]) && $tmp[2] == '')) {
                    		$modx->sendRedirect($tmp[0] . '/' . $name);
                    	}
                    	
                    	// Люди с неправильной ссылкой ушли на правильную и дошли до этого момента со второго раза
                    	// Дальше проверяем наличие запрошенного пользователя
                    	if ($user= $modx->getObject('modUser', array('username' => $name))) {
                    		// Круто, такой пользователь есть, получаем его id
                    		$id = $user->get('id');
                    		$modx->setPlaceholder('id', $id);
                    		$modx->setPlaceholders($user->Profile->toArray());
                    		// А теперь подсовывем юзеру страницу юзеров, а дальше сниппет на ней сам разберётся
                    		$modx->sendForward($section);
                    	}
                    }
                    // Иначе ничего не делаем и юзер получает 404 или его перехватывает другой плагин.

                    И плейсхолдеры должны быть некешируемыми
                    <h3>[[!+fullname]]</h3>

                    Демо: s4432.h2.modhost.pro/ (Логин: s4432, Пароль: zNQI8Rd6rG8B)
                      Wassi Wassinen
                      16 февраля 2016, 09:21
                      0
                      Илья, спасибо за вариант. Действительно работает, но отдает страницу пользователя по адресу site.ru/user/

                      Как заменить /user/ на /имя_пользователя/?
                        Jenya Filimonov
                        16 февраля 2016, 10:00
                        0
                        А как у вас оно заработало? Попробовал. Юзер зарегистрирован через office. Создана страница user. Создан плагин на событие.
                        Вот тут на главной пост
                        Кликаешь на линк юзера — /user/louve Первый раз
                        Опять кликаешь становится так — /user/user/louve
                        : (
                        Илья Уткин
                        16 февраля 2016, 11:24
                        +1
                        Так я ж написал доступ в админку — зайдите и посмотрите =)
                        Jenya Filimonov
                        16 февраля 2016, 11:32
                        0
                        Смотрел: ) Все перепроверил. Я не знаю что не так. Полагаю наверное у меня в системных настройках что-то не так.
                        Илья Уткин
                        16 февраля 2016, 11:37
                        0
                        Значит, пользователя с таким username не найдено
                        Jenya Filimonov
                        16 февраля 2016, 11:48
                        0
                        Это первое что я подумал. Проверил имя. Всего 2 пользователя есть — при нажатии на ссылку с любым из них — адрес в браузере приобретает правильный вид site/user/username. Но при этом бросает на главную ( это полагаю потому что у меня не создана 404-я). А на странице site/user. Мои пользователи так и не отобразились. Вот такая вот беда.
                        Илья Уткин
                        16 февраля 2016, 11:51
                        0
                        Тогда не знаю, у меня больше нет идей)
                        Виталий Серый
                        16 февраля 2016, 13:09
                        0
                        Могу ошибаться, но может быть не найден документ страницы пользователя?
                        т.к. в плагине прописано
                        $modx->findResource($tmp[0] . '/')
                        т.е. выставлен как контейнер, а на cgsleek это .html
                        Jenya Filimonov
                        16 февраля 2016, 14:10
                        0
                        пробовал убирать .html. Результат тот же. Ну и ладно… потом покапаюсь. Сейчас что то понять сложно.
                        Wassi Wassinen
                        16 февраля 2016, 13:34
                        0
                        Илья, все проверил — заработало после отключения этого плагина:

                        <?php
                        if ($modx->event->name == 'OnLoadWebDocument') {
                        	$uri = $_SERVER['REQUEST_URI'];
                        	if ($modx->resource->isfolder && substr($uri, -1) != '/' && !$_GET['page']) {
                        		$modx->sendRedirect($modx->makeUrl($modx->resource->id),array('responseCode' => 'HTTP/1.1 301 Moved Permanently'));
                        	}
                        }


                        Плагин добавляет слеш в конце url. Можешь за дополнительный бонус сделать условие, при котором они будут работать вместе?
                        Илья Уткин
                        16 февраля 2016, 13:38
                        0
                        Вот этот блок
                        if ($tmp[1] != $name || (isset($tmp[2]) && $tmp[2] == '')) {
                           $modx->sendRedirect($tmp[0] . '/' . $name);
                        }

                        Надо поменять на этот
                        if ($tmp[1] != $name || (!isset($tmp[2]) || $tmp[2] != '')) {
                           $modx->sendRedirect($tmp[0] . '/' . $name . '/');
                        }
                        Wassi Wassinen
                        23 февраля 2016, 03:03
                        0
                        Илья, привет, если у тебя есть возможность — подскажи, как реализовать вложенность страниц пользователя, как на modx.pro? Закладки, комментарии и заметки здесь выводятся на отдельных страницах, которые вложены в страницу пользователя.

                        Если это займет много времени — готов оплатить. Спасибо!
                        Илья Уткин
                        24 февраля 2016, 10:56
                        0
                        Надо для каждой такой подстраницы создать отдельный ресурс.
                        <?php
                        if ($modx->event->name != 'OnPageNotFound') {return false;}
                        $alias = $modx->context->getOption('request_param_alias', 'q');
                        if (!isset($_REQUEST[$alias])) {return false;}
                        
                        $request = $_REQUEST[$alias];
                        $tmp = explode('/', $request);
                        if ($tmp[0] == 'user' && count($tmp) >= 2) {
                        	if (!$section = $modx->findResource($tmp[0] . '/')) {
                        		return false;
                        	}
                        	$name = str_replace('.html', '', $tmp[1]);
                        	if ($tmp[1] != $name || !isset($tmp[2]) {  // Убираем второе условие
                        		$modx->sendRedirect($tmp[0] . '/' . $name . '/');
                        	}
                        
                        	// Здесь будем определять, какую страницу надо показывать
                        	switch($tmp[2]) {
                        		case 'tickets':
                        			$section = 21; // id ресурса для подстраницы «Заметки»
                        			break;
                        		case 'comments':
                        			$section = 28; // id ресурса для подстраницы «Комментарии»
                        			break;
                        		default:
                        			break;
                        	}
                        	
                        	if ($user= $modx->getObject('modUser', array('username' => $name))) {
                        		$id = $user->get('id');
                        		$modx->setPlaceholder('id', $id);
                        		$modx->setPlaceholders($user->Profile->toArray());
                        		$modx->sendForward($section);
                        	}
                        }
                        Wassi Wassinen
                        26 февраля 2016, 04:58
                        0
                        Тезка, не работает этот вариант. И почему-то в предыдущем варианте не отрабатывает плейсхолдер [[+username]].
                        Andrei D.
                        23 мая 2016, 20:29
                        0
                        Привет! Убрал плагин, который справляется с user/username и поставил твой, чтобы в одном плагине была и информация и комментарии/заметки

                        <?php
                        if ($modx->event->name != 'OnPageNotFound') {return false;}
                        $alias = $modx->context->getOption('request_param_alias', 'q');
                        if (!isset($_REQUEST[$alias])) {return false;}
                        
                        $request = $_REQUEST[$alias];
                        $tmp = explode('/', $request);
                        if ($tmp[0] == 'tiim' && count($tmp) >= 2) {
                        	if (!$section = $modx->findResource($tmp[0] . '/')) {
                        		return false;
                        	}
                        	$name = str_replace('.html', '', $tmp[1]);
                        	if ($tmp[1] != $name || !isset($tmp[2])) {  // Убираем второе условие
                        		$modx->sendRedirect($tmp[0] . '/' . $name . '/');
                        	}
                        
                        	// Здесь будем определять, какую страницу надо показывать
                        	switch($tmp[2]) {
                        	    
                        		case 'kaassuu':
                        			$section = 164; // id ресурса для подстраницы «Заметки»
                        			break;
                        		case 'kommentaarid':
                        			$section = 165; // id ресурса для подстраницы «Комментарии»
                        			break;
                        		default:
                        			//break;
                        			$section = 163;
                        	}
                        	
                        	
                        	if ($user= $modx->getObject('modUser', array('username' => $name))) {
                        		$id = $user->get('id');
                        		$modx->setPlaceholder('id', $id);
                        		$modx->setPlaceholders($user->Profile->toArray());
                        		$modx->sendForward($section);
                        	}
                        }
                        Целесообразно ли вешать информацию о пользователя на default значение?
                        Илья Уткин
                        23 мая 2016, 20:35
                        +1
                        $section для информации о пользователе уже определен вот здесь:
                        if (!$section = $modx->findResource($tmp[0] . '/')) {

                        Поэтому указывать $section внутри default особо нет смысла.
                        Andrei D.
                        23 мая 2016, 20:55
                        0
                        т.е. можно просто заменить на
                        if (!$section = 163) {
                        ?
                        Илья Уткин
                        24 мая 2016, 09:58
                        +1
                        Можно прям это
                        if (!$section = $modx->findResource($tmp[0] . '/')) {
                            return false;
                        }

                        заменить на
                        $section = 163;
                        Andrei D.
                        24 мая 2016, 12:59
                        0
                        Большое спасибо!
                        Wassi Wassinen
                        16 февраля 2016, 13:35
                        0
                        И напиши в скайп куда денег выслать. :)
                        Илья Уткин
                        16 февраля 2016, 13:38
                        0
                        ilyaut.ru/pay/ (там и номер карты Сбера есть, если так удобнее)
          Волков Николай
          15 февраля 2016, 02:41
          0
          Мне кажется, чтобы это заработал на поддоменах нужно настроиться маску DNS для Wildcard Subdomains. Для этого добавить запись A *.site.name с основным доменом. В зависимости от хостинга и сервера может потребоваться ещё в конфигах прописать кое-что.
      Антон Пастухов
      14 февраля 2016, 21:33
      0
      Это должно работать для новых регистраций или какая-то база пользователей уже есть?
        Wassi Wassinen
        14 февраля 2016, 22:20
        0
        База уже есть. И для новых тоже.
        Волков Николай
        15 февраля 2016, 02:47
        -1
        Чуть выше написал про WildCard Subdomains. Без настроек DNS и сервера такое на субдоменов сделать не думаю, что возможно. Поэтому и дополнений быть не может для этого.

        P.S. Если ошибаюсь, то самому проще кое-что станет сделать. Сейчас вожусь над тем, чтобы для пользователей при регистрации автоматом создавался собственный почтовый ящик вида login@site.name. В дальнейшем как раз думал перейти к твоему вопросу.
          Wassi Wassinen
          15 февраля 2016, 02:52
          0
          Спасибо за участие. У меня уже настроена работа MODX на нескольких субдоменах из одной админки.
            Волков Николай
            15 февраля 2016, 03:16
            0
            Судя по ответу вы не читали, что я написал, поэтому не за что. То, что вы создали пару субдоменов статических ничего в плане задачи не значит, тк вам нужны динамические субдомена, что Wildcard и делает. Ваша задача в админке не решается и код никто не вышлет, т.к. без настройки маршрутизации для DNS и сервера тут не обойтись.
              Wassi Wassinen
              15 февраля 2016, 03:24
              +1
              Я не понял что это и зачем. :) Чтобы не усложнять — могу протестировать решение на основном домене. Чтобы не путать народ — удалите ваши комментарии. Спасибо.
                Волков Николай
                15 февраля 2016, 03:57
                -2
                В смысле путать? Вам нужно, чтобы у людей было после регистрации страница личная по адресу логин_аккаунта.домен.ру? Соответственно, вам нужно получить возможность динамических субдоменов. В DNS запись A *.домен.ру означает то, что любой субдомен (*) обрабатывается на основном домене. Соответственно, останется только решение Ильи сделать.
                  Wassi Wassinen
                  15 февраля 2016, 12:14
                  0
                  Николай, у меня страницы будут на субдомене. Не субдомен под каждого отдельного пользователя. subdomain.site.ru/users/test_user что-то вроде этого. Поэтому, просто читайте внимательнее.
                    Волков Николай
                    15 февраля 2016, 13:43
                    0
                    А-а-а-а. Понял, ссори за оффтоп тогда. Удалю тогда, действительно все, что писал. Хотя тема и интересная :-) P.S. где это делается не вижу.
                  Волков Николай
                  15 февраля 2016, 04:08
                  0
                  Без этого сервер не будет понимать, как обрабатывать субдомены, которые статично отдельно не прописаны, и 404 отдавать. Если надо удалю комменты, пускай народ не путается.
            Николай
            15 февраля 2016, 17:03
            0
            Когда-то делал по этому «мануалу» bezumkin.ru/sections/tips_and_tricks/472/
              Wassi Wassinen
              15 февраля 2016, 22:54
              0
              Покажите как и я готов заплатить. :)
              Jenya Filimonov
              16 февраля 2016, 15:47
              0
              (ERROR @ /index.php) [OnPageNotFound] Plugin user failed!
              Это не переборол: ) Даже прогулявшись по свежему воздуху. Плагинов дополнительных не делал: ))) Только от приложений есть несколько (все из modstore).
                Andrei
                28 мая 2017, 18:56
                0
                Поборол таким образом
                <?php
                if ($modx->event->name == 'OnPageNotFound') {
                    
                    //Определяем системную переменную friendly urls
                    $alias = $modx->context->getOption('request_param_alias', 'q');
                    
                    
                    $request = $_REQUEST[$alias];
                    // Проверяем её наличие в запросе.
                    // Если не находим, то это фигня какая-то - выходим
                    if (!empty($request)) {
                
                        // А если есть - работаем дальше
                        if (preg_match('/catalog\/item\/[0-9]*\//',$request)){
                
                            $id = substr($request, 13, -1);
                            
                            $item = $modx->getObject('CatalogItems', $id);
                
                            if ($item) {
                                $_GET['id'] = $_REQUEST['id'] = $id;
                                $modx->sendForward(10);
                            }
                        }
                    }
                }
                почему-то не нравится ему return false;
                Andrei D.
                23 мая 2016, 17:35
                0
                А как таким образом сделать по аналогии с modx.pro, что на /users идет список пользователей (т.е. свой шаблон), а на /users/username идет уже другой шаблон?
                  Илья И
                  02 ноября 2016, 10:32
                  0
                  Почему-то не ищет ID ресурса,
                  $modx->findResource($tmp[0] . '/')
                  возвращает пустоту. Пофиг, присвоил руками — не гибко, зато работает, и хрен с ним.
                  Проблема: созданная страничка пользователя не может получить плейсхолдеры расширенных полей, типа [[!+extended.abcde]]. Содержание обычных полей отображает корректно. Другой чанк, работающий со сниппетами getPage и Peoples, отобраежает расширенные поля нормально — когда строит список всех пользователей таблицей. Я нуб, да, но гугл ведет в тупик. В какую сторону копать?
                    Fidst
                    18 августа 2020, 12:58
                    0
                    написать плагин на событие какое?
                      Роман
                      18 августа 2020, 13:35
                      0
                      OnPageNotFound
                        Fidst
                        18 августа 2020, 13:50
                        0
                        Тяжело когда не можешь сформулировать вопрос. Вопрос такой как сделать вывод всех пользователей с ссылками для прехода и возможностью написать сообщения
                          Роман
                          18 августа 2020, 14:12
                          0
                          Посмотри тут, сто раз уже задавали этот вопрос: modx.pro/help/11720
                      Fidst
                      18 августа 2020, 17:58
                      0
                      Вот не становятся доступными по ссылке site.ru/user/username. У меня чистая modx из плагинов только FormIt, pdoTools и socialTools
                        Fidst
                        19 августа 2020, 02:19
                        0
                        решено, после установки modx не настроил ЧПУ
                        Fidst
                        21 августа 2020, 14:50
                        0
                        Все хорошо, но на странице пользователя site.ru/user/username недоступно значение [[!+username]]. В чем дело, как это исправить?
                          Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
                          56