Виртуальные вкладки для страницы пользователя!
Приветствую сообщество!
Вопрос собственно в следующем!
Как бы мне сделать вкладки как на здесь на modx.pro для одного юзера! (заметки, комменты, избранное)
П.С.
Говорить о том, что «надо сначала воспользоваться поиском» не надо, пишу это как раз потому, что воспользовался!
Понимаю есть ааахренеть сколько мануалов и примеров, например здесь:
Сама страница пользователя у меня тем не менее есть и организована так:
Прошу помощи! Но так, чтобы не пришлось менять вид чанков и политики вызова данных пользователя на фронт! Заранее спасибо за любою помощь!
Вопрос собственно в следующем!
Как бы мне сделать вкладки как на здесь на modx.pro для одного юзера! (заметки, комменты, избранное)
П.С.
Говорить о том, что «надо сначала воспользоваться поиском» не надо, пишу это как раз потому, что воспользовался!
Понимаю есть ааахренеть сколько мануалов и примеров, например здесь:
https://modx.pro/howto/7909-page-users-on-modxpro/
но тем не менее пример у меня не работает, даже не хочет работать элементарно страница пользователя!Сама страница пользователя у меня тем не менее есть и организована так:
<?php
// обрабатываем только события OnPageNotFound, на случай, если отметили галкой и другие в настройках плагина
if ($modx->event->name != 'OnPageNotFound') {
return false;
}
// на случай, если у нас настройки кто-то менял, получаем значение переменной, через которую передаются ссылки в modx от веб-сервера
$alias = $modx->context->getOption('request_param_alias', 'q');
// проверяем, что такая переменная есть, иначе и обрабатывать нечего
if (!isset($_REQUEST[$alias])) {
return false;
}
// наш запрос, который нужно разобрать и обработать
$request = $_REQUEST[$alias];
// разбиваем ссылку на составляющие,
// как правило, будет что-то вроде users/username, на выходе будет массив с этими значениями
$chunks = explode('/', $request);
// на всякий случай проверяем, что у нас есть корневой ресурс для пользователей, страница users
if (!$users = $modx->getObject('modResource', ['id' => 571])) {
$modx->log(modX::LOG_LEVEL_ERROR, 'Entry point resource for users not found.');
return false;
}
// а теперь обрабатываем нам запрос.
switch ($chunks[0]) {
// сверяем первую часть ссылки с алиасом нашего ресурса для пользователей, должны совпадать
case $users->get('alias'):
// еще одна проверка существования ресурса (наверное можно удалить, взял пример из реального проекта)
if (!$usersSection = $modx->findResource($chunks[0])) {
return false;
}
// у меня ссылки генерились с html, поэтому я вырезаю расширение перед поиском самого юзера
$userAlias = str_replace('.html', '', $chunks[1]);
// еще одна проверка + убираем концевые слеши и редиректим на нормальную ссылку
if ($chunks[1] != $userAlias || (isset($chunks[2]) && $chunks[2] == '')) {
$modx->sendRedirect($chunks[0] . '/' . $userAlias);
}
// пробуем найти пользователя по username из запроса, если не нашли, то посылаем 404 заголовок
// тут важно вручную послать страницу 404, иначе, если вернем просто ошибку, то у нас опять запустится обработчик
// 404 ошибки, опять запустится наш плагин, опять тут будет ошибка и привет бесконечный круг и ААААА! Ничего не работает!!!!!
if (!$user = $modx->getObject('modUser', ['id' => $userAlias])) {
$modx->sendForward($this->getOption('error_page'), $this->getOption('error_page_header', null, 'HTTP/1.0 404 Not Found'));
}
// пользоввателя нашли, теперь подгружаем его данные (профайл, расширенные поля и тд)
/** @var modUserProfile $profile */
$profile = $user->getOne('Profile');
$extended = $profile->get('extended');
// прописываем все наши данные в плейсхолдеры, чтобы потом на странице их вывести
$modx->setPlaceholders($user, 'user.');
$modx->setPlaceholders($profile, 'user.');
$modx->setPlaceholders($extended, 'user.');
// тут у меня еще момент, что пользователь может указать, что у него профиль приватный и его никому показывать нельзя,
// поэтому в таком случае тоже 404 возвращаем. Но можно удалить
// profile private, we should return not found error
// if (isset($extended['private']) && $extended['private'] == 1) {
// $modx->sendForward($this->getOption('error_page'), $this->getOption('error_page_header', null, 'HTTP/1.0 404 Not Found'));
// }
// ну и отправляем нашу страницу с шаблоном профиля пользователя, где уже выводим всю его подноготную
$modx->sendForward($usersSection);
break;
}
Сделана по этому примеру:https://modx.pro/help/9820/
Прошу помощи! Но так, чтобы не пришлось менять вид чанков и политики вызова данных пользователя на фронт! Заранее спасибо за любою помощь!
Комментарии: 40
все очень плохо :(
Ладно, я понял… В пределах разумного сколько это будет стоить?
Можно сделать вот так:
После
Прописываем:
— в местах, где определяется «вкладка» дописать необходимые плейсхолдеры по вкусу и готово.
Если что-то не получится — могу выслать куда-нибудь готовый код плагина.
После
$chunks = explode('/', $request);
Прописываем:
if (end($chunks) == '') {
array_pop($chunks);
}
//Проверяем, что есть минимум 2 части ссылки (/users/ и /username/)
if (count($chunks) >= 2) {
switch ($chunks) {
//Cама страница пользователей
case 'users':
//проверяем существование пользователя
if (!empty($chunks[1]) && $modx->getCount('modUser', array('username' => $chunks[1]))) {
$user = $modx->getObject('modUser', array('username' => $chunks[1]));
if ($user && $user->get('active') == 1) {
$user_name = $user->get('username');
//Приводим юзернейм к правильному регистру
if ($chunks[1] != $user_name) {
$chunks[1] = $user_name;
$modx->sendRedirect(implode('/', $chunks));
}
//выставляем плейсхолдеры
$user_id = $user->get('id');
$modx->setPlaceholder('user_id', $user_id);
$modx->setPlaceholder('user_name', $user_name);
//Страница профиля
if (count($chunks) == 2) {
}
//Подразделы
elseif (count($chunks) == 3) {
switch ($chunks[2]) {
//Сообщения пользователя
case 'posts':
break;
//Комментарии пользователя
case 'comments':
break;
//Избранное пользователя
case 'favorites':
break;
}
}
$modx->sendForward(айди_страницы_users);
}
}
break;
}
}
//иначе редиректим
— в местах, где определяется «вкладка» дописать необходимые плейсхолдеры по вкусу и готово.
Если что-то не получится — могу выслать куда-нибудь готовый код плагина.
хм… Спасибо тебе добрый человек! Сегодня буду пробовать!
Еще раз приветствую! Действительно работает! Вроде бы вкладки определяет + я допилил автономности и динамичности, но вот есть небольшая проблема… Как теперь на этих вкладках вызывать то, что мне надо? Если вас не затруднит распишите пожалуйста! :D
Пробовал вот такую бурду:
Вот полный код плагина:
Пробовал вот такую бурду:
[[*alias:is=`posts`:then=`Контент с Публикациями`]]
[[*alias:is=`comments`:then=`Контент с Коментами`]]
[[*alias:is=`favorites`:then=`Контент с Избранным`]]
При этом использовал небольшой динамиский фрагмент шаблона, где по факту должно было происходить переключение контента! Но чет пошло не по плану :(Вот полный код плагина:
<?php
// обрабатываем только события OnPageNotFound, на случай, если отметили галкой и другие в настройках плагина
if ($modx->event->name != 'OnPageNotFound') {
return false;
}
// на случай, если у нас настройки кто-то менял, получаем значение переменной, через которую передаются ссылки в modx от веб-сервера
$alias = $modx->context->getOption('request_param_alias', 'q');
// проверяем, что такая переменная есть, иначе и обрабатывать нечего
if (!isset($_REQUEST[$alias])) {
return false;
}
// наш запрос, который нужно разобрать и обработать
$request = $_REQUEST[$alias];
// разбиваем ссылку на составляющие,
// как правило, будет что-то вроде users/username, на выходе будет массив с этими значениями
$chunks = explode('/', $request);
if (end($chunks) == '') {
array_pop($chunks);
}
//Проверяем, что есть минимум 2 части ссылки (/users/ и /username/)
if (count($chunks) >= 2) {
switch ($chunks) {
//Cама страница пользователей
case 'users':
//проверяем существование пользователя
if (!empty($chunks[1]) && $modx->getCount('modUser', array('username' => $chunks[1]))) {
$user = $modx->getObject('modUser', array('username' => $chunks[1]));
if ($user && $user->get('active') == 1) {
$user_name = $user->get('username');
//Приводим юзернейм к правильному регистру
if ($chunks[1] != $user_name) {
$chunks[1] = $user_name;
$modx->sendRedirect(implode('/', $chunks));
}
//выставляем плейсхолдеры
$user_id = $user->get('id');
$modx->setPlaceholder('user_id', $user_id);
$modx->setPlaceholder('user_name', $user_name);
//Страница профиля
if (count($chunks) == 2) {
}
//Подразделы
elseif (count($chunks) == 3) {
switch ($chunks[2]) {
//Сообщения пользователя
case 'posts':
break;
//Комментарии пользователя
case 'comments':
break;
//Избранное пользователя
case 'favorites':
break;
}
}
$modx->sendForward(айди_страницы_users);
}
}
break;
}
}
//иначе редиректим
// на всякий случай проверяем, что у нас есть корневой ресурс для пользователей, страница users
if (!$users = $modx->getObject('modResource', ['alias' => users])) {
$modx->log(modX::LOG_LEVEL_ERROR, 'Entry point resource for users not found.');
return false;
}
// а теперь обрабатываем нам запрос.
switch ($chunks[0]) {
// сверяем первую часть ссылки с алиасом нашего ресурса для пользователей, должны совпадать
case $users->get('alias'):
// еще одна проверка существования ресурса (наверное можно удалить, взял пример из реального проекта)
if (!$usersSection = $modx->findResource($chunks[0])) {
return false;
}
// у меня ссылки генерились с html, поэтому я вырезаю расширение перед поиском самого юзера
$userAlias = str_replace('.html', '', $chunks[1]);
// еще одна проверка + убираем концевые слеши и редиректим на нормальную ссылку
if ($chunks[1] != $userAlias || (isset($chunks[2]) && $chunks[2] == '')) {
$modx->sendRedirect($chunks[0] . '/' . $userAlias);
}
// пробуем найти пользователя по username из запроса, если не нашли, то посылаем 404 заголовок
// тут важно вручную послать страницу 404, иначе, если вернем просто ошибку, то у нас опять запустится обработчик
// 404 ошибки, опять запустится наш плагин, опять тут будет ошибка и привет бесконечный круг и ААААА! Ничего не работает!!!!!
if (!$user = $modx->getObject('modUser', ['id' => $userAlias])) {
$modx->sendForward($this->getOption('error_page'), $this->getOption('error_page_header', null, 'HTTP/1.0 404 Not Found'));
}
// пользоввателя нашли, теперь подгружаем его данные (профайл, расширенные поля и тд)
/** @var modUserProfile $profile */
$profile = $user->getOne('Profile');
$extended = $profile->get('extended');
// прописываем все наши данные в плейсхолдеры, чтобы потом на странице их вывести
$modx->setPlaceholders($user, 'user.');
$modx->setPlaceholders($profile, 'user.');
$modx->setPlaceholders($extended, 'user.');
// тут у меня еще момент, что пользователь может указать, что у него профиль приватный и его никому показывать нельзя,
// поэтому в таком случае тоже 404 возвращаем. Но можно удалить
// profile private, we should return not found error
// if (isset($extended['private']) && $extended['private'] == 1) {
// $modx->sendForward($this->getOption('error_page'), $this->getOption('error_page_header', null, 'HTTP/1.0 404 Not Found'));
// }
// ну и отправляем нашу страницу с шаблоном профиля пользователя, где уже выводим всю его подноготную
$modx->sendForward($usersSection);
break;
}
Оперируйте контентом, выстраивая условия в шаблоне, который определен для ресурса, на который произошла замена.
Например:
1. Есть страница /users/ (список всех пользователей), со своим шаблоном, отображающий, допустим, всех пользователей.
2. В плагине, при совпадении шаблона адресного запроса, идет переадресация на /users/ методом sendForward + выставляются плейсхолдеры (допустим, user_id)
3. В шаблоне «списка всех пользователей» проверяем наличие этого плейсхолдеры и, исходя из результата, подставляем нужные данные:
Используя феном, можно так вообще кастомизировать виртуальную страницу без потери результативности, вплоть до сео. Вот, например, как реализована страница пользователя у меня:
Например:
1. Есть страница /users/ (список всех пользователей), со своим шаблоном, отображающий, допустим, всех пользователей.
2. В плагине, при совпадении шаблона адресного запроса, идет переадресация на /users/ методом sendForward + выставляются плейсхолдеры (допустим, user_id)
3. В шаблоне «списка всех пользователей» проверяем наличие этого плейсхолдеры и, исходя из результата, подставляем нужные данные:
[[+user_id:is=``:then=`обычная страница "списка всех пользователей"`:else=`формируем страницу профиля`]]
Используя феном, можно так вообще кастомизировать виртуальную страницу без потери результативности, вплоть до сео. Вот, например, как реализована страница пользователя у меня:
{extends 'template:1'}
{var $user_id = $_modx->getPlaceholder('user_id')}
{block 'meta'}
{if $user_id}
{var $user_name = $_modx->getPlaceholder('user_name')}
{var $pagetitle = $user_name ~ ' / Профиль пользователя'}
{var $avatar = 1 | user: 'photo'}
<title>{$pagetitle ~' :: '~ $_modx->config.site_name}</title>
<meta property="og:title" content="{$pagetitle}" />
<meta name="twitter:title" content="{$pagetitle}" />
{set $canonical_url = $_modx->resource.id | url : ['scheme' => 'full'] ~ $user_name ~ '/'}
<link rel="canonical" href="{$canonical_url}" />
<meta property="og:url" content="{$canonical_url}" />
<meta name="twitter:image" content="{$avatar ?: '/assets/images/users/default/120x120.png'}" />
<meta property="og:image" content="{$avatar ?: '/assets/images/users/default/120x120.png'}" />
<meta property="og:type" content="profile" />
{else}
{parent}
{/if}
{/block}
{block 'main'}
{parent}
{if $user_id}
//оформляем страницу пользователя
{else}
//оформляем общую страницу всех пользователей
{/if}
{/block}
[[+user_id:is=``:then=`обычная страница "списка всех пользователей"`:else=`формируем страницу профиля`]]
вот так сейчас у меня и реализовано! Но это только одна виртуальная страничка, а вот ваш вариант интересный, но феном пока даже с коментами плохо понимаю, потому как это почти пхп, а я в нем мягко говоря не шарю!Вот момента когда происходит вот это:
{if $user}
//оформляем страницу пользователя
{else}
//оформляем общую страницу всех пользователей
{/if}
как впихнуть еще три виртуальные страницы Публикации, Коменты, Избранное в эту часть:{if $user}
//оформляем страницу пользователя
{else}
ведь с учетом работы плагина получается, что страница списка пользователей расположена по адресу:www.sitename/users
а страница пользователя по адресу:www.sitename/users/[[!+user.id]]
а вот виртуальные вкладки, например публикации:www.sitename/users/[[!+user.id]]/posts
вот первые два варианта уживаются так как вы и написали, собственно у меня так и было еще давно:[[+user_id:is=``:then=`обычная страница "списка всех пользователей"`:else=`формируем страницу профиля`]]
А вот как теперь сделать так, чтобы прийти к контенту на виртуальной странице:www.sitename/users/[[!+user.id]]/posts
Ну, в принципе, можно сделать так (но я рекомендую все же обучиться fenom'y, т.к. с ним создавать сайты становится на порядок интереснее):
— качаете какое-нибудь дополнение аля switch
— в плагине, в зависимости от совпадения, передаете плейсхолдер user_page_type
— создаете чанк с оформлением под каждый «тип» страницы (основная, список пользователей, комментарии, избранное)
— далее, в шаблоне списка пользователей:
— качаете какое-нибудь дополнение аля switch
— в плагине, в зависимости от совпадения, передаете плейсхолдер user_page_type
— создаете чанк с оформлением под каждый «тип» страницы (основная, список пользователей, комментарии, избранное)
— далее, в шаблоне списка пользователей:
[[[[!switch?
&get=`[[+user_page_type]]`
&c1=`main`
&do1=`$имя_основного_чанка_профиля_пользователя`
&c2=`comments`
&do2=`$имя_чанка_комментариев_пользователя`
&default=`$имя_чанка_общей_страницы_пользователей`
]]]]
(пояснение по поводу структуры чанков)
Нууу я так то обучаюсь потихоньку. Просто учусь пока на готовых примерах, разбираю их на запчасти, а потом собираю. Поэтому если не сложно не могли бы вы написать, как бы выглядел вызов фенома, чтобы прийти к выводу того, что мне надо! Если конечно это не трудно и это не выглядит как километр кода, чтобы вас не напрягать! Заранее спасибо!
{var $user_page_type = $_modx->getPlaceholder('user_page_type')}
{switch $user_page_type}
{case 'main'}
...
{case 'comments'}
...
{case default}
...
{/switch}
мде, в общем чет нифига не работает по всякому. + виртуальные вкладки мне кажется тоже не работают, а если быть точнее то я не знаю как проверить!
Дело в том, что первый раз установив плагин я обрадовался, т.к. по запросу например страницы:
mysite.ru/users/2/posts
он вроде бы сделал редирект и страница просто обновилась на странице пользователя, я подумал, что и должно быть, что вроде бы как надо теперь кастомизировать алиас для этих страничек! Да вот не тут то было, оказалось, что он так реагирует на все алиасы:
Дело в том, что первый раз установив плагин я обрадовался, т.к. по запросу например страницы:
mysite.ru/users/2/posts
он вроде бы сделал редирект и страница просто обновилась на странице пользователя, я подумал, что и должно быть, что вроде бы как надо теперь кастомизировать алиас для этих страничек! Да вот не тут то было, оказалось, что он так реагирует на все алиасы:
http://mysite.ru/users/2/wadwfw
http://mysite.ru/users/2/awdafw
http://mysite.ru/users/2/sgsgse
У меня вот вопрос, а ресурсы надо в админке создавать с этими алиасами? Может в этом дело :D
Нужен только ресурс /users/, по айди которого плагин будет реализовывать sendForward.
вот это я лопух…
вот теперь вы понимаете почему я не очень люблю феном и пхп, много закорючек!
а вот вопрос, как это можно к динамичности привести? Чтобы он не по айди вычислял страницу а по алиасу?
$modx->sendForward(айди_страницы_users);
забыл то назначить ID…вот теперь вы понимаете почему я не очень люблю феном и пхп, много закорючек!
а вот вопрос, как это можно к динамичности привести? Чтобы он не по айди вычислял страницу а по алиасу?
$resource = $modx->getObject('modResource', array(
'alias' => 'ваш алиас'
));
$modx->sendForward($resource->get('id'));
Но это лишние запросы к бд, т.е. итоговая скорость обработки будет ниже.
Вы не поверите! Но чет не фурычит опять никак! Даже по прямой ссылке ничего не выдает!
Вот плагин сбахал, тот что выше с вашими модификациями, на страницу чтобы вывести контент уже до банального образа дошел:
на странице по адресу:
А когда я пытаюсь перейти на другой алиас, напимер сюда
У меня вот вопрос, может плагин корявый и где то что то конфликтует? Или же его надо доконструировать, что бы начало работать это условие:
Вот плагин сбахал, тот что выше с вашими модификациями, на страницу чтобы вывести контент уже до банального образа дошел:
[[*alias:is=`posts`:then=`Контент с Публикациями`]]
пробовал так же и вот этот вариант:{var $user_page_type = $_modx->getPlaceholder('user_page_type')}
{switch $user_page_type}
{case 'main'}
000
{case 'posts'}
111
{case default}
000
{/switch}
при чем когда загружаю странцу пользователя то вот это условие {case default} или {case 'main'} выполняется, т.е.на странице по адресу:
http://mysite.ru/users/[[!+user.id]]
выдает контент 000А когда я пытаюсь перейти на другой алиас, напимер сюда
http://mysite.ru/users/[[!+user.id]]/posts
то условие {case 'posts'} не срабатывает и один фиг отображается то, что было на стартовой странице пользователя!У меня вот вопрос, может плагин корявый и где то что то конфликтует? Или же его надо доконструировать, что бы начало работать это условие:
{var $user_page_type = $_modx->getPlaceholder('user_page_type')}
{switch $user_page_type}
{case 'main'}
000
{case 'posts'}
111
{case default}
000
{/switch}
Но вот тогда почему не работает это:[[*alias:is=`posts`:then=`Контент с Публикациями`]]
чет я запутался вообще!
[[*alias]] = поле ресурса. У вас оно все время будет полем от страницы «списка пользователей», которой вы подменяете ответ сервера.
Если вам нужно получить плейсхолдер, используйте [[+value]]
Если вам нужно получить плейсхолдер, используйте [[+value]]
та мне без разницы че надо получить, мне просто рабочий готовый вариант нужен, уже пол года ищу решение :D
Вот вы говорите [[+value]]! Да действительно, я чет тупанул, т.к. для [[*alias]] значение будет одно, потому как стоит символ "*" но вот как тогда должен выглядеть вызов, чтобы сработало то условие, которое мне нужно, а еще лучше расскажите подробнее как бы мне сделать, чтобы заработало это, вроде бы оно легче и быстрее:
Вот вы говорите [[+value]]! Да действительно, я чет тупанул, т.к. для [[*alias]] значение будет одно, потому как стоит символ "*" но вот как тогда должен выглядеть вызов, чтобы сработало то условие, которое мне нужно, а еще лучше расскажите подробнее как бы мне сделать, чтобы заработало это, вроде бы оно легче и быстрее:
{var $user_page_type = $_modx->getPlaceholder('user_page_type')}
{switch $user_page_type}
{case 'main'}
000
{case 'posts'}
111
{case default}
000
{/switch}
Просто скажите может в плагине надо что то докалякать, чтобы это заработало? Потому как просто вставкой в шаблон это не работает, а всегда возвращает значение {case default} или {case 'main'}
Для работы этого кода, вам нужно:
— установить дополнение pdoTools
— включить для него системную настройку pdotools_fenom_parser
Но, без базовых знаний js у вас могут возникнуть побочные проблемы, в случае, если у вас в шаблонах или чанках где-то присутствуют {}.
Да, к слову. Вам будет не лишним принудительно отключить кэширование для страницы списка пользователей:
редактирование ресурса -> закладка настройки -> убрать галочку у
пункта «Кэшируемый»
— установить дополнение pdoTools
— включить для него системную настройку pdotools_fenom_parser
Но, без базовых знаний js у вас могут возникнуть побочные проблемы, в случае, если у вас в шаблонах или чанках где-то присутствуют {}.
Да, к слову. Вам будет не лишним принудительно отключить кэширование для страницы списка пользователей:
редактирование ресурса -> закладка настройки -> убрать галочку у
пункта «Кэшируемый»
Да вот не тут то было, оказалось, что он так реагирует на все алиасы:— упс, а это уже моя недоработка, извиняюсь. В том участке кода, где реализуется $modx->sendForward, вам нужно прописать доп. условие, чтобы подмена страницы срабатывала только в диапазоне подходящих вам кейсов.
mysite.ru/users/2/wadwfw
mysite.ru/users/2/awdafw
mysite.ru/users/2/sgsgse
В противном случае не делать ничего, чтобы в случае неподходящего запроса пользователя перехватывал роутер 404 ошибки.
:D
Блин! А что именно допилить надо?
И кстати все что вы выше написали у меня установлено и включено, все же кое что у меня на феноме работает :D
Блин! А что именно допилить надо?
И кстати все что вы выше написали у меня установлено и включено, все же кое что у меня на феноме работает :D
Ну, можете изменить участок кода на такой:
//Страница профиля
if (count($chunks) == 2) {
//...
$modx->sendForward(айди_страницы_users);
}
//Подразделы
elseif (count($chunks) == 3) {
switch ($chunks[2]) {
//Сообщения пользователя
case 'posts':
//...
$modx->sendForward(айди_страницы_users);
break;
//Комментарии пользователя
case 'comments':
//...
$modx->sendForward(айди_страницы_users);
break;
//Избранное пользователя
case 'favorites':
//...
$modx->sendForward(айди_страницы_users);
break;
}
}
— нужно пояснить, что изменилось?
Понял! Ща опробуем!
итак вот собственно сам плагин:
<?php
// обрабатываем только события OnPageNotFound, на случай, если отметили галкой и другие в настройках плагина
if ($modx->event->name != 'OnPageNotFound') {
return false;
}
// на случай, если у нас настройки кто-то менял, получаем значение переменной, через которую передаются ссылки в modx от веб-сервера
$alias = $modx->context->getOption('request_param_alias', 'q');
// проверяем, что такая переменная есть, иначе и обрабатывать нечего
if (!isset($_REQUEST[$alias])) {
return false;
}
// наш запрос, который нужно разобрать и обработать
$request = $_REQUEST[$alias];
// разбиваем ссылку на составляющие,
// как правило, будет что-то вроде users/username, на выходе будет массив с этими значениями
$chunks = explode('/', $request);
if (end($chunks) == '') {
array_pop($chunks);
}
//Проверяем, что есть минимум 2 части ссылки (/users/ и /username/)
if (count($chunks) >= 2) {
switch ($chunks) {
//Cама страница пользователей
case 'users':
//проверяем существование пользователя
if (!empty($chunks[1]) && $modx->getCount('modUser', array('username' => $chunks[1]))) {
$user = $modx->getObject('modUser', array('username' => $chunks[1]));
if ($user && $user->get('active') == 1) {
$user_name = $user->get('username');
//Приводим юзернейм к правильному регистру
if ($chunks[1] != $user_name) {
$chunks[1] = $user_name;
$modx->sendRedirect(implode('/', $chunks));
}
//выставляем плейсхолдеры
$user_id = $user->get('id');
$modx->setPlaceholder('user_id', $user_id);
$modx->setPlaceholder('user_name', $user_name);
//Страница профиля
if (count($chunks) == 2) {
}
$resource = $modx->getObject('modResource', array(
'alias' => 'users'
));
$modx->sendForward($resource->get('id'));
}
}
break;
}
}
//Подразделы
elseif (count($chunks) == 3) {
switch ($chunks[2]) {
//Сообщения пользователя
case 'posts':
//...
$resource = $modx->getObject('modResource', array(
'alias' => 'users'
));
$modx->sendForward($resource->get('id'));
break;
//Комментарии пользователя
case 'comments':
//...
$resource = $modx->getObject('modResource', array(
'alias' => 'users'
));
$modx->sendForward($resource->get('id'));
break;
//Избранное пользователя
case 'favorites':
//...
$resource = $modx->getObject('modResource', array(
'alias' => 'users'
));
$modx->sendForward($resource->get('id'));
break;
}
}
и либо я чет не понял, но теперь на страницы пользователя вообще не заходит, потому как я стер свой плагин вот этот, скоторым хотя бы страница пользователя отображалась:switch ($chunks[0]) {
// на всякий случай проверяем, что у нас есть корневой ресурс для пользователей, страница users
if (!$users = $modx->getObject('modResource', ['alias' => users])) {
$modx->log(modX::LOG_LEVEL_ERROR, 'Entry point resource for users not found.');
return false;
}
// а теперь обрабатываем нам запрос.
switch ($chunks[0]) {
// сверяем первую часть ссылки с алиасом нашего ресурса для пользователей, должны совпадать
case $users->get('alias'):
// еще одна проверка существования ресурса (наверное можно удалить, взял пример из реального проекта)
if (!$usersSection = $modx->findResource($chunks[0])) {
return false;
}
// у меня ссылки генерились с html, поэтому я вырезаю расширение перед поиском самого юзера
$userAlias = str_replace('.html', '', $chunks[1]);
// еще одна проверка + убираем концевые слеши и редиректим на нормальную ссылку
if ($chunks[1] != $userAlias || (isset($chunks[2]) && $chunks[2] == '')) {
$modx->sendRedirect($chunks[0] . '/' . $userAlias);
}
// пробуем найти пользователя по username из запроса, если не нашли, то посылаем 404 заголовок
// тут важно вручную послать страницу 404, иначе, если вернем просто ошибку, то у нас опять запустится обработчик
// 404 ошибки, опять запустится наш плагин, опять тут будет ошибка и привет бесконечный круг и ААААА! Ничего не работает!!!!!
if (!$user = $modx->getObject('modUser', ['id' => $userAlias])) {
$modx->sendForward($this->getOption('error_page'), $this->getOption('error_page_header', null, 'HTTP/1.0 404 Not Found'));
}
// пользоввателя нашли, теперь подгружаем его данные (профайл, расширенные поля и тд)
/** @var modUserProfile $profile */
$profile = $user->getOne('Profile');
$extended = $profile->get('extended');
// прописываем все наши данные в плейсхолдеры, чтобы потом на странице их вывести
$modx->setPlaceholders($user, 'user.');
$modx->setPlaceholders($profile, 'user.');
$modx->setPlaceholders($extended, 'user.');
// тут у меня еще момент, что пользователь может указать, что у него профиль приватный и его никому показывать нельзя,
// поэтому в таком случае тоже 404 возвращаем. Но можно удалить
// profile private, we should return not found error
// if (isset($extended['private']) && $extended['private'] == 1) {
// $modx->sendForward($this->getOption('error_page'), $this->getOption('error_page_header', null, 'HTTP/1.0 404 Not Found'));
// }
// ну и отправляем нашу страницу с шаблоном профиля пользователя, где уже выводим всю его подноготную
$modx->sendForward($usersSection);
break;
}
Да, более того, вы не туда вставили условия.
Посмотрите мой исходный пример и сравните со своим — у вас вначале происходит условие:
а после вы пытаетесь проверить на это:
— в моем же примере второе условие было ВНУТРИ первого.
Посмотрите мой исходный пример и сравните со своим — у вас вначале происходит условие:
if (count($chunks) >= 2) {
//...
}
а после вы пытаетесь проверить на это:
elseif (count($chunks) == 3) {
//..
}
— в моем же примере второе условие было ВНУТРИ первого.
кокейси, вот собственно как я понял он должен выглядеть вот так:
конечно может я что то не так делаю в плане адресной строки:
вызывают так (мой username — K.STARK)
Хоть плюсиками вас поддержу! :D
<?php
// обрабатываем только события OnPageNotFound, на случай, если отметили галкой и другие в настройках плагина
if ($modx->event->name != 'OnPageNotFound') {
return false;
}
// на случай, если у нас настройки кто-то менял, получаем значение переменной, через которую передаются ссылки в modx от веб-сервера
$alias = $modx->context->getOption('request_param_alias', 'q');
// проверяем, что такая переменная есть, иначе и обрабатывать нечего
if (!isset($_REQUEST[$alias])) {
return false;
}
// наш запрос, который нужно разобрать и обработать
$request = $_REQUEST[$alias];
// разбиваем ссылку на составляющие,
// как правило, будет что-то вроде users/username, на выходе будет массив с этими значениями
$chunks = explode('/', $request);
if (end($chunks) == '') {
array_pop($chunks);
}
//Проверяем, что есть минимум 2 части ссылки (/users/ и /username/)
if (count($chunks) >= 2) {
switch ($chunks) {
//Cама страница пользователей
case 'users':
//проверяем существование пользователя
if (!empty($chunks[1]) && $modx->getCount('modUser', array('username' => $chunks[1]))) {
$user = $modx->getObject('modUser', array('username' => $chunks[1]));
if ($user && $user->get('active') == 1) {
$user_name = $user->get('username');
//Приводим юзернейм к правильному регистру
if ($chunks[1] != $user_name) {
$chunks[1] = $user_name;
$modx->sendRedirect(implode('/', $chunks));
}
//выставляем плейсхолдеры
$user_id = $user->get('id');
$modx->setPlaceholder('user_id', $user_id);
$modx->setPlaceholder('user_name', $user_name);
//Страница профиля
if (count($chunks) == 2) {
}
//Подразделы
elseif (count($chunks) == 3) {
switch ($chunks[2]) {
//Сообщения пользователя
case 'posts':
//...
$resource = $modx->getObject('modResource', array(
'alias' => 'users'
));
$modx->sendForward($resource->get('id'));
break;
//Комментарии пользователя
case 'comments':
//...
$resource = $modx->getObject('modResource', array(
'alias' => 'users'
));
$modx->sendForward($resource->get('id'));
break;
//Избранное пользователя
case 'favorites':
//...
$resource = $modx->getObject('modResource', array(
'alias' => 'users'
));
$modx->sendForward($resource->get('id'));
break;
}
}
$resource = $modx->getObject('modResource', array(
'alias' => 'users'
));
$modx->sendForward($resource->get('id'));
}
}
break;
}
}
но один фиг, это ломает мой вызов и перестает работать страница пользователя, т.е. выдает 404 и по ID и по Usernameконечно может я что то не так делаю в плане адресной строки:
вызывают так (мой username — K.STARK)
http://cwonline.ru/users/K.STARK
http://cwonline.ru/users/k.stark
http://cwonline.ru/users/kstark
не робит по всякому! Я уже запутался и вас запутал, и забадал! Вот думаю, может вы вышлите мне готовый вариант как у вас сделано и я попробую у себя интегрировать? Просто тот плагин что был до этого у меня для тсраницы пользователя был достаточно просто для понимания, ваще без заморочек. Поставил, плейсхолдеры с префикосм нафигачил и дело с концом! А тут… чет туплю сильно… но очень хочу разобраться!Хоть плюсиками вас поддержу! :D
нашел ошибку у себя в том плагине, который вы предложили, но тем не менее чет ничего не работает :(
Выглядит он как вы описали:
Выглядит он как вы описали:
<?php
// обрабатываем только события OnPageNotFound, на случай, если отметили галкой и другие в настройках плагина
if ($modx->event->name != 'OnPageNotFound') {
return false;
}
// на случай, если у нас настройки кто-то менял, получаем значение переменной, через которую передаются ссылки в modx от веб-сервера
$alias = $modx->context->getOption('request_param_alias', 'q');
// проверяем, что такая переменная есть, иначе и обрабатывать нечего
if (!isset($_REQUEST[$alias])) {
return false;
}
// наш запрос, который нужно разобрать и обработать
$request = $_REQUEST[$alias];
// разбиваем ссылку на составляющие,
// как правило, будет что-то вроде users/username, на выходе будет массив с этими значениями
$chunks = explode('/', $request);
if (end($chunks) == '') {
array_pop($chunks);
}
//Проверяем, что есть минимум 2 части ссылки (/users/ и /username/)
if (count($chunks) == 2) {
switch ($chunks) {
//Cама страница пользователей
case 'users':
//проверяем существование пользователя
if (!empty($chunks[1]) && $modx->getCount('modUser', array('username' => $chunks[1]))) {
$user = $modx->getObject('modUser', array('username' => $chunks[1]));
if ($user && $user->get('active') == 1) {
$user_name = $user->get('username');
//Приводим юзернейм к правильному регистру
if ($chunks[1] != $user_name) {
$chunks[1] = $user_name;
$modx->sendRedirect(implode('/', $chunks));
}
//выставляем плейсхолдеры
$user_id = $user->get('id');
$modx->setPlaceholder('user_id', $user_id);
$modx->setPlaceholder('user_name', $user_name);
//Страница профиля
if (count($chunks) == 2) {
//...
$modx->sendForward(1226);
}
//Подразделы
elseif (count($chunks) == 3) {
switch ($chunks[2]) {
//Сообщения пользователя
case 'posts':
//...
$modx->sendForward(1226);
break;
//Комментарии пользователя
case 'comments':
//...
$modx->sendForward(1226);
break;
//Избранное пользователя
case 'favorites':
//...
$modx->sendForward(1226);
break;
}
}
$modx->sendForward(1226);
}
}
break;
}
}
//иначе редиректим
При чем не работает даже страница пользователя
Для профилей в виде www.website.com/sampleusername/posts:
На каждую страницу пользователя создается отдельный ресурс, в котором ловятся плейсхолдеры
На каждую страницу пользователя создается отдельный ресурс, в котором ловятся плейсхолдеры
<?php
if ($modx->event->name != 'OnPageNotFound') {return false;}
$alias = $modx->context->getOption('request_param_alias');
if (!isset($_REQUEST[$alias])) {return false;}
$request = $_REQUEST[$alias];
$tmp = explode('/', $request);
if (count($tmp) >= 1) {
$section = 1;//id главной страницы профиля
$name = str_replace('.html', '', $tmp[0]);
if ($tmp[0] != $name || (isset($tmp[1]) && $tmp[1] == '')) {
$modx->sendRedirect('/' . $name);
}
switch($tmp[1]) {
case 'posts':
$section = 2;//id страницы постов
break;
//
case 'comments':
$section = 3;//id страницы комментариев
break;
//
case 'favourites':
$section = 4;//id страницы избранного
break;
//
default:
$section = 1;
break;
}
if ($user = $modx->getObject('modUser', array('username' => $name))) {
$id = $user->get('id');
$joined = $user->get('createdon');
$profile = $user->getOne('Profile');
//
$modx->setPlaceholders(array(
'id' => $user->get('id'),
'username' => $name,
'fullname' => $profile->get('fullname'),
'joined' => $user->get('createdon'),
),'user_');
//
} else {
$section = 5;//id страницы 404
}
$modx->sendForward($section);
}
p.s. табуляция тут спадает( $section = 5;//id страницы 404
— это лучше убрать, а в sendForward добавить проверку заполненности $section, в противном случае не выполнять ничего. Если выполнять $modx->sendForward(айди_страницы_404), то будет отдаваться некорректный код ответа, ну и последующие плагины на OnPageNotFound не будут корректно обрабатываться.
согласен, на скорую руку добавил
та не, мне бы сбахать, чтобы все динамично было…
Чтобы не создавать дохрена ресурсов и не привязывать перехват алиасов к конкретному ресурсу по его индентификатору!
Потому как у меня несколько контекстов и на каждом присутствует данная модель списка и страниц пользователя и поэтому бабахать дофига ресурсов и на каждый конекст плагин, чет не очень хочется, перспективы хреновые, потому черт ногу сломит!
И тем не менее, спасибо!
Чтобы не создавать дохрена ресурсов и не привязывать перехват алиасов к конкретному ресурсу по его индентификатору!
Потому как у меня несколько контекстов и на каждом присутствует данная модель списка и страниц пользователя и поэтому бабахать дофига ресурсов и на каждый конекст плагин, чет не очень хочется, перспективы хреновые, потому черт ногу сломит!
И тем не менее, спасибо!
передавай тогда уникальный идентификатор в плейсхолдер, например,
p.s. уходи от контекстов, если сайт только разрабатывается. для двух языков еще нормально, но потом будет каша из огромного количества ресурсов + по дизайну сложно что-то экстра конкретное сделать для страницы с определенным ID (3 языка = перечисление трёх id и т.д.)
case 'comments':
$page_type = 'comments';
…$modx->setPlaceholder('page_type', $page_type);
и на общей странице через fenom выводи нужный контентp.s. уходи от контекстов, если сайт только разрабатывается. для двух языков еще нормально, но потом будет каша из огромного количества ресурсов + по дизайну сложно что-то экстра конкретное сделать для страницы с определенным ID (3 языка = перечисление трёх id и т.д.)
та ушел бы, если бы мозгов хватило :D
А то что вы предлагаете уже пробовал выше, говорю ж не работает :(
А то что вы предлагаете уже пробовал выше, говорю ж не работает :(
просто понимаете какое дело, я как уже писал вышел практически полностью не шарю в пхп и даже написать плагин для меня было бы довольно таки сложно, поэтому если вам не трудно, не могли бы вы поделиться рабочим примером и с хотя бы небольшим описанием того, как на странице вывести феномом страницу пользователя! Я уже очень долго бьюсь, но так и не нашел решения, которое бы работало у меня… Благо хотя бы нашелся плагин который работает и вызывает страницу пользователя. Вот я прям очень хочу под него интегрировать виртуальные вкладки. Просто пока не один из перечисленных примеров не помог, а может и написан с мааааленькой ошибкой, которую я не найду, поскольку нифига не шарю в пхп :(
Как в моем комменте выше, если вы не хотите (извиняюсь, что переходил на «ты» – увидел тёзку, расслабился)) создавать отдельные ресурсы для каждой из виртуальных страниц, но у вас есть одна общая страница, то нужно передавать любой идентификатор на неё.
Если плагин и все страницы (username/posts, username/comments и т.д.) работают +
если установлен pdoTools и в настройках сайта значения: pdotools_fenom_default, pdotools_fenom_modx, pdotools_fenom_parser,pdotools_fenom_php = ДА, то с помощью Fenom это будет примерно так:
{if $page_type == 'comments'}
[[$чанк_комментов]] или контент
{elseif $page_type == 'favorites'}
[[$чанк_избранного]] или контент
{/if}
Шаблонизатор Fenom
или просто подставляете нужный чанк на странице одной строчкой:
Если плагин и все страницы (username/posts, username/comments и т.д.) работают +
если установлен pdoTools и в настройках сайта значения: pdotools_fenom_default, pdotools_fenom_modx, pdotools_fenom_parser,pdotools_fenom_php = ДА, то с помощью Fenom это будет примерно так:
{if $page_type == 'comments'}
[[$чанк_комментов]] или контент
{elseif $page_type == 'favorites'}
[[$чанк_избранного]] или контент
{/if}
Шаблонизатор Fenom
или просто подставляете нужный чанк на странице одной строчкой:
[[$virtualpage_{$page_type}]]
или[[$virtualpage_[[!+page_type]]]]
не, ну это все уже понятно! А я имею ввиду как плагин ваш должен выглядеть? С учетом всех всех изменений и чтобы удовлетворял условия:
1. Адрес страницы пользователя выглядит так: mysite.com/users/[[+идентификатор пользователя]]
2. В плагине учтены моменты с динамической. Ко всем алиасам со значением users применяется работа данного плагина, а так же формируются вкладки.
3. В плагине учтена динамика для вкладок. (См. выше)
Т.е.
Тема с плейсхолдерами конечно мне понятна, но как это технически организовывается? Добавляются ли значения в плагин или нет? Мне нужен просто готовый плагин с готовым вызовом, как это делается! Я ж говорю, дубина я совсем, если давать мне все по кусочкам, умею только разбирать и собираться обратно пока :(
Заранее спасибо!
1. Адрес страницы пользователя выглядит так: mysite.com/users/[[+идентификатор пользователя]]
2. В плагине учтены моменты с динамической. Ко всем алиасам со значением users применяется работа данного плагина, а так же формируются вкладки.
3. В плагине учтена динамика для вкладок. (См. выше)
Т.е.
Тема с плейсхолдерами конечно мне понятна, но как это технически организовывается? Добавляются ли значения в плагин или нет? Мне нужен просто готовый плагин с готовым вызовом, как это делается! Я ж говорю, дубина я совсем, если давать мне все по кусочкам, умею только разбирать и собираться обратно пока :(
Заранее спасибо!
плагин примерно такой (не проверял):
если fenom включен, то на странице профиля примерно так (наобум):
<?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] == 'users' && count($tmp) >= 2) {
$section = 1; //id страницы профиля
$name = str_replace('.html', '', $tmp[1]);
if ($tmp[1] != $name || !isset($tmp[2])) {
$modx->sendRedirect($tmp[0] . '/' . $name);
}
switch($tmp[2]) {
case 'posts':
$page_type = 'posts';
break;
case 'comments':
$page_type = 'comments';
break;
case 'favourites':
$page_type = 'favourites';
break;
default:
$page_type = 'main';
break;
}
if ($user = $modx->getObject('modUser', array('username' => $name))) {
$id = $user->get('id');
$joined = $user->get('createdon');
$profile = $user->getOne('Profile');
$fullname = $profile->get('fullname');
$photo = $profile->get('photo');
//
$modx->setPlaceholder('page_type', $page_type);
$modx->setPlaceholders(array(
'id' => $id,
'joined' => $joined,
'username' => $name,
'fullname' => $fullname,
'photo' => $photo,
),'user_');
/////// может пригодиться
$additional = $modx->getObject('TicketAuthor', $id);
$modx->setPlaceholder('user_posts_count', $additional->tickets);
$modx->setPlaceholder('user_comments_count', $additional->comments);
$modx->setPlaceholder('user_favourites_count', $additional->stars_tickets);
$modx->setPlaceholder('pagetitle', $fullname);
/////// может пригодиться//
$modx->sendForward($section);
}
}
если fenom включен, то на странице профиля примерно так (наобум):
<ul class="tabs">
<li class="{if $page_type == 'main'}active{/if}"><a href="/users/{$user_username}">Профиль</a></li>
<li class="{if $page_type == 'posts'}active{/if}"><a href="/users/{$user_username}/posts">Посты<span class="count">{$user_posts_count}</span></a></li>
<li class="{if $page_type == 'comments'}active{/if}"><a href="/users/{$user_username}/comments">Комменты<span class="count">{$user_comments_count}</span></a></li>
<li class="{if $page_type == 'favourites'}active{/if}"><a href="/users/{$user_username}/favourites">Избранное<span class="count">{$user_favourites_count}</span></a></li>
</ul>
<!--чанк-->[[$virtualpage_{$page_type}]]<!--чанк//-->
p.s. в чанке плейсхолдеры через [[!+плейсхолдер]], либо вызывать чанк через {$_modx->getChunk(…
Скорее всего у вас проблемы с настройками htaccess или системными настройками суффикса html-документов.
Попробуйте в плагине выше заменить:
На это:
А вообще, правильнее было бы убрать суффикс '.html' для документов.
Попробуйте в плагине выше заменить:
$name = str_replace('.html', '', $tmp[1]);
if ($tmp[1] != $name || !isset($tmp[2])) {
$modx->sendRedirect($tmp[0] . '/' . $name);
}
На это:
$name = str_replace('.html', '', $tmp[1]);
if (!isset($tmp[2])) {
$modx->sendRedirect($tmp[0] . '/' . $name);
}
А вообще, правильнее было бы убрать суффикс '.html' для документов.
убран! С самого начала пользования!
кажется понял! Вот это условие:
users
:D
$section = 1; //id страницы профиля
как бы мне его заменить на динамическое определение страницы по алиасу:users
:D
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.