<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss version="2.0">
	<channel>
		<title>Predvoditelev.RU</title>
		<link>http://predvoditelev.ru/</link>
		<description>Личный сайт Предводителева Сергея</description>
		<pubDate>Mon, 19 Jul 2010 17:35:05 +0000</pubDate>
		<language>en-ru</language>
		<generator>MaxSite CMS (http://max-3000.com/)</generator>
		<copyright>Copyright 2010, http://predvoditelev.ru/</copyright>
				<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/predvoditelev" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="predvoditelev" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
			<title><![CDATA[Техника работы с META&#45;тэгами Description и Keywords в MODx]]></title>
			<link>http://predvoditelev.ru/page/modx-work-with-meta</link>
			<guid>http://predvoditelev.ru/page/modx-work-with-meta</guid>
			<pubDate>Mon, 19 Jul 2010 17:35:05 +0000</pubDate>
			<category><![CDATA[MODx]]></category>
			<description><![CDATA[<p>
В этой статье хотелось бы рассказать об одном из вариантов реализации работы с META-тэгами <em>Description</em> и <em>Keywords</em> в MODx.
</p>

<p>
Если на сайте используются уникальные описания и ключевые слова, которые нельзя генерировать автоматически, то достаточно создать два TV-параметра <tt>meta-description</tt> и <tt>meta-keywords</tt> с типом ввода <tt>Text</tt>. А затем подключить их в шаблоне:
</p>

<a name="cut"></a>

<pre class="brush: html;">...
&lt;head&gt;
	...
	&lt;meta name=&quot;keywords&quot; content=&quot;[*meta-keywords*]&quot; /&gt;
	&lt;meta name=&quot;description&quot; content=&quot;[*meta-description*]&quot; /&gt;
	...
&lt;/head&gt;
...</pre>

<p>
Если же на сайте есть страницы, для которых эти META-тэги можно генерировать автоматически, то можно использовать следующий способ: так же создаем два TV-параметра <tt>meta-description</tt> и <tt>meta-keywords</tt>, но в шаблоне выводим META-тэги с помощью сниппета.
</p>

<p>
Назовем сниппет <tt>html_getMeta</tt>. У сниппета будет всего один параметр <tt>type</tt>, который может принимать значения <em>description</em> или <em>keywords</em>. В зависимости от этого параметра будет возвращаться соответственно либо описание страницы, либо ключевые слова.
</p>

<p>
Получить значения TV-параметров в сниппете можно следующим образом:
</p>

<pre class="brush: php;">$keywords = $modx-&gt;getTemplateVar('meta-keywords', '*', $modx-&gt;documentIdentifier);
$keywords = $keywords['value'];

$description = $modx-&gt;getTemplateVar('meta-description', '*', $modx-&gt;documentIdentifier);
$description = $description['value'];</pre>

<p>
Логика такая. Если у документа заполнен соответствующий параметр, то выводим его, даже если значения для данного типа документов генерируются автоматически. Если же параметр не заполнен и значения для документа генерируются автоматически, то генерируем их и возвращаем.
</p>

<p>
В шаблоне вызов сниппета выглядит так:
</p>

<pre class="brush: php;">...
&lt;head&gt;
	...
	&lt;meta name=&quot;keywords&quot; content=&quot;[[html_getMeta? &amp;type=`keywords`]]&quot; /&gt;
	&lt;meta name=&quot;description&quot; content=&quot;[[html_getMeta? &amp;type=`description`]]&quot; /&gt;
	...
&lt;/head&gt;
...</pre>

<p>
Генерировать автоматически значения META-тэгов можно, например, для документов с определенным типом шаблона. Пример подобного сниппета:
</p>

<pre class="brush: php;">&lt;?php
$out = '';


// Возвращаем ключевые слова
if ($type=='keywords') {
	$keywords = $modx-&gt;getTemplateVar('meta-keywords', '*', $modx-&gt;documentIdentifier);	
	$keywords = $keywords['value'];
	
	// Если ключевые слова не прописаны вручную - можем их сгенерировать
	if ($keywords=='') {
		
		// Для примера генерируем для документов, у которых установлен шаблон с ID = 5
		if ($modx-&gt;documentObject['template']==5) {
			$keywords = 'документ ID шаблон '.$modx-&gt;documentObject['pagetitle'];
		}
		
		// 
		// Здесь могут идти генерации ключевых слов ещё для каких-либо документов
		//
		
	}
	
	$out.= $keywords;
}


// Возвращаем описание
if ($type=='description') {
	$description = $modx-&gt;getTemplateVar('meta-description', '*', $modx-&gt;documentIdentifier);
	$description = $description['value'];
	
	// Если описание не прописано вручную - можем их сгенерировать
	if ($description=='') {
		
		// Для примера генерируем для документов, у которых установлен шаблон с ID = 5
		if ($modx-&gt;documentObject['template']==5) {
			$description = 'Описание документа с ID равным 5 и заголовком '.$modx-&gt;documentObject['pagetitle'];
		}
		
		// 
		// Здесь могут идти генерации описаний ещё для каких-либо документов
		//
		
	}
	
	$out.= $description;
}


echo $out;
?&gt;</pre>

<p>
В принципе подобную технику работы с META-тэгами можно применить и для произвольных TV-параметров, которые можно генерировать автоматически.
</p><a href="http://predvoditelev.ru/page/modx-work-with-meta#comments"> Обсудить</a>]]></description>
		</item>
				<item>
			<title><![CDATA[Изображение с фиксированной высотой и 100% шириной]]></title>
			<link>http://predvoditelev.ru/page/img_100p_fix_height</link>
			<guid>http://predvoditelev.ru/page/img_100p_fix_height</guid>
			<pubDate>Wed, 02 Sep 2009 12:32:42 +0000</pubDate>
			<category><![CDATA[CSS и Верстка]]></category>
			<description><![CDATA[<p>
	Бывают случаи, когда необходимо показать изображение, которое тянется по ширине на <tt>100%</tt>, но при этом имеет
	фиксированную высоту. Также изображение должно сохранять свои пропорции (то есть всё, что не влазит по высоте - обрезается).
	Если написать вот так:
</p>

<a name="cut"></a>

<pre class="brush: html;">&lt;img src=&quot;image.jpg&quot; width=&quot;100%&quot; height=&quot;300&quot; alt=&quot;&quot;&gt;</pre>

<p>
	... то картинка будет растягиваться не пропорционально. Для того, чтобы это исправить используем слой-обертку:
</p>

<pre class="brush: html;">&lt;div class=&quot;b-img-wrap&quot;&gt;
	&lt;img src=&quot;image.jpg&quot; width=&quot;100%&quot; alt=&quot;&quot;&gt;
&lt;/div&gt;</pre>

<p>
	Стили:
</p>

<pre class="brush: css;">.b-img-wrap {
	height: 300px;
	overflow: hidden;
}</pre>

<p>
	Как вы заметили, у изображение убрали параметр <tt>height</tt>, те высота изображения будет высчитываться
	браузером автоматически и изображение будет пропорционально изменять свои размеры. Для того, чтобы
	сохранилась фиксированная высота - задаём её слою-обёртке и присваиваем ему свойство <tt>overflow: hidden;</tt>.
	Таким образом всё, что выходит за пределы слоя будет скрываться.
</p>

<h2>Метод масштабирования изобажения</h2>

<p>
	Во всех популярных браузерах кроме Internet Explorer ниже 8й версии используется качественный
	<strong>бикубический метод</strong> масштабирования изображения. А вот IE6 и IE7 используют <strong>метод копирования
	ближайшего пикселя</strong> - поэтому масштабированное изображение в этих браузерах получается менее качественным.
	С IE6 мы ничего	не сделаем, а вот <strong>в IE7 мы можем решить проблему</strong> с помощью CSS-свойства
	<tt>-ms-interpolation-mode</tt>. Это свойство определяет каким способом масштабировать изображения и может
	принимать одно из следующих значений:
</p>

<ul>
	<li><tt>nearest-neighbor</tt> (метод копирования ближайшего пикселя) – по умолчанию</li>
	<li><tt>bicubic</tt> (бикубический метод)</li>
</ul>

<p>
	Соответственно используем CSS-хак для IE7:
</p>

<pre class="brush: css;">*+html .b-img-wrap IMG { -ms-interpolation-mode: bicubic; }</pre>


<h2>Пример к статье</h2>
<p>
	<a href="http://predvoditelev.ru/dc/L2V4YW1wbGVzL2ltZ18xMDBwX2ZpeF9oZWlnaHQvaW1nXzEwMHBfZml4X2hlaWdodC56aXA=" title="/examples/img_100p_fix_height/img_100p_fix_height.zip" >Скачать пример</a> <sup title="Количество переходов">24</sup> (img_100p_fix_height.zip, ~352Kb) |
	<a href="/examples/img_100p_fix_height/" target="_blank">Посмотреть пример</a>
</p>

<p>Работоспособность была проверена в следующих браузерах:</p>

<ul>
	<li>Mozilla Firefox 3.5</li>
	<li>Opera 9.64</li>
	<li>Safari 4 (win)</li>
	<li>Internet Explorer 6, 7, 8</li>
</ul><a href="http://predvoditelev.ru/page/img_100p_fix_height#comments"> Обсудить</a>]]></description>
		</item>
				<item>
			<title><![CDATA[Создание тянущейся карусели с помощью jQuery + jCarousel]]></title>
			<link>http://predvoditelev.ru/page/jcarousel_100p</link>
			<guid>http://predvoditelev.ru/page/jcarousel_100p</guid>
			<pubDate>Sat, 29 Aug 2009 00:23:03 +0000</pubDate>
			<category><![CDATA[CSS и Верстка]]></category>
			<description><![CDATA[<p>
	В этой статье хотелось бы рассмотреть создание карусели изображений (и не только) со 100% шириной.
	Для примера будем делать карусель новостей. Каждая новость &mdash; отдельный блок фиксированный
	как по вертикали, так и по горизонтали, содержащий картинку, заголовок и краткий анонс.
	Для реализации используем популярный js-фреймворк <strong>jQuery</strong> и плагин для создания каруселей &mdash; <strong>jCarousel</strong>.
</p>

<a name="cut"></a>

<p>
	То, что в итоге у нас получится можно посмотреть <a href="/examples/jcarousel_100p/" target="_blank">здесь</a>.
</p>

<p>
	Для начала скачиваем последнюю версию jQuery (<a href="/go.php?http://jquery.com/" target="_blank">http://jquery.com/</a>)
	и плагин jCarousel (<a href="/go.php?http://sorgalla.com/jcarousel/" target="_blank">http://sorgalla.com/jcarousel/</a>).
	На момент написания статьи последние версии jQuery 1.3.2 и jCarousel 0.2.3.
</p>

<p>
	Подключаем jQuery и jCarousel к нашей странице. Из jCarousel нам понадобится сам файл плагина (<tt>jquery.jcarousel.pack.js</tt>)
	и файл со стилями (<tt>jquery.jcarousel.css</tt>). Теперь все необходимые инструменты у нас есть. Создаём список новостей:
</p>

<pre class="brush: html;">&lt;div class=&quot;b-news&quot;&gt;
	&lt;ul&gt;
		&lt;li&gt;
			&lt;div class=&quot;picture&quot;&gt;&lt;img src=&quot;images/news1.jpg&quot; width=&quot;300&quot; height=&quot;200&quot; alt=&quot;&quot;&gt;&lt;/div&gt;
			&lt;div class=&quot;title&quot;&gt;Новость номер 1&lt;/div&gt;
			&lt;div class=&quot;desc&quot;&gt;Краткий анонс первой новости&lt;/div&gt;
		&lt;/li&gt;
		...
		&lt;li&gt;
			&lt;div class=&quot;picture&quot;&gt;&lt;img src=&quot;images/news8.jpg&quot; width=&quot;300&quot; height=&quot;200&quot; alt=&quot;&quot;&gt;&lt;/div&gt;
			&lt;div class=&quot;title&quot;&gt;Новость номер 8&lt;/div&gt;
			&lt;div class=&quot;desc&quot;&gt;Краткий анонс восьмой новости&lt;/div&gt;
		&lt;/li&gt;
	&lt;/ul&gt;
&lt;/div&gt;</pre>

<p>
	Инициализация карусели довольно простая:
</p>

<pre class="brush: javascript;">$(document).ready(function(){
	$('.b-news UL').jcarousel({ scroll: 1 });
});</pre>

<p>
	Параметр <tt>scroll</tt> определяет сколько блоков прокручивать за раз.
</p>

<p>
	Теперь пропишем стили для карусели. Нам нужно задать <tt>width: 100%</tt> для контейнера, определить размеры
	элементов, а также местоположение и внешний вид кнопок управления (прокрутка вперед/назад).
	В коде даны комментарии:
</p>

<pre class="brush: css;">/* Растягиваем контейнер на 100% по ширине */
.b-news .jcarousel-container-horizontal { width: 100%; }
.b-news .jcarousel-clip-horizontal { width: 100%; }

/* Задаем размер одного блока */
.b-news .jcarousel-item, .b-news .jcarousel-list LI { width: 310px; height: 250px; }

/* Задаем внешний вид и расположение кнопок управления */
.b-news .jcarousel-next-horizontal {
	position: absolute;
	top: 80px;
	right: 15px;
	width: 30px;
	height: 30px;
	cursor: pointer;
	background: transparent url(../images/btn_next.gif) no-repeat 0 0;
}
.b-news .jcarousel-next-disabled-horizontal,
.b-news .jcarousel-next-disabled-horizontal:hover,
.b-news .jcarousel-next-disabled-horizontal:active { cursor: default; background-position: -30px 0; }
.b-news .jcarousel-prev-horizontal {
	position: absolute;
	top: 80px;
	left: 15px;
	width: 30px;
	height: 30px;
	cursor: pointer;
	background: transparent url(../images/btn_prev.gif) no-repeat 0 0;
}
.b-news .jcarousel-prev-disabled-horizontal,
.b-news .jcarousel-prev-disabled-horizontal:hover,
.b-news .jcarousel-prev-disabled-horizontal:active { cursor: default; background-position: -30px 0; }</pre>

<p>
	Осталось навести красивости и получим отличную карусель для новостей.
</p>


<h2>Пример к статье</h2>
<p>
	<a href="http://predvoditelev.ru/dc/L2V4YW1wbGVzL2pjYXJvdXNlbF8xMDBwL2pjYXJvdXNlbF8xMDBwLnppcA==" title="/examples/jcarousel_100p/jcarousel_100p.zip" >Скачать пример</a> <sup title="Количество переходов">502</sup> (jcarousel_100p.zip, ~160Kb) |
	<a href="/examples/jcarousel_100p/" target="_blank">Посмотреть пример</a>
</p>

<p>Работоспособность была проверена в следующих браузерах:</p>

<ul>
	<li>Mozilla Firefox 3.5</li>
	<li>Opera 9.64</li>
	<li>Safari 4 (win)</li>
	<li>Internet Explorer 6, 7, 8</li>
</ul><a href="http://predvoditelev.ru/page/jcarousel_100p#comments"> Обсудить</a>]]></description>
		</item>
				<item>
			<title><![CDATA[Рекурсивная смена прав доступа на PHP]]></title>
			<link>http://predvoditelev.ru/page/php_recursion_chmod</link>
			<guid>http://predvoditelev.ru/page/php_recursion_chmod</guid>
			<pubDate>Mon, 27 Apr 2009 21:28:08 +0000</pubDate>
			<category><![CDATA[PHP, Web-мастеринг]]></category>
			<description><![CDATA[<p>
	Возникла тут задачка. Необходимо <strong>сменить права доступа</strong> на все файлы, папки и подпапки в
	определенной директории. Я наивный думал, что такое должно быть реализовано в каждом
	FTP-браузере, но в моём любимом Total Commander'е такой функции не обнаружилось.
	Пришлось писать скрипт.
</p>

<a name="cut"></a>

<p>
	Как обычно сначала немного погуглил - готового решения не нашел.
	В общем по кусочкам собрал вот такой вот простенький скриптик:
</p>

<pre class="brush: php;">&lt;?
 
/*                                                      */
/*  СКРИПТ ДЛЯ РЕКУРСИВНОЙ СМЕНЫ ПРАВ НА ФАЙЛЫ И ПАПКИ  */
/*                                                      */
/*   Автор: Предводителев Сергей (Niko)                 */
/*   http://predvoditelev.ru                            */
/*                                                      */
/*   27.04.2009                                         */
/*                                                      */
 
 
// Папка, в которой находятся файлы и папки для изменения прав
$PARENT_DIR = '/home/*****';
 
$FILE_MODE = 0644; // права на файлы
$DIR_MODE = 0755; // права на папки
 
function chmodex($file) {
global $PARENT_DIR;
global $FILE_MODE;
global $DIR_MODE;
    
    if ( file_exists($file) ) {
        if ( is_dir($file) ) {
            if ( !($file==$PARENT_DIR) ) { chmod( $file, $DIR_MODE ); }
            $handle = opendir( $file );
            while( $filename = readdir($handle) )
            if ( $filename != &quot;.&quot; &amp;&amp; $filename != &quot;..&quot; ) chmodex( $file.&quot;/&quot;.$filename );
                closedir($handle);
        } else {
            chmod( $file, $FILE_MODE );
        }
    }
}
 
chmodex($PARENT_DIR);
 
?&gt;</pre>

<p>Для использования скрипта необходимо:</p>

<ul>
	<li>Открыть файл <tt>chmodex.php</tt> (см. приложенный архив).</li>
	<li>Указать <tt>$PARENT_DIR</tt> - это путь к папке, в которой необходимо изменить права доступа.</li>
	<li>Указать <tt>$FILE_MODE</tt> и <tt>$DIR_MODE</tt> - это права доступа, которые необходимо установить для файлов и папок соответственно.</li>
	<li>Залить скрипт <tt>chmodex.php</tt> в папку, в которой необходимо поменять права 
	доступа, те в папку, которую указали в <tt>$PARENT_DIR</tt>. Права доступа самой 
	папки <tt>$PARENT_DIR</tt> измененены не будут.</li>
	<li>Через браузер запустить <tt>chmodex.php</tt>.</li>
	<li>Если после запуска скрипта - белый экран, то значит всё прошло успешно :).</li>
</ul>

<p style="text-align: right;"><a href="http://predvoditelev.ru/dc/L2V4YW1wbGVzL2NobW9kZXguemlw" title="/examples/chmodex.zip" >Скачать скрипт</a> <sup title="Количество переходов">741</sup> (chmodex.zip, ~ 0.6 kb)</p><a href="http://predvoditelev.ru/page/php_recursion_chmod#comments"> Обсудить</a>]]></description>
		</item>
				<item>
			<title><![CDATA[Установка плагина Popularity Contest на WordPress 2.7 ]]></title>
			<link>http://predvoditelev.ru/page/wordpress_install_popularity_contest</link>
			<guid>http://predvoditelev.ru/page/wordpress_install_popularity_contest</guid>
			<pubDate>Wed, 04 Feb 2009 14:37:59 +0000</pubDate>
			<category><![CDATA[Web-мастеринг]]></category>
			<description><![CDATA[<p>
	Во время разработки очередного шаблона для <strong>WordPress 2.7</strong> столкнулся с проблемой
	при установке плагина <strong>Popularity Contest</strong>.
	Этот плагин предназначен для вывода самых популярных постов на сайте.
</p>

<a name="cut"></a>

<p>
	Скачал плагин Popularity Contest c <a href="http://alexking.org/projects/wordpress">оффициального сайта</a>.
	На момент написания поста последняя версия - 1.3b3 от 16 декабря 2007 года.
	Как видим плагин давно уже не обновлялся. Установка по идее довольно простая:
</p>

<ol>
	<li>Копируем файл <tt>popularity-contest.php</tt> в папку <tt>\wp-content\plugins\</tt>.</li>
	<li>Активировать плагин в разделе <i>Плагины</i> панели управления WordPress.</li>
</ol>

<p>
	Но при активации плагина WordPress выдавал следующую ошибку: 
	<i>&ldquo;Плагин не может быть активирован, поскольку он вызвал <b>фатальную ошибку</b>&ldquo;</i>.
</p>

<p>Немного погуглив нашел решение:</p>

<p>1) Открываем <tt>popularity-contest.php</tt> и заменяем строчку 59:</p>
<p><i>require('../../wp-blog-header.php');</i></p>
<p>на</p>
<p><i>require('../wp-blog-header.php');</i></p>

<p>2) Необходимо создать таблицы в базе данных. Вот код:</p>
<pre class="brush: sql;">CREATE TABLE IF NOT EXISTS `wp_ak_popularity` (
`post_id` int(11) NOT NULL,
`total` int(11) NOT NULL,
`feed_views` int(11) NOT NULL,
`home_views` int(11) NOT NULL,
`archive_views` int(11) NOT NULL,
`category_views` int(11) NOT NULL,
`single_views` int(11) NOT NULL,
`comments` int(11) NOT NULL,
`pingbacks` int(11) NOT NULL,
`trackbacks` int(11) NOT NULL,
`last_modified` datetime,
KEY `post_id` (`post_id`)
) ENGINE=MyISAM;

CREATE TABLE IF NOT EXISTS `wp_ak_popularity_options` (
`option_name` varchar(50) NOT NULL,
`option_value` varchar(50) NOT NULL
) ENGINE=MyISAM;</pre>

<p class="note"><b>Примечание.</b> Если вы используете в БД префикс для таблиц отличный от <tt>wp_</tt>, то при создании таблиц замените префиксы на используемые вами.</p>
<p>После этих действий плагин должен активироваться и работать без проблем.</p><a href="http://predvoditelev.ru/page/wordpress_install_popularity_contest#comments"> Обсудить</a>]]></description>
		</item>
				<item>
			<title><![CDATA[Проверка на максимальную длину названия темы в Vanilla]]></title>
			<link>http://predvoditelev.ru/page/vanilla_max_length_theme</link>
			<guid>http://predvoditelev.ru/page/vanilla_max_length_theme</guid>
			<pubDate>Wed, 12 Nov 2008 18:04:01 +0000</pubDate>
			<category><![CDATA[Web-мастеринг]]></category>
			<description><![CDATA[<img src="/images/vanilla_max_length_theme.gif" alt="Проверка на максимальную длину названия темы в Vanilla" width="200" height="55" class="img-left">

<p>
	<strong>Форум Vanilla</strong>, конечно, довольно интересный и очень удобный, но ещё достаточно сыроват.
	Поэтому приходится некоторые ошибки по ходу находить и самому править. Собственно обнаружилась
	ошибка в <strong>проверке на максимальную длину названия темы в Vanilla</strong>.
	Описываемая ошибка у меня проявилась в версии 1.1.5a.
</p>

<a name="cut"></a>

<p>
	Итак в файле <tt>[путь к форуму]/appg/settings.php</tt> есть такой параметр
	<tt>$Configuration['MAX_TOPIC_WORD_LENGTH']</tt>, который вероятно и должен отвечать за
	максимальную длину названия темы. Но как не менял я этот параметр - результат был один
	и тот же: ограничение всегда было в 100 символов.
</p>

<p>
	Стоит сказать, что определил-то я это не сразу :). Ошибка показывается, не как обычно что-то
	вроде <i>&ldquo;Превышено ограничение в N символов&rdquo;</i>, а показывается на сколько
	символов длина заголовка превышает ограничение, поэтому у меня число было всегда разным,
	а перевод был не правильным: "Заголовок темы превышает N символов".
	Я перевел для себя так (см. файл <tt>[путь к форуму]/languages/[название языка]/definitions.php</tt>):
</p>

<pre class="brush: php;">$Context-&gt;Dictionary['ErrInputLength'] = '//1 слишком длинный. Сократите его на //2 символ(а, ов).';</pre>

<p>
	Но собственно к ошибке с проверкой длинны. Раз ограничение всегда было одно - в 100 символов,
	значит оно где-то жестко прописано, вместо того, чтобы использовать наш параметр. Порывшись в
	исходниках, обнаружилось проблемное место. Итак, чтобы исправить этот глюк открываем файл
	<tt>[путь к форуму]/library/Vanilla/Vanilla.Class.DiscussionManager.php</tt>
	и заменяем в нём строку 448:
</p>

<pre class="brush: php;">Validate($this-&gt;Context-&gt;GetDefinition('DiscussionTopicLower'), 1, $Name, 100, '', $this-&gt;Context);</pre>

<p>на строку:</p>

<pre class="brush: php;">Validate($this-&gt;Context-&gt;GetDefinition('DiscussionTopicLower'), 1, $Name, $this-&gt;Context-&gt;Configuration['MAX_TOPIC_WORD_LENGTH'], '', $this-&gt;Context);</pre>

<p>Теперь проверка на длину строки будет работать корректно.</p>

<p>
В шаблоне также ограничение на длину прописано жестко, то есть параметр <tt>maxlength=&rdquo;100&Prime;</tt>. Заменим его.
Открываем файл <tt>[путь к форуму]/themes/discussion_form.php</tt> и заменяем в нем:
</p>

<pre class="brush: php;">&lt;input id=&quot;txtTopic&quot; type=&quot;text&quot; name=&quot;Name&quot; class=&quot;DiscussionBox&quot; maxlength=&quot;100&quot; value=&quot;'.$Discussion-&gt;Name.'&quot; /&gt;</pre>

<p>на</p>

<pre class="brush: php;">&lt;input id=&quot;txtTopic&quot; type=&quot;text&quot; name=&quot;Name&quot; class=&quot;DiscussionBox&quot; maxlength=&quot;'.$this-&gt;Context-&gt;Configuration['MAX_TOPIC_WORD_LENGTH'].'&quot; value=&quot;'.$Discussion-&gt;Name.'&quot; /&gt;</pre>

<p>Вот теперь вроде бы всё. Ошибка исправлена полностью.</p>

<p><b>PS</b> Много информациии по Vanilla вы найдете здесь: <a href="http://www.vanillain.ru/">Русскоязычное сообщество Vanilla forum</a>.</p><a href="http://predvoditelev.ru/page/vanilla_max_length_theme#comments"> Обсудить</a>]]></description>
		</item>
				<item>
			<title><![CDATA[Список пользователей на форуме Vanilla]]></title>
			<link>http://predvoditelev.ru/page/member_list_in_vanilla</link>
			<guid>http://predvoditelev.ru/page/member_list_in_vanilla</guid>
			<pubDate>Tue, 11 Nov 2008 11:58:17 +0000</pubDate>
			<category><![CDATA[Web-мастеринг]]></category>
			<description><![CDATA[<img src="/images/member_list_in_vanilla.gif" alt="Список пользователей на форуме Vanilla" width="220" height="50" class="img-left">

<p>
	Продолжаем расширять функциональность форума <strong>Vanilla</strong>.
	Изучая админку форума я так и не нашел - где же посмотреть список зарегестрированных
	пользователей. К сожалению, авторы не посчитали эту возможность настолько важной,
	чтобы включить её в базовую версию форума. Раз нет в базовой версии, значит должно
	быть расширение дающее такую возможность. И оно нашлось - <strong>MembersList</strong>&hellip;
</p>

<a name="cut"></a>

<p>
	Данное разрешение добавляет вкладку <i>&ldquo;Список пользователей&rdquo;</i> в основное меню
	и соответственно позволяет в удобном виде просмотреть список зарегистрированных пользователей.
</p>

<p>
	<strong>Скачать расширение MembersList</strong> можно отсюда: <a href="http://lussumo.com/addons/index.php?PostBackAction=AddOn&amp;AddOnID=355">http://lussumo.com/addons/index.php?PostBackAction=AddOn&amp;AddOnID=355</a> (на момент написания заметки актуальная версия - 1.2).
</p>

<p>
	Скаченный архив разархивируем и перед тем как закачать расширение на сервер,
	переведем его на русский язык. Для этого открываем файл <tt>MembersList/conf/language.php</tt>
	и переводим на русский язык соответствующие значения. У меня получилось вот так:
</p>

<pre class="brush: php;">&lt;?php
// Language Dictionary
 
$Context-&gt;Dictionary['Members'] = 'Список пользователей'; // Tab title
$Context-&gt;Dictionary['AvatarDefinition'] = 'Аватар'; // Avatar Cell Title
$Context-&gt;Dictionary['Username'] = 'Ник'; // Username Cell Title
$Context-&gt;Dictionary['NameTag'] = 'Имя, фамилия'; // Name &amp; Lastname Cell Title
$Context-&gt;Dictionary['Visit'] = 'Посещения'; // Total Visit Count Title
$Context-&gt;Dictionary['Role'] = 'Роль'; // Role Description Cell Title
$Context-&gt;Dictionary['Email'] = 'E-mail'; // Email Cell Title
$Context-&gt;Dictionary['Posts'] = 'Сообщения'; // Total Posts Title
$Context-&gt;Dictionary['Registered'] = 'Дата регистрации'; // Registration Date Title
 
$Context-&gt;Dictionary['Gizli'] = 'Secret'; // Secret Fields
$Context-&gt;Dictionary['notAvail'] = 'N/A'; // Not Available Fields (empty fields)
 
// denfinitions for Admin Panel
$Context-&gt;Dictionary['permission_view'] = 'Показывать дополнительные вкладки (Список пользователей)';
$Context-&gt;Dictionary['permission_view_secret'] ='Разрешить смотреть скрытые данные пользователей (Имя и e-mail)';
 
?&gt;</pre>

<p>Не забываем, что сохранять файл надо в кодировке <tt>UTF-8</tt>.</p>

<p>
	Теперь закачиваем папку <tt>MembersList</tt> на сервер в директорию <tt>[путь к форуму]/extensions/</tt>.
	Далее на форуме заходим в <i>настройки - дополнения</i> и ставим галочку напротив расширения <tt>MembersList</tt>.
</p>

<p>
	Расширение мы активировали, осталось только указать, какие группы пользователей могут смотреть
	списки зарегистрированных пользователей. Для этого служат параметры
	<i>Показывать дополнительные вкладки (Список пользователей)</i> и
	<i>Разрешить смотреть скрытые данные пользователей (Имя и e-mail)</i>
	(см. <i>настройки - полномочия</i>).
</p>

<p><strong>PS</strong> Описанные в посте действия производились над форумом Vanilla версии 1.1.5a.</p><a href="http://predvoditelev.ru/page/member_list_in_vanilla#comments"> Обсудить</a>]]></description>
		</item>
				<item>
			<title><![CDATA[Установка редактора TinyMCE на форум Vanilla]]></title>
			<link>http://predvoditelev.ru/page/install_tinymce_on_vanilla</link>
			<guid>http://predvoditelev.ru/page/install_tinymce_on_vanilla</guid>
			<pubDate>Mon, 10 Nov 2008 12:25:52 +0000</pubDate>
			<category><![CDATA[Web-мастеринг]]></category>
			<description><![CDATA[<img src="/images/install_tinymce_on_vanilla.gif" alt="Установка редактора TinyMCE на форум Vanilla" width="200" height="181" class="img-left">
<p>
	На одном из своих проектов решил установить форум. После непродолжительных раздумий остановил
	свой выбор на легковесном и жутко удобном форуме <strong><a href="http://getvanilla.com/">Vanilla</a></strong>
	(на момент написания поста последняя версия 1.1.5a).
</p>

<p>
	В базовой версии форума - только самое необходимое.
	Дополнительная функциональность делается с помощью расширения для форума.
</p>

<p>
	Первым расширением, которое мне понадобилось - был визуальный редактор для написания сообщения
	в форум. Выбор был сделан в пользу старого доброго <strong>TinyMCE</strong>. Собственно далее
	следует <strong>инструкция по установке TinyMCE на форум Vanilla</strong>.
</p>

<a name="cut"></a>

<p>
	Во-первых, качаем сам TinyMCE отсюда: <a href="http://tinymce.moxiecode.com/download.php">http://tinymce.moxiecode.com/download.php</a>
	(нам необходим <tt>Main package</tt>, на момент написания поста последняя версия - 3.2.1).
	В архиве есть папка <tt>jscripts</tt> - только она нужна нам из архива, документацию
	и примеры можно смело удалить :). Закачиваем папку <tt>jscripts</tt> на сервер в директорию
	<tt>[путь к форуму]/js/tinymce/</tt> (папку <tt>tinymce</tt> необходимо создать).
</p>

<p>
	Теперь скачиваем расширение для Vanilla, позволяющее установить TinyMCE в качестве редактора,
	отсюда: <a href="http://lussumo.com/addons/index.php?PostBackAction=AddOn&amp;AddOnID=179">http://lussumo.com/addons/index.php?PostBackAction=AddOn&amp;AddOnID=179</a>
	(на момент написания поста последняя версия - 1.4.1). Распаковываем содержимое архива на сервер
	в директорию <tt>[путь к форуму]/extensions/</tt>.
</p>

<p>
	Всё, осталось только активировать дополнение. Для этого заходим в
	<i>настройки форума - дополнения</i> и ставим галочку напротив расширения <i>Tinymce</i>.
</p><a href="http://predvoditelev.ru/page/install_tinymce_on_vanilla#comments"> Обсудить</a>]]></description>
		</item>
				<item>
			<title><![CDATA[ MODx: Вывод информации только для администратора ]]></title>
			<link>http://predvoditelev.ru/page/modx_info_only_for_admin</link>
			<guid>http://predvoditelev.ru/page/modx_info_only_for_admin</guid>
			<pubDate>Thu, 06 Nov 2008 12:12:08 +0000</pubDate>
			<category><![CDATA[MODx]]></category>
			<description><![CDATA[<p><strong>&hellip; или зачем админу смотреть на рекламу?</strong></p>

<p>
	Просматривая свой сайт, подумалось мне - а зачем мне смотреть рекламу на своём сайте?
	Пускай посетители видят рекламу, а я что-нибудь полезное посмотрю :).
	Например, какую-нибудь статистику. Что я и сделал.
</p>

<p><strong>Задача:</strong> если администратор залогинился на сайте, то при просмотре вместо чанка с рекламой показывать чанк со статистикой.</p>
<a name="cut"></a>

<p>Создаем простой сниппет <tt>ad_or_stat</tt>:</p>

<pre class="brush: php;">&lt;?php
    if ($_SESSION['mgrShortname'] == 'admin') {
        echo $modx-&gt;getChunk(&quot;tpl_admin-stat&quot;);
    } else {
        echo $modx-&gt;getChunk(&quot;tpl_begun-code&quot;);
    }
?&gt;</pre>

<p>
	В переменной <tt>$_SESSION['mgrShortname']</tt> содержится логин пользователя.
	Соответственно смотрим, если логин - <i>&ldquo;admin&rdquo;</i>, то выводим чанк
	со статистикой <tt>tpl_admin-stat</tt>; если же логин какой-то другой или это
	просто посетитель - выводим чанк с рекламой <tt>tpl_begun-code</tt>
	(в моем случае - это блок бегуна).
</p>

<p>Чанк <tt>tpl_admin-stat</tt> у меня выглядит следующим образом:</p>

<pre class="brush: html;">&lt;div class=&quot;admin-stat&quot;&gt;
	&lt;div class=&quot;title&quot;&gt;Статистика&lt;/div&gt;
	&lt;div class=&quot;stat&quot;&gt;
		Запросы к БД: &lt;b&gt;[^q^] ([^qt^])&lt;/b&gt;&lt;br /&gt;
		Время работы скриптов: &lt;b&gt;[^p^]&lt;/b&gt;&lt;br /&gt;
		Время генерации страницы: &lt;b&gt;[^t^]&lt;/b&gt;&lt;br /&gt;
		Источник: &lt;b&gt;[^s^]&lt;/b&gt;
	&lt;/div&gt;
&lt;/div&gt;</pre>

<p>Теперь просто вместо вызова чанка с рекламой в шаблоне - вызываем наш сниппет: <tt>[!ad_or_stat!]</tt> и вместо рекламы - наблюдаем статистику.</p><a href="http://predvoditelev.ru/page/modx_info_only_for_admin#comments"> Обсудить</a>]]></description>
		</item>
				<item>
			<title><![CDATA[MODx: Проблема с использованием регулярных выражений в Jot]]></title>
			<link>http://predvoditelev.ru/page/modx_jot_trable_with_regex</link>
			<guid>http://predvoditelev.ru/page/modx_jot_trable_with_regex</guid>
			<pubDate>Sun, 02 Nov 2008 20:37:26 +0000</pubDate>
			<category><![CDATA[MODx]]></category>
			<description><![CDATA[<img src="/images/modx_jot_trable_with_regex.jpg" alt="MODx: Проблема с использованием регулярных выражений в Jot" width="115" height="80" class="img-left">
<p>
	Захотелось вот на одном сайте сделать форму, чтобы пользователи могли оставлять комментарии.
	Сайт, как понятно из названия, на <strong>MODx</strong>. Для комментирования решил использовать
	сниппет <strong>Jot</strong>. На данный момент самая свежая версия - <em>1.1.4</em>.
	Скачал, установил&hellip; вроде работает :). Но в дальнейшем появился один глюк, не позволяющий в
	полной мере использовать регулярные выражения для проверки на правильность ввода данных, но обо всём по порядку&hellip;
</p>

<a name="cut"></a>

<p>
	Для поля <em>&ldquo;имя пользователя&rdquo;</em> необходимо было сделать проверку на длину строки (чтобы не менее 5 символов).
	Не проблема - в <strong>Jot</strong> можно использовать регулярные выражения для проверки с помощью параметра <tt>validate</tt>.
	Синтаксис следующий:
</p>

<p><em>fieldname:message(:validation),fieldname:message(:validation),&hellip;</em></p>

<p>где:</p>
<ul>
	<li><tt>fieldname</tt> - имя поля;</li>
	<li><tt>message</tt> - сообщение, показываемое при ошибке;</li>
	<li><tt>validation</tt> - правило проверки (<i>number</i>, <i>email</i>, регулярное выражение).</li>
</ul>
<p>Можно задать правила проверки для всех полей, разделяя их запятой.</p>

<p>
	Регулярное выражение для моего случая (длина строки не более 5 символов) следующее:
	<tt>/^.{5,}$/</tt>. В итоге получаем такой параметр:
</p>

<p><tt>&amp;validate=`Name:Имя должно содержать не менее 5 символов:/^.{5,}$/`</tt></p>

<p>
	Вроде бы всё правильно, но это не работает - вылазит ошибка: неверный синтаксис регулярного выражения.
	А проблема на самом деле в том, что в регулярном выражении мы используем запятую, но запятая используется
	в синтаксисе <tt>validate</tt> для разделения правил для полей. Соответственно строка парсится не правильно.
</p>

<p>
	Для исправления этого глюка я решил заменить разделение полей в <tt>validate</tt> с запятой на <tt>||</tt>.
	Для этого открываем файл <tt>/assets/snippets/jot/jot.class.inc.php</tt> и переходим на строку 171, она выглядит следующим образом:
</p>

<pre class="brush: php;">$valStrings = explode(&quot;,&quot;,$this-&gt;config[&quot;validate&quot;]);</pre>

<p>И заменяем запятую на на наш разделитель <i>"||"</i>:</p>

<pre class="brush: php;">$valStrings = explode(&quot;||&quot;,$this-&gt;config[&quot;validate&quot;]);</pre>

<p>
	Всё&hellip; теперь <strong>регулярные выражения в Jot</strong> работают корректно, но надо не забывать, что теперь разделителем в
	<tt>validate</tt> является <i>"||"</i> вместо запятой.
</p><a href="http://predvoditelev.ru/page/modx_jot_trable_with_regex#comments"> Обсудить</a>]]></description>
		</item>
			</channel>
</rss>
