Страница пользователя как на modx.pro
1 1 000
Реализация страницы пользователя как на mоdx.pro (https://modx.pro/users/bezumkin/). Не используются дополнения virtualPage и userProfile\userProfile2 из-за их глючности и конфликтов с другими дополнениями. Все протестировано на рабочем проекте.
1. Создаем ресурс с алиасом user
2. Для примера добавим на созданный ресурс этот контент:
3. Создаем плагин и вешаем его на событие joxi.ru/12MYMYPI41BEQ2
Если что-то пошло не так и по этому адресу не отображается страница пользователя, смотрите какие у вас есть еще плагины. У меня был плагин для подставления в конец url слеша.
Вот этот блок
Всем удачи. Мне этот функционал долго был недоступен. Спасибо Илье Уткину modx.pro/users/ilyautkin/ за помощь.
Предложить вариант реализации страниц пользователей как на modx.pro. Без использования virtualPage и userProfile. Первый рабочий вариант (рабочий вариант, это когда я скопировал ваш код или пакет и у меня на проекте заработали страницы пользователей) получит 1000 рублей. Варианты предлагать в комментариях.
Отличие моего проекта от modx.pro (если это на что-то влияет) — страницы пользователей на поддомене (уже настроен). Примерно так — subdomain.site.ru/user_name
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 (если это на что-то влияет) — страницы пользователей на поддомене (уже настроен). Примерно так — subdomain.site.ru/user_name
Комментарии: 56
Я предлагаю вот такое решение: bezumkin.ru/sections/tips_and_tricks/2918/
Илья, спасибо за ответ. Эту страничку видел. Мне нужно готовое решение. Чтобы я копипастом получил работающие страницы пользователей.
Создаём страницу «Пользователь» (user).
Создаём плагин на событие OnPageNotFound
<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 или его перехватывает другой плагин.
Написал в скайп.
Э-э-э, не… Я думал, надо в комментах предложить рабочее решение — и будет шанс получить 1000 руб.
А так — если не подходит, значит, ждем других кандидатов. =))
А так — если не подходит, значит, ждем других кандидатов. =))
Копипастом не работает.
Да, я понял, жаль…
А ты на каком-нибудь тестовом сайте пробовал это реализовать или без теста сюда написал? :)
Без теста, сегодня весь день с женой провожу, поэтому только по-быстрому накидал и без проверки.
Наверняка, еще кто-нибудь поправит или другое решение предложит
Наверняка, еще кто-нибудь поправит или другое решение предложит
Понял :) Все равно, спасибо за участие!
Вот, вроде, рабочее решение
И плейсхолдеры должны быть некешируемыми
Демо: s4432.h2.modhost.pro/ (Логин: s4432, Пароль: zNQI8Rd6rG8B)
<?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)
Илья, спасибо за вариант. Действительно работает, но отдает страницу пользователя по адресу site.ru/user/
Как заменить /user/ на /имя_пользователя/?
Как заменить /user/ на /имя_пользователя/?
А как у вас оно заработало? Попробовал. Юзер зарегистрирован через office. Создана страница user. Создан плагин на событие.
Вот тут на главной пост
Кликаешь на линк юзера — /user/louve Первый раз
Опять кликаешь становится так — /user/user/louve
: (
Вот тут на главной пост
Кликаешь на линк юзера — /user/louve Первый раз
Опять кликаешь становится так — /user/user/louve
: (
Так я ж написал доступ в админку — зайдите и посмотрите =)
Смотрел: ) Все перепроверил. Я не знаю что не так. Полагаю наверное у меня в системных настройках что-то не так.
Значит, пользователя с таким username не найдено
Это первое что я подумал. Проверил имя. Всего 2 пользователя есть — при нажатии на ссылку с любым из них — адрес в браузере приобретает правильный вид site/user/username. Но при этом бросает на главную ( это полагаю потому что у меня не создана 404-я). А на странице site/user. Мои пользователи так и не отобразились. Вот такая вот беда.
Тогда не знаю, у меня больше нет идей)
Могу ошибаться, но может быть не найден документ страницы пользователя?
т.к. в плагине прописано
т.к. в плагине прописано
$modx->findResource($tmp[0] . '/')
т.е. выставлен как контейнер, а на cgsleek это .html
пробовал убирать .html. Результат тот же. Ну и ладно… потом покапаюсь. Сейчас что то понять сложно.
Илья, все проверил — заработало после отключения этого плагина:
Плагин добавляет слеш в конце 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'));
}
}
Плагин добавляет слеш в конце url. Можешь за дополнительный бонус сделать условие, при котором они будут работать вместе?
Вот этот блок
Надо поменять на этот
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? Закладки, комментарии и заметки здесь выводятся на отдельных страницах, которые вложены в страницу пользователя.
Если это займет много времени — готов оплатить. Спасибо!
Если это займет много времени — готов оплатить. Спасибо!
Надо для каждой такой подстраницы создать отдельный ресурс.
<?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);
}
}
Тезка, не работает этот вариант. И почему-то в предыдущем варианте не отрабатывает плейсхолдер [[+username]].
Привет! Убрал плагин, который справляется с 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 значение?
$section для информации о пользователе уже определен вот здесь:
Поэтому указывать $section внутри default особо нет смысла.
if (!$section = $modx->findResource($tmp[0] . '/')) {
Поэтому указывать $section внутри default особо нет смысла.
т.е. можно просто заменить на
if (!$section = 163) {
?
Можно прям это
заменить на
if (!$section = $modx->findResource($tmp[0] . '/')) {
return false;
}
заменить на
$section = 163;
Большое спасибо!
И напиши в скайп куда денег выслать. :)
ilyaut.ru/pay/ (там и номер карты Сбера есть, если так удобнее)
Мне кажется, чтобы это заработал на поддоменах нужно настроиться маску DNS для Wildcard Subdomains. Для этого добавить запись A *.site.name с основным доменом. В зависимости от хостинга и сервера может потребоваться ещё в конфигах прописать кое-что.
Это должно работать для новых регистраций или какая-то база пользователей уже есть?
База уже есть. И для новых тоже.
Чуть выше написал про WildCard Subdomains. Без настроек DNS и сервера такое на субдоменов сделать не думаю, что возможно. Поэтому и дополнений быть не может для этого.
P.S. Если ошибаюсь, то самому проще кое-что станет сделать. Сейчас вожусь над тем, чтобы для пользователей при регистрации автоматом создавался собственный почтовый ящик вида login@site.name. В дальнейшем как раз думал перейти к твоему вопросу.
P.S. Если ошибаюсь, то самому проще кое-что станет сделать. Сейчас вожусь над тем, чтобы для пользователей при регистрации автоматом создавался собственный почтовый ящик вида login@site.name. В дальнейшем как раз думал перейти к твоему вопросу.
Спасибо за участие. У меня уже настроена работа MODX на нескольких субдоменах из одной админки.
Судя по ответу вы не читали, что я написал, поэтому не за что. То, что вы создали пару субдоменов статических ничего в плане задачи не значит, тк вам нужны динамические субдомена, что Wildcard и делает. Ваша задача в админке не решается и код никто не вышлет, т.к. без настройки маршрутизации для DNS и сервера тут не обойтись.
Я не понял что это и зачем. :) Чтобы не усложнять — могу протестировать решение на основном домене. Чтобы не путать народ — удалите ваши комментарии. Спасибо.
В смысле путать? Вам нужно, чтобы у людей было после регистрации страница личная по адресу логин_аккаунта.домен.ру? Соответственно, вам нужно получить возможность динамических субдоменов. В DNS запись A *.домен.ру означает то, что любой субдомен (*) обрабатывается на основном домене. Соответственно, останется только решение Ильи сделать.
Николай, у меня страницы будут на субдомене. Не субдомен под каждого отдельного пользователя. subdomain.site.ru/users/test_user что-то вроде этого. Поэтому, просто читайте внимательнее.
А-а-а-а. Понял, ссори за оффтоп тогда. Удалю тогда, действительно все, что писал. Хотя тема и интересная :-) P.S. где это делается не вижу.
Без этого сервер не будет понимать, как обрабатывать субдомены, которые статично отдельно не прописаны, и 404 отдавать. Если надо удалю комменты, пускай народ не путается.
Когда-то делал по этому «мануалу» bezumkin.ru/sections/tips_and_tricks/472/
Покажите как и я готов заплатить. :)
(ERROR @ /index.php) [OnPageNotFound] Plugin user failed!
Это не переборол: ) Даже прогулявшись по свежему воздуху. Плагинов дополнительных не делал: ))) Только от приложений есть несколько (все из modstore).
Поборол таким образом
<?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;
А как таким образом сделать по аналогии с modx.pro, что на /users идет список пользователей (т.е. свой шаблон), а на /users/username идет уже другой шаблон?
Почему-то не ищет ID ресурса,
Проблема: созданная страничка пользователя не может получить плейсхолдеры расширенных полей, типа [[!+extended.abcde]]. Содержание обычных полей отображает корректно. Другой чанк, работающий со сниппетами getPage и Peoples, отобраежает расширенные поля нормально — когда строит список всех пользователей таблицей. Я нуб, да, но гугл ведет в тупик. В какую сторону копать?
$modx->findResource($tmp[0] . '/')
возвращает пустоту. Пофиг, присвоил руками — не гибко, зато работает, и хрен с ним.Проблема: созданная страничка пользователя не может получить плейсхолдеры расширенных полей, типа [[!+extended.abcde]]. Содержание обычных полей отображает корректно. Другой чанк, работающий со сниппетами getPage и Peoples, отобраежает расширенные поля нормально — когда строит список всех пользователей таблицей. Я нуб, да, но гугл ведет в тупик. В какую сторону копать?
написать плагин на событие какое?
OnPageNotFound
Тяжело когда не можешь сформулировать вопрос. Вопрос такой как сделать вывод всех пользователей с ссылками для прехода и возможностью написать сообщения
Посмотри тут, сто раз уже задавали этот вопрос: modx.pro/help/11720
Вот не становятся доступными по ссылке site.ru/user/username. У меня чистая modx из плагинов только FormIt, pdoTools и socialTools
решено, после установки modx не настроил ЧПУ
Все хорошо, но на странице пользователя site.ru/user/username недоступно значение [[!+username]]. В чем дело, как это исправить?
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.