<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Очередной блог фрилансера &#187; php</title>
	<atom:link href="http://dreamhelg.ru/tag/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://dreamhelg.ru</link>
	<description>о моей работе в сети и не только</description>
	<lastBuildDate>Fri, 23 Dec 2011 07:10:04 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>WordPress. Функции базы данных</title>
		<link>http://dreamhelg.ru/2010/12/wordpress-database-functions/</link>
		<comments>http://dreamhelg.ru/2010/12/wordpress-database-functions/#comments</comments>
		<pubDate>Tue, 07 Dec 2010 11:09:27 +0000</pubDate>
		<dc:creator>dreamhelg</dc:creator>
				<category><![CDATA[wordpress]]></category>
		<category><![CDATA[переводы]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[wpdb]]></category>

		<guid isPermaLink="false">http://dreamhelg.ru/?p=2104</guid>
		<description><![CDATA[<p><img width="200" height="200" src="http://dreamhelg.ru/wp-content/uploads/2010/12/home.jpg" class="attachment-200x200 wp-post-image" alt="home" title="home" /></p><p>В wordpress существует достаточно обширный класс, предоставляющий набор методов для эффективной работы с базой данных. Вы можете найти описание этого класса а также всех его методов в файле /wp-includes/wp-db.php. В сегодняшней статье будут рассмотрены наиболее важные из этих методов, и небольшие примеры их использования. Важно умение использовать возможности класса $wpdb, для безопасной работы плагинов.</p><span id="more-2104"></span>  
<p>В статье будут приведены примеры использования следующих шести методов:</p>  
<ul>
<li><strong>insert($table, $data, $format)</strong> – вставляет строку в таблицу через массивы.</li>    <li><strong>update($table, $data, $where, $format, $where_format)</strong> – обновляет строку в таблице через массивы.</li>
<li><strong>get_var($query, $x, $y)</strong> – получает одиночную переменную из базы данных.</li>
<li><strong>query($query)</strong> — выполняет MySQL-запрос к базе данных, с текущим подключением.</li>
<li><strong>get_results($query, $output)</strong> – получает данные SQL-запроса из базы данных (одну или множество строк).</li>
<li><strong>escape($data)</strong> – Экранирует контент для вставки в базу данных, используя метод <strong>addslashes()</strong> для безопасности.</li>
</ul>  

<p>Кроме этого, есть еще несколько интересных методов:</p>  <ul>
<li><strong>set_prefix($prefix)</strong> – используется для установления префикса wordpress-таблиц, также может быть использован для переопределения префикса в любое время.</li>
<li><strong>prepare($query)</strong> – безопасно подготавливает SQL-запрос к выполнению, с помощью sprint()-подобного синтаксиса.</li>
<li><strong>get_row($query, $output, $y)</strong> – получает одиночную запись из базы данных.</li>    <li><strong>get_col($query, $x)</strong> – получает одиночную колонку из базы данных в формате массива.</li> 
</ul>  
[code lang="php"]
/**
 * insert
 */
$wpdb-&gt;insert( $wpdb-&gt;posts, array( 'post_title' =&gt; $mytitle ) );
 
$wpdb-&gt;insert( $wpdb-&gt;options, array(
            'option_name',
            'new_option_key',
            'option_value' =&gt; 'New Option Value',
            'autoload' =&gt; 'yes' )
            );
 
/**
 * update
 */
$wpdb-&gt;update( $wpdb-&gt;posts, array( 'post_title' =&gt; $mytitle ),
            array( 'ID' =&gt; $myid )
            );
 
$wpdb-&gt;update( $wpdb-&gt;options,
            array( 'option_value' =&gt; 'New Option Value' ),
            array( 'option_name' =&gt; 'new_option_value' )
            );
 
/**
 * get_var
 */
$post_id = $wpdb-&gt;get_var(
            $wpdb-&gt;prepare( &quot;SELECT post_id FROM
                    $wpdb-&gt;postmeta WHERE
                    post_id = %d AND
                    meta_key = 'enclosure' AND
                    meta_value LIKE (%s)&quot;, $post_ID, $url . '&amp;' )
            );
 
$content = $wpdb-&gt;get_var(
            $wpdb-&gt;prepare(&quot;SELECT post_content FROM &quot; .
                    &quot;$wpdb-&gt;posts WHERE &quot; .
                    &quot;post_title = %s AND &quot; .
                    &quot;ID = %d&quot;, $title, $id )
        );
 
/**
 * query
 */
$wpdb-&gt;query( &quot;DELETE FROM $wpdb-&gt;options WHERE option_name = '$name'&quot; );
 
$wpdb-&gt;query( &quot;UPDATE $wpdb-&gt;posts SET post_title = '$mytitle' WHERE ID = $myid&quot; );
 
/**
 * query and escape
 */
$mytitle = $wpdb-&gt;escape( $mytitle );
$myid    = absint( $myid );
$wpdb-&gt;query( &quot;UPDATE $wpdb-&gt;posts SET post_title = '$mytitle' WHERE ID = $myid&quot; );
 
/**
 * get_results
 */
$type = $wpdb-&gt;get_results( &quot;SELECT post_type FROM &quot; .
                &quot;$wpdb-&gt;posts WHERE ID=$id&quot; );
[/code]

<p>Перевод статьи “<a href="http://wpengineer.com/1746/wordpress-database-functions/">WordPress Database Functions”</a>.</p>]]></description>
		<wfw:commentRss>http://dreamhelg.ru/2010/12/wordpress-database-functions/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>WordPress. Создаем встроенную форму обратной связи</title>
		<link>http://dreamhelg.ru/2010/06/wordpress-create-built-in-contact-form/</link>
		<comments>http://dreamhelg.ru/2010/06/wordpress-create-built-in-contact-form/#comments</comments>
		<pubDate>Wed, 30 Jun 2010 06:30:45 +0000</pubDate>
		<dc:creator>dreamhelg</dc:creator>
				<category><![CDATA[wordpress]]></category>
		<category><![CDATA[переводы]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://dreamhelg.ru/?p=2079</guid>
		<description><![CDATA[<p><img width="200" height="200" src="http://dreamhelg.ru/wp-content/uploads/2010/06/home2.png" class="attachment-200x200 wp-post-image" alt="home" title="home" /></p>Множество существующих плагинов wordpress позволяют встраивать форму обратной связи на ваш блог, но использование плагинов – не обязательное условие. В сегодняшней статье, вы узнаете как создать встроенную контактную форму, с помощью собственной WordPress-темы.<span id="more-2079"></span>
<br/>
Пример такой формы можно найти на сайте <a href="http://www.phpsnippets.info/">PHP Snippets</a>, там она выглядит следующим образом:

<a href="http://dreamhelg.ru/wp-content/uploads/2010/06/contact.jpg"><img class="aligncenter size-full wp-image-2082" title="contact" src="http://dreamhelg.ru/wp-content/uploads/2010/06/contact.jpg" alt="" width="462" height="357" /></a>
<h3>Шаг 1: Создание шаблона</h3>
Сначала, нам понадобится создать шаблон страницы. Для этого, скопируйте содержимое файла <em>page.php</em> в новый файл, и сохраните его под именем <em>page-contact.php.</em>

Для того, чтобы WordPress определил наш файл как шаблон, нам нужно добавить комментарий, следующего вида:

[php]
&lt;?php
/*
Template Name: Contact
*/
?&gt;
[/php]

В результате наш файл <em>page-contact.php</em> должен выглядеть вот так:

[php]
&lt;?php
/*
Template Name: Contact
*/
?&gt;

&lt;?php get_header() ?&gt;

	&lt;div id=&quot;container&quot;&gt;
		&lt;div id=&quot;content&quot;&gt;
			&lt;?php the_post() ?&gt;
			&lt;div id=&quot;post-&lt;?php the_ID() ?&gt;&quot; class=&quot;post&quot;&gt;
				&lt;div class=&quot;entry-content&quot;&gt;
				&lt;/div&gt;&lt;!-- .entry-content -&gt;
			&lt;/div&gt;&lt;!-- .post--&gt;
		&lt;/div&gt;&lt;!-- #content --&gt;
	&lt;/div&gt;&lt;!-- #container --&gt;

&lt;?php get_sidebar() ?&gt;
&lt;?php get_footer() ?&gt;
[/php]

<h3>Шаг 2: Создание формы</h3>
Теперь, создадим простую форму обратной связи. Просто вставьте приведенный код внутри блока <em>entry-content.</em>

[php]
&lt;form action=&quot;&lt;?php the_permalink(); ?&gt;&quot; id=&quot;contactForm&quot; method=&quot;post&quot;&gt;
	&lt;ul&gt;
		&lt;li&gt;
			&lt;label for=&quot;contactName&quot;&gt;Name:&lt;/label&gt;
			&lt;input type=&quot;text&quot; name=&quot;contactName&quot; id=&quot;contactName&quot; value=&quot;&quot; /&gt;
		&lt;/li&gt;
		&lt;li&gt;
			&lt;label for=&quot;email&quot;&gt;Email&lt;/label&gt;
			&lt;input type=&quot;text&quot; name=&quot;email&quot; id=&quot;email&quot; value=&quot;&quot; /&gt;
		&lt;/li&gt;
		&lt;li&gt;
			&lt;label for=&quot;commentsText&quot;&gt;Message:&lt;/label&gt;
			&lt;textarea name=&quot;comments&quot; id=&quot;commentsText&quot; rows=&quot;20&quot; cols=&quot;30&quot;&gt;&lt;/textarea&gt;
		&lt;/li&gt;
		&lt;li&gt;
			&lt;button type=&quot;submit&quot;&gt;Send email&lt;/button&gt;
		&lt;/li&gt;
	&lt;/ul&gt;
	&lt;input type=&quot;hidden&quot; name=&quot;submitted&quot; id=&quot;submitted&quot; value=&quot;true&quot; /&gt;
&lt;/form&gt;
[/php]

Код формы очень простой, и не нуждается в разъяснениях. Обратите внимания на  тэг <em>input type=”hidden”, </em>добавленный в строке 19 – позже, он будет использоваться для проверки была ли отправлена форма.

<h3>Шаг 3: Обработка данных и ошибок</h3>
Наша форма выглядит прекрасно, но пока что является бесполезной, поскольку не отправляет сообщения. Прежде всего, перед отправкой сообщения, нам нужно проверить была ли отправлена форма, и правильно ли заполнены все поля.

Если поля заполнены правильно, мы получаем почтовый адрес администратора блога и отправляем ему сообщение. Если поля заполнены частично или с ошибками, сообщение не отправляется, и пользователю выводится список ошибок.

Вставьте следующий код между комментарием с названием шаблона и функцией <em>get_header()</em>.

[php]
&lt;?php
if(isset($_POST['submitted'])) {
	if(trim($_POST['contactName']) === '') {
		$nameError = 'Please enter your name.';
		$hasError = true;
	} else {
		$name = trim($_POST['contactName']);
	}

	if(trim($_POST['email']) === '')  {
		$emailError = 'Please enter your email address.';
		$hasError = true;
	} else if (!eregi(&quot;^[A-Z0-9._%-]+@[A-Z0-9._%-]+\.[A-Z]{2,4}$&quot;, trim($_POST['email']))) {
		$emailError = 'You entered an invalid email address.';
		$hasError = true;
	} else {
		$email = trim($_POST['email']);
	}

	if(trim($_POST['comments']) === '') {
		$commentError = 'Please enter a message.';
		$hasError = true;
	} else {
		if(function_exists('stripslashes')) {
			$comments = stripslashes(trim($_POST['comments']));
		} else {
			$comments = trim($_POST['comments']);
		}
	}

	if(!isset($hasError)) {
		$emailTo = get_option('tz_email');
		if (!isset($emailTo) || ($emailTo == '') ){
			$emailTo = get_option('admin_email');
		}
		$subject = '[PHP Snippets] From '.$name;
		$body = &quot;Name: $name \n\nEmail: $email \n\nComments: $comments&quot;;
		$headers = 'From: '.$name.' &lt;'.$emailTo.'&gt;' . &quot;\r\n&quot; . 'Reply-To: ' . $email;

		mail($emailTo, $subject, $body, $headers);
		$emailSent = true;
	}

} ?&gt;
[/php]

В этом коде, проверяется отправка формы и корректное заполнение полей. Если появляются ошибки, в виде пустого поля или неправильно указанного почтового адреса, формируется сообщение об ошибке и форма не отправляется.

Теперь, нам нужно отобразить сообщение об ошибке, рядом с нужным полем, например “Пожалуйста, введите имя”.  <strong>Ниже приведен полный код шаблона, который вы можете использовать в своей теме.</strong>

[php]
&lt;?php
/*
Template Name: Contact
*/
?&gt;

&lt;?php
if(isset($_POST['submitted'])) {
	if(trim($_POST['contactName']) === '') {
		$nameError = 'Please enter your name.';
		$hasError = true;
	} else {
		$name = trim($_POST['contactName']);
	}

	if(trim($_POST['email']) === '')  {
		$emailError = 'Please enter your email address.';
		$hasError = true;
	} else if (!eregi(&quot;^[A-Z0-9._%-]+@[A-Z0-9._%-]+\.[A-Z]{2,4}$&quot;, trim($_POST['email']))) {
		$emailError = 'You entered an invalid email address.';
		$hasError = true;
	} else {
		$email = trim($_POST['email']);
	}

	if(trim($_POST['comments']) === '') {
		$commentError = 'Please enter a message.';
		$hasError = true;
	} else {
		if(function_exists('stripslashes')) {
			$comments = stripslashes(trim($_POST['comments']));
		} else {
			$comments = trim($_POST['comments']);
		}
	}

	if(!isset($hasError)) {
		$emailTo = get_option('tz_email');
		if (!isset($emailTo) || ($emailTo == '') ){
			$emailTo = get_option('admin_email');
		}
		$subject = '[PHP Snippets] From '.$name;
		$body = &quot;Name: $name \n\nEmail: $email \n\nComments: $comments&quot;;
		$headers = 'From: '.$name.' &lt;'.$emailTo.'&gt;' . &quot;\r\n&quot; . 'Reply-To: ' . $email;

		mail($emailTo, $subject, $body, $headers);
		$emailSent = true;
	}

} ?&gt;
&lt;?php get_header(); ?&gt;
	&lt;div id=&quot;container&quot;&gt;
		&lt;div id=&quot;content&quot;&gt;

			&lt;?php if (have_posts()) : while (have_posts()) : the_post(); ?&gt;
			&lt;div &lt;?php post_class() ?&gt; id=&quot;post-&lt;?php the_ID(); ?&gt;&quot;&gt;
				&lt;h1 class=&quot;entry-title&quot;&gt;&lt;?php the_title(); ?&gt;&lt;/h1&gt;
					&lt;div class=&quot;entry-content&quot;&gt;
						&lt;?php if(isset($emailSent) &amp;&amp; $emailSent == true) { ?&gt;
							&lt;div class=&quot;thanks&quot;&gt;
								&lt;p&gt;Thanks, your email was sent successfully.&lt;/p&gt;
							&lt;/div&gt;
						&lt;?php } else { ?&gt;
							&lt;?php the_content(); ?&gt;
							&lt;?php if(isset($hasError) || isset($captchaError)) { ?&gt;
								&lt;p class=&quot;error&quot;&gt;Sorry, an error occured.&lt;p&gt;
							&lt;?php } ?&gt;

						&lt;form action=&quot;&lt;?php the_permalink(); ?&gt;&quot; id=&quot;contactForm&quot; method=&quot;post&quot;&gt;
							&lt;ul class=&quot;contactform&quot;&gt;
							&lt;li&gt;
								&lt;label for=&quot;contactName&quot;&gt;Name:&lt;/label&gt;
								&lt;input type=&quot;text&quot; name=&quot;contactName&quot; id=&quot;contactName&quot; value=&quot;&lt;?php if(isset($_POST['contactName'])) echo $_POST['contactName'];?&gt;&quot; class=&quot;required requiredField&quot; /&gt;
								&lt;?php if($nameError != '') { ?&gt;
									&lt;span class=&quot;error&quot;&gt;&lt;?=$nameError;?&gt;&lt;/span&gt;
								&lt;?php } ?&gt;
							&lt;/li&gt;

							&lt;li&gt;
								&lt;label for=&quot;email&quot;&gt;Email&lt;/label&gt;
								&lt;input type=&quot;text&quot; name=&quot;email&quot; id=&quot;email&quot; value=&quot;&lt;?php if(isset($_POST['email']))  echo $_POST['email'];?&gt;&quot; class=&quot;required requiredField email&quot; /&gt;
								&lt;?php if($emailError != '') { ?&gt;
									&lt;span class=&quot;error&quot;&gt;&lt;?=$emailError;?&gt;&lt;/span&gt;
								&lt;?php } ?&gt;
							&lt;/li&gt;

							&lt;li&gt;&lt;label for=&quot;commentsText&quot;&gt;Message:&lt;/label&gt;
								&lt;textarea name=&quot;comments&quot; id=&quot;commentsText&quot; rows=&quot;20&quot; cols=&quot;30&quot; class=&quot;required requiredField&quot;&gt;&lt;?php if(isset($_POST['comments'])) { if(function_exists('stripslashes')) { echo stripslashes($_POST['comments']); } else { echo $_POST['comments']; } } ?&gt;&lt;/textarea&gt;
								&lt;?php if($commentError != '') { ?&gt;
									&lt;span class=&quot;error&quot;&gt;&lt;?=$commentError;?&gt;&lt;/span&gt;
								&lt;?php } ?&gt;
							&lt;/li&gt;

							&lt;li&gt;
								&lt;input type=&quot;submit&quot;&gt;Send email&lt;/input&gt;
							&lt;/li&gt;
						&lt;/ul&gt;
						&lt;input type=&quot;hidden&quot; name=&quot;submitted&quot; id=&quot;submitted&quot; value=&quot;true&quot; /&gt;
					&lt;/form&gt;
				&lt;?php } ?&gt;
				&lt;/div&gt;&lt;!-- .entry-content --&gt;
			&lt;/div&gt;&lt;!-- .post --&gt;

				&lt;?php endwhile; endif; ?&gt;
		&lt;/div&gt;&lt;!-- #content --&gt;
	&lt;/div&gt;&lt;!-- #container --&gt;

&lt;?php get_sidebar(); ?&gt;
&lt;?php get_footer(); ?&gt;
[/php]

<h3>Шаг 4: Добавляем проверку jQuery</h3>
Наша форма уже работает прекрасно, но мы можем улучшить ее, добавив проверку на клиенте. Для этого, мы будем использовать jQuery и плагин <a href="http://docs.jquery.com/Plugins/Validation">jQuery Validation</a>. Это отличный плагин, позволяющий легко и быстро проверить правильное заполнение полей.

C<a href="http://docs.jquery.com/Plugins/Validation">качайте плагин</a> и поместите его в папку с вашей темой, внутри папки <em>/js. </em>После этого, вставьте следующие строки в новый файл:

[javascript]
$(document).ready(function(){
	$(&quot;#contactForm&quot;).validate();
});
[/javascript]

Сохраните файл под именем <em>verif.js</em> в папке <em>/js</em>.

Теперь, нам нужно подключить ява-скрипт файлы в нашу тему. Откройте файл <em>header.php</em> и вставьте следующий код внутри тэгов &lt;head&gt;&lt;/head&gt;:

[html]
&lt;?php if( is_page('contact') ){ ?&gt;
	&lt;script type=&quot;text/javascript&quot; src=&quot;&lt;?php bloginfo('template_directory'); ?&gt;/js/jquery.validate.min.js&quot;&gt;&lt;/script&gt;
	&lt;script type=&quot;text/javascript&quot; src=&quot;&lt;?php bloginfo('template_directory'); ?&gt;/js/verif.js&quot;&gt;&lt;/script&gt;
&lt;?php }?&gt;
[/html]

После этого, ваша форма будет проверяться плагином на клиентской стороне. Плагин работает довольно просто – выбирает элементы формы, имеющий css-класс <em>required</em> и проверяет их на корректное заполнение. В случае ошибки, отображается сообщение. Надеюсь, вам понравится ваша новая WordPress-форма.

Перевод статьи “<a href="http://www.catswhocode.com/blog/how-to-create-a-built-in-contact-form-for-your-wordpress-theme">How to create a built-in contact form for your WordPress theme</a>”, автор <strong>Jean-Baptiste Jung</strong>]]></description>
		<wfw:commentRss>http://dreamhelg.ru/2010/06/wordpress-create-built-in-contact-form/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>Введение в пользовательскую таксономию WordPress 3.0</title>
		<link>http://dreamhelg.ru/2010/05/intorducing-into-custom-taxonomy-wordpress-3-0/</link>
		<comments>http://dreamhelg.ru/2010/05/intorducing-into-custom-taxonomy-wordpress-3-0/#comments</comments>
		<pubDate>Fri, 14 May 2010 07:00:17 +0000</pubDate>
		<dc:creator>dreamhelg</dc:creator>
				<category><![CDATA[wordpress]]></category>
		<category><![CDATA[переводы]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[taxonomy]]></category>

		<guid isPermaLink="false">http://dreamhelg.ru/?p=2008</guid>
		<description><![CDATA[<p><img width="200" height="200" src="http://dreamhelg.ru/wp-content/uploads/2010/05/200x200.jpg" class="attachment-200x200 wp-post-image" alt="200x200" title="200x200" /></p>В WordPress 3.0 будут восполнены серьезные пробелы, благодаря чему, он станет гораздо более серьезной системой управления контентом. Довольно простая в использовании функция пользовательской таксономии, предоставит разработчикам сайта мощный инструмент для построения хорошей информационной архитектуры. В сегодняшней статье, вы узнаете что собой представляют таксономии, почему они полезны и как их можно использовать.<span id="more-2008"></span>
<h3>Что такое Таксономия?</h3>
Таксономии – это различные методы для классификации информации. В этой статье приведен пример записей о персональных компьютерах, которые можно классифицировать по целому ряду различных критериев, включая:
<ul>
	<li>Количество оперативной памяти</li>
	<li>Размер жесткого диска</li>
	<li>Скорость процессора</li>
	<li>Тип процессора</li>
	<li>Установленная операционная система</li>
	<li>и так далее…</li>
</ul>
<h3>Краткая история таксономии WordPress</h3>
<h4>Рубрики</h4>
<a href="http://dreamhelg.ru/wp-content/uploads/2010/05/category_old.png"><img class="aligncenter size-full wp-image-2012" title="category_old" src="http://dreamhelg.ru/wp-content/uploads/2010/05/category_old.png" alt="" width="295" height="315" /></a>

До версии 2.3, в WordPress был только один тип таксономии для записей, под названием <strong>Рубрики</strong>. Это было удобно для блогов, а в нашем случае, нам пришлось бы создать рубрику верхнего уровня под названием “Персональные компьютеры”, затем дочернюю рубрику “Оперативная память”, которая, в свою очередь, может содержать такие дочерние рубрики как “Меньше 1Гб”, “1Гб”, “2Гб”, “4Гб” и так далее. Вторая дочерняя рубрика, от основной рубрики “Персональные компьютеры”, называлась бы “Операционная система” и содержала бы такие дочерние рубрики, как: “Windows XP”, “Mac OS”, “Red Hat”, “Ubuntu” и т.д.

Система, позволяющая иметь рубрики, состоящие из дочерних рубрик – называется иерархической структурой. До версии WordPress 2.3, создать серьезную информационную архитектуру сайта можно было только путем создания большой иерархии рубрик, в которой рубрики верхнего уровня представляли собой большие группы таксономий.
<h4>Метки</h4>
<a href="http://dreamhelg.ru/wp-content/uploads/2010/05/tags.png"><img class="aligncenter size-full wp-image-2013" title="tags" src="http://dreamhelg.ru/wp-content/uploads/2010/05/tags.png" alt="" width="287" height="178" /></a>

Начиная с версии 2.3, в WordPress был добавлен второй вид таксономии под названием <strong>Метки</strong>. В отличие от рубрик, которые придумываются заранее, в зависимости от типа контента на сайте, метки предоставляют более свободный метод классификации контента.

Например, при создании записи о персональном компьютере, метки позволяют автору указать одно или несколько ключевых слов, таких как “игровой”, “шумный”, “офисный” и т.д. Эти ключевые слова конечно не несут такого смысла как рубрики, однако помогают добавить дополнительную классификацию к записи.

Посетители сайта, в дальнейшем, легко смогут найти все записи с меткой “шумный”. Однако, свободная форма меток, не поможет нам построить надежную классификационную систему на основе заранее известных значений, таких как типы операционной системы или процессора. Кроме того, метки являются одномерными, и не поддерживают иерархическую структуру.
<h3>Одноуровневые пользовательские таксономии</h3>
<a href="http://dreamhelg.ru/wp-content/uploads/2010/05/04-custom-tax-1d.png"><img class="aligncenter size-full wp-image-2014" title="04-custom-tax-1d" src="http://dreamhelg.ru/wp-content/uploads/2010/05/04-custom-tax-1d.png" alt="" width="494" height="462" /></a>

Начиная с версии 2.8, в WordPress появляется возможность добавить пользовательские классификационные схемы, путем незначительных изменений в коде сайта. С помощью этой функции, вы можете построить список операционных систем, отдельно от списка типов оперативной памяти и т.д. Однако,  в версии 2.8 нет возможности создать иерархическую стркутуру таксономии, как у рубрик.
<h3>Иерархические пользовательские таксономии</h3>
<a href="http://dreamhelg.ru/wp-content/uploads/2010/05/05-custom-tax-2d.png"><img class="aligncenter size-full wp-image-2015" title="05-custom-tax-2d" src="http://dreamhelg.ru/wp-content/uploads/2010/05/05-custom-tax-2d.png" alt="" width="292" height="242" /></a>

И наконец, WordPress 3.0, дает нам полностью иерархические пользовательские таксономии. Обратите внимание как иерархическое устройство позволяет упростить таксономию операционных систем, путем группировки всех вариантов операционной системы Windows в общей родительской рубрике “Windows”. Такая классификация позволит пользователям просматривать все компьютеры с ОС Windows, или например конкретные, с Windows XP.
<h3>Создание пользовательской Таксономии</h3>
<strong>Редактирование файла functions.php</strong>

В Wordpress 3.0 нет возможности создавать пользовательские таксономии в панели управления. Для начального описания вашей пользовательской таксономии без использования плагина, вам понадобится добавить немного кода в файл functions.php, расположенный в папке с вашей темой. Это совсем не сложно – просто следуйте приведенным примерам.
<h3>Добавляем Таксономии в коде</h3>
Итак, на примере персонального компьютера, мы добавим отдельные таксономии для Оперативной памяти, Жесткого диска и Операционной системы. На данном этапе, мы просто добавим таксономии сами по себе, как пустые контейнеры. К счастью, мы можем добавлять и управлять различными классификациями, не выходя из панели управления.

<strong>Шаг 1. Первая функция для создания всего</strong>

Для начала, нам нужно создать функцию, которая создает все необходимые нам таксономии. Назовем функцию “build_taxonomies”. Давайте добавим эту функцию в конец файла functions.php.

[php]
function build_taxonomies() {  
    // code will go here  
}  
[/php]

<strong>Шаг 2. Описание Таксономий</strong>

Далее, для каждой таксономии, которую мы создадим, нам нужно взывать определенную WordPress-функцию, с правильными параметрами. Далее представлена эта функция, и разъяснены ее важные параметры.

[php]
register_taxonomy(  
    'internal_name',  
    'object_type',  
    array(  
        'hierarchical' =&gt; {true|false},  
        'label' =&gt; 'Human Readable Name',  
        'query_var' =&gt; {true|false},  
        'rewrite' =&gt; {true|false}  
    )  
);  
[/php]

<ul>
	<li><strong>internal_name:</strong> название таксономии, которое будет использоваться в базе данных и файлах шаблона</li>
	<li><strong>object_type:</strong> определяет типы контента, к которым можно будет применить эту таксономию. Возможные значения: “post” (запись), “page” (страница), “link” (ссылка).</li>
	<li>Далее идет массив из опциональных параметров. В этой статье, мы будем использовать наиболее важные из них, а полный список можно найти в кодексе WordPress, на странице описания функции <a href="http://codex.wordpress.org/Function_Reference/register_taxonomy">register_taxonomy</a>. Далее идет список используемых параметров.</li>
	<li><strong>hierarchical</strong>: если значение установлено в “true”, эта таксономия будет иметь возможности иерархической структуры, как у Рубрик. Если значение “false”, то таксономия по структуре будет похожа на Метки.</li>
	<li><strong>label</strong>:  это читаемое название, которое будет использоваться в интерфейсе сайта для обозначения этой таксономии.</li>
	<li><strong>query_var</strong>: если значение параметра установлено в “true”, мы сможем получать записи, на основе выбранного значения этой таксономии. Например, можно найти все записи, для которых в таксономии “операционная система” указано значение “Windows”.</li>
	<li><strong>rewrite</strong>: если значение установлено в “true”, при просмотре страницы с этой таксономией, WordPress будет использовать дружественные URL. Например, страница, отображающая все записи с операционной системой “Windows”, будет представлена следующим url: http://domain.com/operating_system/windows</li>
</ul>
Код, добавляющий таксономию “Операционная система” выглядит следующим образом:

[php]
register_taxonomy( 'operating_system', 'post', array( 'hierarchical' =&gt; true, 'label' =&gt; 'Operating System', 'query_var' =&gt; true, 'rewrite' =&gt; true ) );  
[/php]

Вставьте эту функцию, внутри ранее созданной функции build_taxonomies.

<strong>Шаг 3 Вызов функции, создающей таксономию</strong>

Для того, чтобы наша функция build_taxonomies была выполнена, нам понадобится добавить одну строчку кода, в файле functions.php. Фактически мы “прицепим” функцию build_taxonomies к событию init, путем добавления следующего кода:

[php]
add_action( 'init', 'build_taxonomies', 0 ); 
[/php]

Вы можете вставить эту строчку в любом месте, в нашем примере она добавлена выше вызова функции build_taxonomies, поэтому код выглядит вот так:

[php]
// Custom Taxonomy Code  
add_action( 'init', 'build_taxonomies', 0 );  
  
function build_taxonomies() {  
    register_taxonomy( 'operating_system', 'post', array( 'hierarchical' =&gt; true, 'label' =&gt; 'Operating System', 'query_var' =&gt; true, 'rewrite' =&gt; true ) );  
}  
[/php]

<h3>Добавляем классификацию к новой Таксономии</h3>
<a href="http://dreamhelg.ru/wp-content/uploads/2010/05/os.png"><img class="aligncenter size-full wp-image-2016" title="os" src="http://dreamhelg.ru/wp-content/uploads/2010/05/os.png" alt="" width="155" height="166" /></a>

Если вы правильно добавили таксономию “Операционная система” в файле functions.php, она должна появится в виде нового пункта, в блоке “Записи”, вашей панели управления. Кликните по нему, чтобы добавить необходимые классификации.

<a href="http://dreamhelg.ru/wp-content/uploads/2010/05/os-category.jpg"><img class="aligncenter size-full wp-image-2017" title="os-category" src="http://dreamhelg.ru/wp-content/uploads/2010/05/os-category.jpg" alt="" width="618" height="425" /></a>

Теперь, вы можете добавлять и редактировать операционные системы, точно таким же образом, как Рубрики.
<h3>Добавляем больше Таксономий</h3>
Оставшиеся таксономии добавляем аналогичным способом, то есть для каждой таксономии в файле functions.php, создается своя функция register_taxonomy:

[php]
register_taxonomy( 'ram', 'post', array( 'hierarchical' =&gt; true, 'label' =&gt; 'RAM', 'query_var' =&gt; true, 'rewrite' =&gt; true ) );
  
register_taxonomy( 'hard_drive', 'post', array( 'hierarchical' =&gt; true, 'label' =&gt; 'Hard Drive', 'query_var' =&gt; true, 'rewrite' =&gt; true ) );
[/php]

После того, как вы добавите все таксономии, код должен выглядеть следующим образом:

[php]
// Custom Taxonomy Code  
add_action( 'init', 'build_taxonomies', 0 );  
  
function build_taxonomies() {  
register_taxonomy( 'operating_system', 'post', array( 'hierarchical' =&gt; true, 'label' =&gt; 'Operating System', 'query_var' =&gt; true, 'rewrite' =&gt; true ) );  
register_taxonomy( 'ram', 'post', array( 'hierarchical' =&gt; true, 'label' =&gt; 'RAM', 'query_var' =&gt; true, 'rewrite' =&gt; true ) );  
register_taxonomy( 'hard_drive', 'post', array( 'hierarchical' =&gt; true, 'label' =&gt; 'Hard Drive', 'query_var' =&gt; true, 'rewrite' =&gt; true ) );  
}  
[/php]

<h3>Создание записи, с использованием новой Таксономии</h3>
<a href="http://dreamhelg.ru/wp-content/uploads/2010/05/publish_post.jpg"><img class="aligncenter size-full wp-image-2018" title="publish_post" src="http://dreamhelg.ru/wp-content/uploads/2010/05/publish_post.jpg" alt="" width="636" height="476" /></a>

Создайте несколько записей, указав необходимую классификацию, в окне создания/редактирования записей, вы увидите панели вашей таксономии.
<h3>Отображение различной таксономии записей</h3>
Пока что ничего, из того что мы сделали, не доступно посетителям сайта. Следовательно, нам необходимо отобразить для каждой записи, название пользовательской таксономии, к которой она принадлежит.

Для этого, нам понадобится немного изменить цикл, в определенных файлах шаблона.
<h3>Вывод таксономии на индивидуальной странице</h3>
В дефолтной теме <em>Twenty Ten</em><em>, </em>как и во многих других темах WordPress, данные о рубрике и метках записи, выводятся непосредственно под текстом этой записи. Мы будем выводить нашу таксономию, если она существует, чуть выше блока рубрик с метками.

<a href="http://dreamhelg.ru/wp-content/uploads/2010/05/taxonomy.jpg"><img class="aligncenter size-full wp-image-2019" title="taxonomy" src="http://dreamhelg.ru/wp-content/uploads/2010/05/taxonomy.jpg" alt="" width="702" height="262" /></a>

<strong>Шаг 1. Редактирование файла single.php</strong>

Шаблон индивидуальной записи называется single.php, и расположен он внутри папки с вашей темой. Если такого шаблона у вас нет, его можно создать, и скопировать в него содержимое файла index.php.

Найдите в шаблоне single.php строчку:

[html]
&lt;div class=&quot;entry-utility&quot;&gt; 
[/html]

В теме Twenty Ten, этот блок содержит название рубрик, метки, ссылки  и другую информацию о текущей записи. Код для вывода нашей таксономии, мы будем размещать непосредственно над этим блоком.

<strong>Шаг 2. Получение таксономии для текущей записи</strong>

Здесь мы определяем несколько переменных, для хранения вывода пользовательской таксономии.

[php]
&lt;?php  
// Эта переменная используется для вывода таксономии, если она существует
$taxo_text = &quot;&quot;;  
  
// Список переменных, для хранения списков таксономии
// Эта строка получает данные о классификации &quot;Операционная система&quot;
$os_list = get_the_term_list( $post-&gt;ID, 'operating_system', '&lt;strong&gt;Operating System(s):&lt;/strong&gt; ', ', ', '' );  
[/php]

Для получения информации о таксономии текущей записи, мы используем функцию get_the_term, со следующими параметрами:
<ul>
	<li><strong>$post-&gt;ID</strong> : id текущей записи</li>
	<li><strong>‘operation_system’</strong> : имя пользовательской таксономии. Мы проверяем, была ли назначена текущей записи, какая-либо классификация из пользовательской таксономии operation_system.</li>
	<li><strong>‘Операционная система (ы)’</strong> : если данные будут найдены, эта строчка будет вставлена, перед их выводом на экран.</li>
	<li><strong>‘, ’ </strong>:  если найденных значений будет несколько, то они будут разделены запятой</li>
	<li><strong>“ </strong>: если данные будут найдены, эта строка будет вставлена после вывода данных. В нашем случае, мы оставляем ее пустой.</li>
</ul>
Точно так же, используя эту функцию для двух других таксономий, мы получим код следующего вида:

[php]
$ram_list = get_the_term_list( $post-&gt;ID, 'ram', '&lt;strong&gt;RAM Option(s):&lt;/strong&gt; ', ', ', '' );  
$hd_list = get_the_term_list( $post-&gt;ID, 'hard_drive', '&lt;strong&gt;Hard Drive Option(s):&lt;/strong&gt; ', ', ', '' );  
[/php]

<strong>Шаг 3. Форматирование полученного результата</strong>

Проверяем результаты для каждой из трех возможных таксономий. Если результат есть, добавляем его к нашему выводу, вместе с тэгом перевода строки.

[php]
// Добавляем список ОС, если они указаны
if ( '' != $os_list ) {  
    $taxo_text .= &quot;$os_list&lt;br /&gt;\n&quot;;  
}  
// Добавляем данные об Оперативной памяти, если они указаны
if ( '' != $ram_list ) {  
    $taxo_text .= &quot;$ram_list&lt;br /&gt;\n&quot;;  
}  
// Добавляем данные о жестком диске, если они указаны
if ( '' != $hd_list ) {  
    $taxo_text .= &quot;$hd_list&lt;br /&gt;\n&quot;;  
}  
[/php]

<strong>Шаг 4. Выводим классификацию, если она найдена</strong>

Проверяем, была ли получена таксономия из предыдущих шагов. Если таксономия существует, выводим ее, предварительно обернув в div с классом “entry-utility”.

[php]
// Выводим пользовательскую таксономию, если она существует 
// Обратите внимание: Мы не будет открывать div, если у него не будет содержимого
if ( '' != $taxo_text ) {  
?&gt;  
&lt;div class=&quot;entry-utility&quot;&gt;  
&lt;?php  
echo $taxo_text;  
?&gt;  
&lt;/div&gt;  
&lt;?  
} // endif  
?&gt;  
[/php]

<strong>Шаг 5. Проверяем результаты</strong>

Теперь, если открыть страницу любой записи, вы должны увидеть пользовательскую классификацию, расположенную сразу после текста записи.

<a href="http://dreamhelg.ru/wp-content/uploads/2010/05/taxonomy_2.jpg"><img class="aligncenter size-full wp-image-2020" title="taxonomy_2" src="http://dreamhelg.ru/wp-content/uploads/2010/05/taxonomy_2.jpg" alt="" width="659" height="277" /></a>

<h3>Просмотр списка записей, построенный на основе пользовательской таксономии</h3>
Теперь, на странице индивидуальной записи, мы можем узнать к какой классификации принадлежит текущая запись. Вы, наверное, заметили, что при отображении пользовательской классификации, термины выводятся в виде ссылки, которая должна вести на страницу с записями, принадлежащими к этой классификации. К примеру, кликнув по ссылке “Mac OS”, мы по идее, должны увидеть страницу со списком записей, с классификацией “Mac OS”.

Однако, ничего такого не происходит. Для того, чтобы у нас выводилась такая страница, нам нужно создать специальный шаблонный файл, с именем taxonomy.php. WordPress пытается грузить этот шаблон (если он существует) каждый раз, при просмотре записей, группированных пользовательской таксономией.

<strong>Шаг 1</strong>

Откройте файл category.php, скопируйте его контент, и вставьте в новый файл, сохранив его под именем “taxonomy.php”.

<strong>Шаг 2 Получение информации о текущей классификации</strong>

В файле taxonomy.php, нам необходимо получить информацию о текущей, просматриваемой таксономии. Скорее всего, нам понадобится название и описание (если есть) для выбранной классификации.

Сразу после строки &lt;?php get_header(); ?&gt; следующую строку:

[php]
$term = get_term_by( 'slug', get_query_var( 'term' ), get_query_var( 'taxonomy' ) ); 
[/php]

Эта строка получает всю информацию о таксономии и возвращает ее в виде объекта, записанного в переменную $term. Например, классификация “Mac OS” возвращает следующий объект:

[php]
stdClass Object  
(  
    [term_id] =&gt; 13  
    [name] =&gt; Mac OS  
    [slug] =&gt; mac-os  
    [term_group] =&gt; 0  
    [term_taxonomy_id] =&gt; 22  
    [taxonomy] =&gt; operating_system  
    [description] =&gt;  
    [parent] =&gt; 0  
    [count] =&gt; 2  
)  
[/php]

<strong>Шаг 3 Вывод Названия классификации и ее описание</strong>

Нам нужно изменить название страницы, чтобы пользователи видели, какая классификация отображена на странице. Поскольку мы скопировали содержимое шаблона category.php, мы можем взять строку кода, использующуюся для вывода названия рубрики, и немного ее изменить, с тем, чтобы она отображала текущее название классификации, и (если доступно) ее описание.

Измените следующую строку, взятую из шаблона category.php

[php]
printf( __( 'Category Archives: %s', 'twentyten' ), '&lt;span&gt;' . single_cat_title( '', false ) . '&lt;/span&gt;' );  
[/php]

следующим образом:

[php]
printf( __( 'Posts classified under: %s', 'twentyten' ), '&lt;span&gt;' . $term-&gt;name . '&lt;/span&gt;' );  
[/php]

Эта строка выведет название текущей классификации. Далее, ниже добавьте следующую строчку:

[php]
if ('' != $term_descr ) {  
echo &quot;&lt;p&gt;$term_descr&lt;/p&gt;\n&quot;;  
}  
[/php]

Здесь, как не трудно догадаться, будет выведено описание классификации, если оно доступно.

<a href="http://dreamhelg.ru/wp-content/uploads/2010/05/final.jpg"><img class="aligncenter size-full wp-image-2021" title="final" src="http://dreamhelg.ru/wp-content/uploads/2010/05/final.jpg" alt="" width="649" height="563" /></a>

Проверить как работает классификационный список записей, очень просто. Откройте любую, отдельную запись, и кликните на ссылку-название классификации.

Перевод статьи “<a href="http://net.tutsplus.com/tutorials/wordpress/introducing-wordpress-3-custom-taxonomies/">Introducing WordPress 3 Custom Taxonomies</a>”, автор <strong>Paul Kaiser</strong>]]></description>
		<wfw:commentRss>http://dreamhelg.ru/2010/05/intorducing-into-custom-taxonomy-wordpress-3-0/feed/</wfw:commentRss>
		<slash:comments>29</slash:comments>
		</item>
		<item>
		<title>WordPress. Создаем удобную панель настроек</title>
		<link>http://dreamhelg.ru/2010/04/wordpress-create-better-options-panel/</link>
		<comments>http://dreamhelg.ru/2010/04/wordpress-create-better-options-panel/#comments</comments>
		<pubDate>Fri, 09 Apr 2010 05:00:52 +0000</pubDate>
		<dc:creator>dreamhelg</dc:creator>
				<category><![CDATA[wordpress]]></category>
		<category><![CDATA[переводы]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://dreamhelg.ru/?p=1942</guid>
		<description><![CDATA[<p><img width="200" height="200" src="http://dreamhelg.ru/wp-content/uploads/2010/03/200x200.jpg" class="attachment-200x200 wp-post-image" alt="200x200" title="200x200" /></p>Сегодня, мы подробно рассмотрим процесс создания страницы настроек для темы WordPress, на примере замечательного фреймворка <a href="http://www.woothemes.com/">WooFramework</a>.

Затем, мы немного усложним задачу, используя возможности jQuery, немного улучшим  функциональность страницы.<span id="more-1942"></span>
<br/>
<br/>
WordPress – на сегодняшний день является наиболее популярной системой управления контентом (CMS). Многие разработчики выбирают WordPress в качестве CMS, независимо от типа проекта.

Этой системой очень просто пользоваться, но вы можете сделать ее еще проще, включив дополнительные панели управления для пользователей. Вместо того, чтобы открывать файлы PHP-шаблонов и манипулировать с кодом, пользователи могут использовать обычную страницу настроек в панели управления, и с ее помощью управлять вашей WordPress-темой.

<a href="http://dreamhelg.ru/wp-content/uploads/2010/03/theme.jpg"><img class="aligncenter size-full wp-image-1963" title="theme" src="http://dreamhelg.ru/wp-content/uploads/2010/03/theme.jpg" alt="" width="597" height="518" /></a>

Например, если ваша тема имеет красную, синюю и зеленую цветовые схемы, каждой из которых соответствует определенный CSS-файл, было бы гораздо проще, если бы пользователь мог выбирать нужный цвет из выпадающего списка. Поэтому сегодня, вы познакомитесь с процессом создания и совершенствования дополнительной страницы настроек для панели администрирования WordPress.

<h3>Шаг 1</h3>
Прежде чем мы приступим к созданию панели управления, нам понадобится тема. Поэтому загрузите <a href="http://nettuts.s3.amazonaws.com/575_wp/source.zip">архив</a>, с исходными файлами. Вы увидите слегка измененную классическую тему WordPress. Скопируйте папку “nettuts” (так будет называться наша тема) в папку wp-content/themes. Внутри папки должны быть следующие файлы:
<ul>
	<li>functions.php (пустой)</li>
	<li>index.php</li>
	<li>comments.php</li>
	<li>footer.php</li>
	<li>header.php</li>
	<li>rtl.php</li>
	<li>sidebar.php</li>
	<li>style.css</li>
	<li>screenshot.png</li>
	<li>папка с картинками, содержащая два файла</li>
</ul>

Большая часть нашего кода, будет расположена в файле functions.php.
<blockquote>Тема опционально может использовать функциональный файл, расположенный внутри папки с темой, с именем functions.php. Этот файл действует так же как плагин, и если он входит в состав вашей темы, то он автоматически загружается во время инициализации WordPress (как внешних страниц так и панели администрирования).</blockquote>
Этот файл предполагается использовать для:
<ul>
	<li>описания функций, используемых в различных шаблонных файлах вашей темы</li>
	<li>установки дополнительных панелей управления, позволяющих пользователям настраивать цвета, стили и другие аспекты вашей темы.</li>
</ul>
(<a href="http://codex.wordpress.org/Theme_Development#Theme_Functions_File">Из Кодекса WordPress</a>)
<h3>Шаг 2</h3>
Теперь, после того как вы скачали и установили предложенную тему, зайдите на страницу “Внешний вид” – “Темы”, и активируйте нашу тему nettuts.

<a href="http://dreamhelg.ru/wp-content/uploads/2010/03/theme_active.jpg"><img class="aligncenter size-full wp-image-1964" title="theme_active" src="http://dreamhelg.ru/wp-content/uploads/2010/03/theme_active.jpg" alt="" width="569" height="298" /></a>

Теперь, нам нужно продумать html-разметку для нашей панели управления. Будем использовать вот такую структуру:

[html]
&lt;div class=&quot;wrap rm_wrap&quot;&gt;
	&lt;div class=&quot;rm_opts&quot;&gt;
		&lt;form method=&quot;post&quot;&gt;
			&lt;div class=&quot;rm_section&quot;&gt;
				&lt;div class=&quot;rm_title&gt;
					&lt;h3&gt;Title&lt;/h3&gt;
					&lt;submit button&gt;
				&lt;/div&gt;
				&lt;div class=&quot;rm_input rm_&lt;select/textarea/text etc&gt;&quot;&gt;
					&lt;input area&gt;
					&lt;description&gt;
				&lt;/div&gt;
			&lt;/div&gt;

		/*Выводим инпуты нужное количество раз (соответствующее количеству настроек)*/
		/* используем &lt;div class=&quot;rm_section&quot;&gt; для каждой секции настроек */
		&lt;/form&gt;
	&lt;/div&gt;
&lt;/div&gt;

[/html]

Позвольте мне все вам все здесь объяснить. Группы настроек будут заключены в блок с классом “rm_wrap”, а затем в блок с классом “rp_opts”. Затем, внутри этих блоков, мы открываем тег form, внутри которой будут размещены все необходимые инпуты. Каждая секция настроек (Основные настройки, Настройки домашней страницы, Настройки блога и т.д.) будет расположена в отдельном блоке с именем класса “rm_section”. В этом блоке будет расположено название (для секции настроек) и несколько блоков с инпутами. Используя специальные классы для блоков, типа &lt;div class=”rm_input rm_select”&gt;, мы можем назначить стили выпадающим спискам, текстовым а также многострочным полям.

Наиболее важной частью всего этого является то, что нам не придется создавать весь этот код вручную – мы будем использовать возможности PHP, везде где это возможно. Нет смысла составлять код вручную, когда в нашем распоряжении есть циклы.
<h3>Шаг 3</h3>
Откройте файл functions.php своим любимым редактором кода (я использую NotePad++), и вставьте следующий код:

[php]
&lt;?php

	$themename = &quot;NetTuts&quot;;
	$shortname = &quot;nt&quot;;

[/php]

Это две PHP-переменные, содержащие имя вашей темы (в нашем случае это Nettuts), и псевдоним, который вы укажете (в нашем примере это nt). Псевдоним используется в качестве префикса к именам всех настроек темы, и как правило является уникальным для каждой темы.

Далее, мы создадим пару строчек кода, для автоматического генерирования списка wordpress-рубрик, вместо того, чтобы заставлять пользователя вручную указывать их ID. Вставьте следующий код, сразу же после, предыдущего:

[php]
$categories = get_categories('hide_empty=0&amp;order_by=name');
		$wp_cats = array();

    foreach ($categories as $category_list){
        $wp_cats[$category_list -&gt; cat_ID] = $category_list -&gt; cat_name;
    }

array_unshift($wp_cats, &quot;Выберите рубрику&quot;);
[/php]

Этот фрагмент кода использует встроенную wordpress-функцию get_categories, для получения всех рубрик, а затем, с помощью цикла foreach, сохранения их в переменной $wp_cats. Затем к массиву добавляется опция “выберите рубрику”.

<h3>Шаг 4</h3>
Теперь пришло время создать список настроек для нашей темы. Вставьте следующий код в файл functions.php:

[php]
$options = array(

        array( &quot;name&quot; =&gt; &quot;Настройки&quot;,
                &quot;type&quot; =&gt; &quot;title&quot; ),

        array ( &quot;name&quot; =&gt; &quot;Основные настройки&quot;,
                &quot;type&quot; =&gt; &quot;section&quot; ),
        array ( &quot;type&quot; =&gt; &quot;open&quot;),

        array ( &quot;name&quot; =&gt; &quot;Цветовая схема&quot;,
                &quot;desc&quot; =&gt; &quot;Выберите цветовую схему темы&quot;,
                &quot;id&quot; =&gt; $shortname . &quot;_color_scheme&quot;,
                &quot;type&quot; =&gt; &quot;select&quot;,
                &quot;options&quot; =&gt; array (&quot;синяя&quot;, &quot;красная&quot;, &quot;зеленая&quot;),
                &quot;std&quot; =&gt; &quot;blue&quot; ),

        array ( &quot;name&quot; =&gt; &quot;URL Логотипа&quot;,
                &quot;desc&quot; =&gt; &quot;Введите ссылку к картинке логотипа&quot;,
                &quot;id&quot; =&gt; $shortname . &quot;_logo&quot;,
                &quot;type&quot; =&gt; &quot;text&quot;,
                &quot;std&quot; =&gt; &quot;&quot; ),

        array ( &quot;name&quot; =&gt; &quot;Пользовательский CSS&quot;,
                &quot;desc&quot; =&gt; &quot;Хотите использовать свой CSS-код? Вставьте его в это поле&quot;,
                &quot;id&quot; =&gt; $shortname . &quot;_custom_css&quot;,
                &quot;type&quot; =&gt; &quot;textarea&quot;,
                &quot;std&quot; =&gt; &quot;&quot; ),
        
        array ( &quot;type&quot; =&gt; &quot;close&quot;),

        array ( &quot;name&quot; =&gt; &quot;Домашняя страница&quot;,
                &quot;type&quot; =&gt; &quot;section&quot; ),

        array (&quot;type&quot; =&gt; &quot;open&quot;),

        array ( &quot;name&quot; =&gt; &quot;Картинка в шапке, на главной странице&quot;,
                &quot;desc&quot; =&gt; &quot;Введите URL картинки, которая будет использоваться в шапке&quot;,
                &quot;id&quot; =&gt; $shortname .&quot;_header_img&quot;,
                &quot;type&quot; =&gt; &quot;text&quot;,
                &quot;std&quot; =&gt; &quot;&quot;),

         array ( &quot;name&quot; =&gt; &quot;Рубрика домашней страницы&quot;,
                &quot;desc&quot; =&gt; &quot;Выберите рубрику, в которую будут публиковатся записи&quot;,
                &quot;id&quot; =&gt; $shortname .&quot;_feat_cat&quot;,
                &quot;type&quot; =&gt; &quot;select&quot;,
                &quot;options&quot; =&gt; $wp_cats,
                &quot;std&quot; =&gt; &quot;Выберите рубрику&quot;),
        
        array ( &quot;type&quot; =&gt; &quot;close&quot;),

        array ( &quot;name&quot; =&gt; &quot;Подвал&quot;,
                &quot;type&quot; =&gt; &quot;section&quot;),

        array ( &quot;type&quot; =&gt; &quot;open&quot;),

        array(  &quot;name&quot; =&gt; &quot;Текст копирайта&quot;,
                &quot;desc&quot; =&gt; &quot;Введите текст, который будет размещен в правой части подвала. Можно использовать HTML&quot;,
                &quot;id&quot; =&gt; $shortname.&quot;_footer_text&quot;,
                &quot;type&quot; =&gt; &quot;text&quot;,
                &quot;std&quot; =&gt; &quot;&quot;),

        array(  &quot;name&quot; =&gt; &quot;Код Google Analytics&quot;,
                &quot;desc&quot; =&gt; &quot;Здесь вы можете разместить код Google Analytics, или любой другой счетчик&quot;,
                &quot;id&quot; =&gt; $shortname.&quot;_ga_code&quot;,
                &quot;type&quot; =&gt; &quot;textarea&quot;,
                &quot;std&quot; =&gt; &quot;&quot;),

        array( &quot;name&quot; =&gt; &quot;Favicon&quot;,
                &quot;desc&quot; =&gt; &quot;Favicon - это пиксельная иконка, которая представляет ваш сайт. Вставьте URL к картинке с расширением .ico&quot;,
                &quot;id&quot; =&gt; $shortname.&quot;_favicon&quot;,
                &quot;type&quot; =&gt; &quot;text&quot;,
                &quot;std&quot; =&gt; get_bloginfo('url') .&quot;/favicon.ico&quot;),

        array(  &quot;name&quot; =&gt; &quot;Feedburner URL&quot;,
                &quot;desc&quot; =&gt; &quot;Feedburner - это сервис Google, управляющий RSS-потоками. Paste your Feedburner URL here to let readers see it in your website&quot;,
                &quot;id&quot; =&gt; $shortname.&quot;_feedburner&quot;,
                &quot;type&quot; =&gt; &quot;text&quot;,
                &quot;std&quot; =&gt; get_bloginfo('rss2_url')),

        array( &quot;type&quot; =&gt; &quot;close&quot;)

    );
[/php]

Это был довольно большой фрагмент кода, заслуживающий небольшого разъяснения. Итак:
<ul>
	<li>PHP-переменная $options хранит весь список настроек для нашей темы.</li>
	<li>Список настроек состоит из нескольких массивов, каждый из которых содержит ключ “type”, для определения типа настройки и способа ее отображения.</li>
	<li>Наш список настроек начинается с массива “type” =&gt; “title” – который будет использоваться для отображения имени темы и названия в заголовке страницы.</li>
	<li>Каждый раздел (Основные настройки, Домашняя страница, Подвал) имеет отдельный список настроек.</li>
	<li>Мы начинаем новую секцию, закрывая любую из предыдущих секций, и объявления новой секции с помощью массива array(“name” =&gt; “Подвал”, “type” =&gt; “section”).</li>
	<li>Каждая опция может содержать следующие настройки:
<strong>name:</strong> Имя текстового поля.
<strong>desc: </strong>Короткое описание поля, для пользователя.<strong>
id:</strong> id поля, с префиксом из псевдонима. Оно будет использоваться как для записи настройки, так и для доступа к ней.
<strong>type: </strong>тип input - text, select или textarea
<strong>options:</strong> используется для объявления массива настроек для поля выпадающего списка.
<strong>std:</strong> значение поля по умолчанию, используется если никаких других значений не указано.</li>
</ul>

<h3>Шаг 5</h3>
Попробуйте зайти в панель управления Wordpress. Вы нигде не найдете указанных нами настроек, как же нам отобразить их? Добавляем следующий код в файл functions.php:

[php]
function mytheme_add_admin(){
        
        global $themename, $shortname, $options;
		
        if($_GET['page'] == basename(__FILE__) ){
            
            if( 'saved' == $_REQUEST['action']){
                foreach ($options as $value){
                    update_option($value['id'], $_REQUEST[$value['id']]);
                }

                foreach ($options as $value){
                    if( isset ($_REQUEST[$value['id']]) ){
                        update_option($value['id'], $_REQUEST[$value['id']] );
                    }else{
                        delete_option($value['id']);
                    }
                }
                header(&quot;Location: admin.php?page=functions.php&amp;saved=true&quot;);
                die;
            }
        }

        else if('reset' == $_REQUEST['action']){
            foreach($options as $value){
                delete_option($value['id']);
            }

            header(&quot;Location: admin.php&amp;page=functions.php&amp;reset=true&quot;);

            die;
        }

         add_menu_page($themename, $themename, 'administrator', basename(__FILE__), 'mytheme_admin');
    }

    function mytheme_add_init() {
 
}
[/php]

Эта функция используется как для обновления самих настроек, так и для добавления страницы в панели управления. Если настройки были сохранены (определяется с помощью скрытой переменной save), то все настройки обновляются указанными значениями. Если же, настройки были сброшены (определяется с помощью другой скрытой переменной reset), то все настройки удаляются.

Последняя строка функции, добавляет страницу меню – параметры по порядку: имя и название, уровень пользовательских прав для просмотра страницы, страница сохранения и функция, использующаяся для отображения/сохранения настроек (в нашем примере называется mytheme_admin).

Заметили, что функция mytheme_add_init пустая? Пусть пока останется такой как есть, мы вернемся к ней позже.

<h3>Шаг 6</h3>
Страница настроек в панели управления так и не появилась? Но, мы еще не дописали функцию mytheme_admim, о которой говорилось выше. Для создания этой функции нам понадобится код из шагов 6,7 и 8. Давайте начнем.

[php]
function mytheme_admin(){
        global $themename, $shortname, $options;
        $i = 0;

         if($_REQUEST['action'] == 'save')
	echo '&lt;div id=&quot;message&quot; class=&quot;updated fade&quot;&gt;&lt;p&gt;&lt;strong&gt; настройки темы '. $themename .' были сохранены&lt;/strong&gt;&lt;/p&gt;&lt;/div&gt;';  

        if($_REQUEST['reset'])
            echo '&lt;div id=&quot;message&quot; class=&quot;updated fade&quot;&gt;&lt;p&gt;&lt;strong&gt; настройки темы '. $themename .' были сброшены&lt;/strong&gt;&lt;/p&gt;&lt;/div&gt;';
    ?&gt;

&lt;div class=&quot;wrap rm_wrap&quot;&gt;
    &lt;h2&gt;Настройки &lt;?php echo $themename ?&gt;&lt;/h2&gt;

    &lt;div class=&quot;rm_opts&quot;&gt;
        &lt;form method=&quot;post&quot;&gt;
[/php]

Очень просто, не правда ли? Если настройка была сохранена, выводим подтверждающее сообщение. То же самое для сброса. Обратите внимание на класс “update fade” – WordPress автоматически выведет это сообщение в самом верху окна. Удобно, не правда ли? Идем дальше, начиная с блока “rm_wrap”

<h3>Шаг 7</h3>
Вставляем следующий код, ниже:

[php]
&lt;?php foreach($options as $value) {
                    switch ($value['type']){
                    case &quot;open&quot; :
             ?&gt;

            &lt;?php
                    break;
                    case &quot;close&quot; :
            ?&gt;

            &lt;/div&gt;
            &lt;/div&gt;
            &lt;br /&gt;

            &lt;?php
                    break;
                    case &quot;title&quot; :
            ?&gt;

            &lt;p&gt;Для более удобного управления темой &lt;?php echo $themename;?&gt;, вы можете использовать меню, расположенное ниже&lt;/p&gt;

            &lt;?php
                    break;
                    case &quot;text&quot; :
            ?&gt;

            &lt;div class=&quot;rm_input rm_text&quot;&gt;
                &lt;label for=&quot;&lt;?php echo $value['id']?&gt;&quot;&gt;
                    &lt;?php echo $value['name']?&gt;
                &lt;/label&gt;

                &lt;input name=&quot;&lt;?php echo $value['id']?&gt;&quot; id=&quot;&lt;?php echo $value['id']?&gt;&quot; type=&quot;&lt;?php echo $value['type']?&gt;&quot;
                       value=&quot;&lt;?php if (get_settings($value['id']) != &quot;&quot;){ echo stripslashes(get_settings($value['id'])); } else {echo $value[&quot;std&quot;];} ?&gt;&quot; /&gt;

                &lt;small&gt;&lt;?php echo $value['desc']; ?&gt;&lt;/small&gt;
                &lt;div class=&quot;clearfix&quot;&gt;&lt;/div&gt;
            &lt;/div&gt;

             &lt;?php
                    break;
                    case &quot;textarea&quot; :
            ?&gt;

            &lt;div class=&quot;rm_input rm_textarea&quot;&gt;
                &lt;label for=&quot;&lt;?php echo $value['id']?&gt;&quot;&gt;
                    &lt;?php echo $value['name']?&gt;
                &lt;/label&gt;

                &lt;textarea name=&quot;&lt;?php echo $value['id']?&gt;&quot; type=&quot;&lt;?php echo $value['type']?&gt;&quot; &gt;
                    &lt;?php if (get_settings($value['id']) != &quot;&quot;){
                                echo stripslashes(get_settings($value['id']));
                          }else {
                                echo $value[&quot;std&quot;];
                          }?&gt;
                &lt;/textarea&gt;

                &lt;small&gt;&lt;?php echo $value['desc']; ?&gt;&lt;/small&gt;
                &lt;div class=&quot;clearfix&quot;&gt;&lt;/div&gt;
            &lt;/div&gt;

            &lt;?php
                    break;
[/php]

Здесь используется php-цикл foreach, каждый тип настроек определяется индивидуально для каждого случая. Для этого мы будем использовать оператор switch. Переменная в операторе switch – это текущий тип параметра, case – ожидаемый тип параметра. Вы, наверное, обратили внимание на выражение “break”, после каждого case? Это выражение используется для предотвращения неправильной обработки условия. Когда значение case соответствует переменной, все последующие case также будут выполнены. То есть, если у нас определен case3, то кроме него, также будут выполняться case4, case5 и т.д. Но нам этого не нужно, поэтому мы используем break, для прекращения работы оператора switch.

Если текущее значение параметра “open” – ничего не происходит. Если текущее значение “close”, ставятся два закрывающих блока. Значение параметра “title” используется только один раз – во вступительном тексте перед настройками темы. Для каждого типа “text” (input type=”text”), “select” (выпадающий список) и “textarea” (название говорит само за себя) – отображается соответствующий input. Обратите внимание на блок &lt;div class=”clearfix”&gt; – он используется для чистки флоатов, которые мы будем использовать далее.
<h3>Шаг 8</h3>
Мы приближаемся к концу этой довольно большой функции. Вставьте следующий код:

[php]
case &quot;select&quot; :
            ?&gt;

            &lt;div class=&quot;rm_input rm_select&quot;&gt;
                 &lt;label for=&quot;&lt;?php echo $value['id']?&gt;&quot;&gt;
                    &lt;?php echo $value['name']?&gt;
                &lt;/label&gt;

                &lt;select name=&quot;&lt;?php echo $value['id']; ?&gt;&quot; id=&quot;&lt;?php echo $value['id']; ?&gt;&quot;&gt;
                    &lt;?php foreach ($value['options'] as $option) : ?&gt;
                    &lt;option &lt;?php if(get_settings($value['id']) == $option){ echo &quot;selected=selected&quot;;} ?&gt;&gt;
                        &lt;?php echo $option; ?&gt;
                    &lt;/option&gt;
                    &lt;?php endforeach; ?&gt;
                &lt;/select&gt;

                 &lt;small&gt;&lt;?php echo $value['desc']; ?&gt;&lt;/small&gt;
                 &lt;div class=&quot;clearfix&quot;&gt;&lt;/div&gt;
            &lt;/div&gt;

             &lt;?php
                    break;
                    case &quot;checkbox&quot; :
            ?&gt;

            &lt;div class=&quot;rm_input rm_checkbox&quot;&gt;
                &lt;label for=&quot;&lt;?php echo $value['id']?&gt;&quot;&gt;
                    &lt;?php echo $value['name']?&gt;
                &lt;/label&gt;

                &lt;?php if(get_options($value['id'])){
                        $checked = &quot;checked=\&quot;checked\&quot;&quot;;
                    }else{
                        $checked = &quot;&quot;;
                    }
                ?&gt;

                &lt;input type=&quot;checkbox&quot; name=&quot;&lt;?php echo $value['id']?&gt;&quot; id=&quot;&lt;?php echo $value['id']?&gt;&quot; value=&quot;true&quot; &lt;?php echo $checked; ?&gt; /&gt;

                &lt;small&gt;&lt;?php echo $value['desc']; ?&gt;&lt;/small&gt;
                &lt;div class=&quot;clearfix&quot;&gt;&lt;/div&gt;
            &lt;/div&gt;

            &lt;?php
                    break;
                    case &quot;section&quot; :
                    $i++;
            ?&gt;

            &lt;div class=&quot;rm_section&quot;&gt;
                &lt;div class=&quot;rm_title&quot;&gt;
                    &lt;h3&gt;
                        &lt;img src=&quot;&lt;?php bloginfo('template_directory')?&gt;/functions/images/trans.gif&quot; class=&quot;inactive&quot; alt=&quot;&quot;/&gt;
                        &lt;?php echo $value['name']; ?&gt;
                    &lt;/h3&gt;
					
					 &lt;span class=&quot;submit&quot;&gt;
                            &lt;input name=&quot;save&lt;?php echo $i; ?&gt;&quot; type=&quot;submit&quot; value=&quot;Сохранить&quot; /&gt;
                  	 &lt;/span&gt;
                    &lt;div class=&quot;clearfix&quot;&gt;&lt;/div&gt;
                &lt;/div&gt;

                &lt;div class=&quot;rm_options&quot;&gt;
            &lt;?php
                    break;
                    }
                }
            ?&gt;
            &lt;input type=&quot;hidden&quot; name=&quot;action&quot; value=&quot;save&quot; /&gt;
        &lt;/form&gt;

        &lt;form method=&quot;post&quot;&gt;
            &lt;p class=&quot;submit&quot;&gt;
                &lt;input name=&quot;reset&quot; type=&quot;submit&quot; value=&quot;Сброс&quot; /&gt;
                &lt;input name=&quot;action&quot; type=&quot;hidden&quot; value=&quot;reset&quot; /&gt;
            &lt;/p&gt;
        &lt;/form&gt;

        &lt;div style=&quot;font-size:9px; margin-bottom:10px;&quot;&gt;
            Иконки: &lt;a href=&quot;http://www.woothemes.com/2009/09/woofunction/&quot;&gt;WooFunction&lt;/a&gt;
        &lt;/div&gt;
&lt;/div&gt;

  &lt;?php  }
[/php]

Для типа настройки “section”, мы используем переменную-счетчик $i. Это позволяет отслеживать номер секций и соединять его с именем кнопки отправки данных, получая таким образом уникальное имя для каждой кнопки. Кроме того, в конец секции добавляется форма, для сброса всех настроек. Картинка будет использована для дальнейшей jQuery-фикации. Это последний фрагмент кода, который приведет наши функции в действие:

[php]

add_action('admin_init', 'mytheme_add_init');
add_action('admin_menu', 'mytheme_add_admin');
 
[/php]

Этот код добавляет дополнительную страницу в панели управления WordPress.

<h3>Шаг 9</h3>
<a href="http://dreamhelg.ru/wp-content/uploads/2010/03/theme_no_style.jpg"><img class="aligncenter size-full wp-image-1965" title="theme_no_style" src="http://dreamhelg.ru/wp-content/uploads/2010/03/theme_no_style.jpg" alt="" width="626" height="338" /></a>

Отлично, теперь у нас есть собственная страница управления, с отдельным пунктом меню. Однако, зайдя на эту страничку, мы видим, что не все так хорошо как нам бы хотелось. Но не беда, у нас есть отличный помощник – CSS! Создаем новую папку “functions”, внутри папки nettuts. Внутри этой папки, создаем новый файл – functions.css, и вставляем в него следующий код:

[css]
.rm_wrap{
	width:740px;
}
.rm_section{
	border:1px solid #ddd;
	border-bottom:0;
	background:#f9f9f9;
}
.rm_opts label{
	font-size:12px;
	font-weight:700;
	width:200px;
	display:block;
	float:left;
}
.rm_input {
	padding:30px 10px;
	border-bottom:1px solid #ddd;
	border-top:1px solid #fff;
}
.rm_opts small{
	display:block;
	float:right;
	width:200px;
	color:#999;
}
.rm_opts input[type=&quot;text&quot;], .rm_opts select{
	width:280px;
	font-size:12px;
	padding:4px;
	color:#333;
	line-height:1em;
	background:#f3f3f3;
}
.rm_input input:focus, .rm_input textarea:focus{
		background:#fff;
}
.rm_input textarea{
	width:280px;
	height:175px;
	font-size:12px;
	padding:4px;
	color:#333;
	line-height:1.5em;
	background:#f3f3f3;
}
.rm_title h3 {
	cursor:pointer;
	font-size:1em;
	text-transform: uppercase;
	margin:0;
	font-weight:bold;
	color:#232323;
	float:left;
	width:80%;
	padding:14px 4px;
}
.rm_title{
	cursor:pointer;
	border-bottom:1px solid #ddd;
	background:#eee;
	padding:0;
}
.rm_title h3 img.inactive{
	margin:-8px 10px 0 2px;
	width:32px;
	height:32px;
	background:url('images/pointer.png') no-repeat 0 0;
	float:left;
	-moz-border-radius:6px;
	border:1px solid #ccc;
}
.rm_title h3 img.active{
	margin:-8px 10px 0 2px;
	width:32px;
	height:32px;
	background:url('images/pointer.png') no-repeat  0 -32px;
	float:left;
	-moz-border-radius:6px;
	-webkit-border-radius:6px;
	border:1px solid #ccc;
}
.rm_title h3:hover img{
	border:1px solid #999;
}
.rm_title span.submit{
	display:block;
	float:right;
	margin:0;
	padding:0;
	width:15%;
	padding:14px 0;
}
.clearfix{
	clear:both;
}
.rm_table th, .rm_table td{
	border:1px solid #bbb;
	padding:10px;
	text-align:center;
}
.rm_table th, .rm_table td.feature{
	border-color:#888;
	}

[/css]

Думаю, этот код не требует каких-либо разъяснений, все предельно просто и понятно. Вы, конечно, можете изменять его по своему вкусу.

<h3>Шаг 10</h3>
Теперь, когда у нас есть готовый CSS-файл, как же подключить его к странице, если у нас нет прямого доступа к разделу документа &lt;head&gt;? Помните, мы создали пустую функцию mytheme_add_init()? Вон она-то как раз нам и поможет. Измените ее следующим образом:

[php]
function mytheme_add_init() {
       $file_dir = get_bloginfo('template_directory');
       wp_enqueue_style(&quot;functions&quot;, $file_dir.&quot;/functions/style.css&quot;, false, &quot;1.0&quot;, &quot;all&quot;);
}
[/php]

Этот код подключит файл functions.css в раздел документа &lt;head&gt;. Расположение файла определяется папкой с шаблоном.

<a href="http://dreamhelg.ru/wp-content/uploads/2010/03/theme_no_script.jpg"><img class="aligncenter size-full wp-image-1966" title="theme_no_script" src="http://dreamhelg.ru/wp-content/uploads/2010/03/theme_no_script.jpg" alt="" width="599" height="566" /></a>

<h3>Шаг 11</h3>
Взгляните на нашу страницу. Она выглядит вполне хорошо, осталось лишь добавить функциональность иконкам плюса, в заголовках секции. Для этого будем использовать jQuery. Создайте новый файл rm_script.js внутри папки nettuts/functions/folder. Вставьте следующий код:

[javascript]
jQuery(document).ready(function(){
		jQuery('.rm_options').slideUp();

		jQuery('.rm_section h3').click(function(){
			if(jQuery(this).parent().next('.rm_options').css('display')==='none')
				{	jQuery(this).removeClass('inactive').addClass('active').children('img').removeClass('inactive').addClass('active');

				}
			else
				{	jQuery(this).removeClass('active').addClass('inactive').children('img').removeClass('active').addClass('inactive');
				}

			jQuery(this).parent().next('.rm_options').slideToggle('slow');
		});
});
[/javascript]

Что же делает этот код? После того как DOM загружен, все блоки с классом “rm_options” сворачиваются. Затем, при клике на иконке плюса, удаляется класс “inactive”, и добавляется класс “active”, который заменяет иконку на знак минус. При повторном нажатии этой иконки, происходит обратный процесс. Для сворачивания/разворачивания блоков используется довольно простая функция jQuery slideToggle. Чтобы подключить этот скрипт к странице, мы будем использовать уже знакомую нам функцию mytheme_add_init(), измените ее следующим образом:

[php]
function mytheme_add_init() {
       $file_dir = get_bloginfo('template_directory');
       wp_enqueue_style(&quot;functions&quot;, $file_dir.&quot;/functions/style.css&quot;, false, &quot;1.0&quot;, &quot;all&quot;);
       wp_enqueue_script(&quot;rm_script&quot;, $file_dir.&quot;/functions/script.js&quot;, false, &quot;1.0&quot;);  
}
[/php]

После этого, скрипт должен работать. Проверьте, как это выглядит на странице:

<a href="http://dreamhelg.ru/wp-content/uploads/2010/03/theme_final.jpg"><img class="aligncenter size-full wp-image-1967" title="theme_final" src="http://dreamhelg.ru/wp-content/uploads/2010/03/theme_final.jpg" alt="" width="613" height="399" /></a>
<h3>Шаг 12</h3>
Теперь, после того как наша страница настроек полностью готова, осталось немного рассказать об использовании самих настроек. Код, позволяющий использовать параметры, выглядит следующим образом:

[php]
$var = get_option('nt_colur_scheme');
[/php]

С его помощью, мы сможем реализовать смену цветовой схемы сайта. Это довольно просто:

[php]
/* Изменяем CSS-файл, в зависимости от выбранного цвета */
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot;  href=&quot;&lt;?php bloginfo('template_directory'); ?&gt;/&lt;?php echo get_option('nt_color_scheme'); ?&gt;.css&quot; /&gt; 

/*Выводим текст в подвале, можно использовать HTML-тэги */
&lt;p&gt;&lt;?php echo stripslashes(get_option('bl_footer_text')); ?&gt;&lt;/p&gt;
[/php]

Область применения ограничивается только вашим воображением.

<a href="http://dreamhelg.ru/wp-content/uploads/2010/03/nettuts.zip">Скачать архив с приведенным примером.</a>

Перевод статьи “<a href="http://net.tutsplus.com/tutorials/wordpress/how-to-create-a-better-wordpress-options-panel/">How to Create a Better WordPress Options Panel</a>”, автор <strong>Rohan Mehta</strong>]]></description>
		<wfw:commentRss>http://dreamhelg.ru/2010/04/wordpress-create-better-options-panel/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Создаем счетчик загрузок файла с помощью PHP и MySQL</title>
		<link>http://dreamhelg.ru/2010/03/create-download-counter-with-php-and-mysql/</link>
		<comments>http://dreamhelg.ru/2010/03/create-download-counter-with-php-and-mysql/#comments</comments>
		<pubDate>Thu, 18 Mar 2010 13:38:43 +0000</pubDate>
		<dc:creator>dreamhelg</dc:creator>
				<category><![CDATA[общая]]></category>
		<category><![CDATA[переводы]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://dreamhelg.ru/?p=1921</guid>
		<description><![CDATA[<p><img width="200" height="200" src="http://dreamhelg.ru/wp-content/uploads/2010/03/home.png" class="attachment-200x200 wp-post-image" alt="home" title="home" /></p>В сегодняшней статье, мы создадим простую, но надежную систему учета загрузок файлов. Каждый файл будет иметь соответствующую строку в базе данных, где будет хранится общее число загрузок этого файла. PHP будет обновлять базу данных MySQL, и перенаправлять пользователей на соответствующие файлы.<span id="more-1921"></span>

Чтобы отслеживать количество загрузок, вам понадобится только загрузить файлы в нужную папку, и использовать определенный URL для доступа к ним.

<h3>Шаг 1 – XHTML</h3>
Для начала нам понадобится XHTML-разметка. Она очень простая – это общий блок <strong>file-manager</strong>, содержащий маркированный список, в котором ссылка на каждый файл будет находится внутри элемента <strong>li</strong>.

Файлы, по которым будет учитываться количество скачиваний, нужно загрузить в папку <strong>files</strong>, расположенную в корневой директории скрипта (вы можете посмотреть как организована структура файлов, в архиве с приведенным примером). PHP будет проходить циклом по всем файлам в папке, и добавлять каждый файл в виде отдельного элемента li, в маркированный список.

<strong>demo.php</strong>

[html]
&lt;div id=&quot;file-manager&quot;&gt;

	&lt;ul class=&quot;manager&quot;&gt;

		&lt;!-- The LI items are generated by php --&gt;
		&lt;li&gt;&lt;a href=&quot;download.php?file=photoShoot-1.0.zip&quot;&gt;photoShoot-1.0.zip
			&lt;span class=&quot;download-count&quot; title=&quot;Times Downloaded&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;download-label&quot;&gt;download&lt;/span&gt;&lt;/a&gt;
		&lt;/li&gt;
	&lt;/ul&gt;

&lt;/div&gt;
[/html]

Обратите внимание, что атрибут <strong>href</strong> у ссылки передает имя загружаемого файла в качестве параметра для файла <strong>download.php</strong>. Именно здесь будет происходить подсчет загрузок, как вы увидите в дальнейшем.

Вам не обязательно пользоваться именно этим интерфейсом для организации подсчета загрузок. Вы можете просто разместить ссылки на <strong>download.php</strong> на страницах блога или сайта, и все загрузки будут подсчитаны правильно.

<a href="http://dreamhelg.ru/wp-content/uploads/2010/03/i11.png"><img class="aligncenter size-full wp-image-1922" title="i11" src="http://dreamhelg.ru/wp-content/uploads/2010/03/i11.png" alt="" width="620" height="460" /></a>

<h3>Шаг 2 – CSS</h3>
После того как наша XHTML-разметка готова, мы можем сконцентрироваться на внешнем виде нашего скрипта. CSS-стили, представленные ниже, назначают внешний вид блоку file-manager, через его ID, поскольку он у нас один на странице. Остальные элементы стилизуются через имена классов.

<strong>style.css</strong>

[css]
#file-manager{
	background-color:#EEE;
	border:1px solid #DDD;
	margin:50px auto;
	padding:10px;
	width:400px;
}

ul.manager li{
	background:url(&quot;img/bg_gradient.gif&quot;) repeat-x center bottom #F5F5F5;
	border:1px solid #DDD;
	border-top-color:#FFF;

	list-style:none;
	position:relative;
}

ul.manager li a{
	display:block;
	padding:8px;
}

ul.manager li a:hover .download-label{
	/* When a list is hovered over, show the download green text inside it: */
	display:block;
}

span.download-label{
	background-color:#64B126;
	border:1px solid #4E9416;
	color:white;
	display:none;
	font-size:10px;
	padding:2px 4px;
	position:absolute;
	right:8px;
	text-decoration:none;
	text-shadow:0 0 1px #315D0D;
	top:6px;

	/* CSS3 Rounded Corners */

	-moz-border-radius:3px;
	-webkit-border-radius:3px;
	border-radius:3px;
}

span.download-count{
	color:#999;
	font-size:10px;
	padding:3px 5px;
	position:absolute;
	text-decoration:none;
}
[/css]

Обратите внимание, что здесь подпись “download” скрыта по умолчанию, с помощью свойства <strong>display: none</strong>. Она отображается через <strong>display:block</strong>, только при наведении мыши на ссылку, без использования JavaScript. Немного CSS3 используется для закругления уголков у подписи.

<a href="http://dreamhelg.ru/wp-content/uploads/2010/03/i21.png"><img class="aligncenter size-full wp-image-1923" title="i21" src="http://dreamhelg.ru/wp-content/uploads/2010/03/i21.png" alt="" width="620" height="260" /></a>

<h3>Шаг 3 – PHP</h3>
Как мы уже говорили выше, PHP проходит циклом по всей папке <strong>files</strong>, и выводит каждый файл в виде элемента li маркированного списка. Давайте рассмотрим подробнее, как это происходит.

<strong>demo.php  - Верхняя часть</strong>

[php]
// Error reporting:
error_reporting(E_ALL^E_NOTICE);

// Including the DB connection file:
require 'connect.php';

$extension='';
$files_array = array();

/* Opening the thumbnail directory and looping through all the thumbs: */

$dir_handle = @opendir($directory) or die(&quot;There is an error with your file directory!&quot;);

while ($file = readdir($dir_handle))
{
	/* Skipping the system files: */
	if($file{0}=='.') continue;

	/* end() returns the last element of the array generated by the explode() function: */
	$extension = strtolower(end(explode('.',$file)));

	/* Skipping the php files: */
	if($extension == 'php') continue;

	$files_array[]=$file;
}

/* Sorting the files alphabetically */
sort($files_array,SORT_STRING);

$file_downloads=array();

$result = mysql_query(&quot;SELECT * FROM download_manager&quot;);

if(mysql_num_rows($result))
while($row=mysql_fetch_assoc($result))
{
	/* 	The key of the $file_downloads array will be the name of the file,
		and will contain the number of downloads: */

	$file_downloads[$row['filename']]=$row['downloads'];
}
[/php]

Обратите внимание, как мы выбираем все записи из таблицы download_manager с помощью <strong>mysql_query()</strong> и затем добавляем их в массив <strong>$file_downloads</strong>, с ключом массива filename, и значением downloads. Таким образом, далее в коде, мы сможем записать <strong>$file_downloads[‘archive.zip’]</strong>, и вывести количество загрузок этого файла.

Ниже представлен код, который используется для генерации элементов li маркированного списка.

<strong>demo.php – Центральная часть</strong>

[php]
foreach($files_array as $key=&gt;$val)
{
	echo '&lt;li&gt;&lt;a href=&quot;download.php?file='.urlencode($val).'&quot;&gt;'.$val.'
		&lt;span class=&quot;download-count&quot; title=&quot;Times Downloaded&quot;&gt;'.(int)$file_downloads[$val].'&lt;/span&gt; &lt;span class=&quot;download-label&quot;&gt;download&lt;/span&gt;&lt;/a&gt;
	&lt;/li&gt;';
}
[/php]

Все очень просто – проходим циклом <strong>foreach</strong> по массиву <strong>$files_array</strong>, и выводим на страницу нужные данные в соответствующей разметке.

Теперь давайте более подробно рассмотрим как происходит учет загрузок.

<strong>download.php</strong>

[php]
// Error reporting:
error_reporting(E_ALL^E_NOTICE);

// Including the connection file:
require('connect.php');

if(!$_GET['file']) error('Missing parameter!');
if($_GET['file']{0}=='.') error('Wrong file!');

if(file_exists($directory.'/'.$_GET['file']))
{
	/* If the visitor is not a search engine, count the downoad: */
	if(!is_bot())
	mysql_query(&quot;	INSERT INTO download_manager SET filename='&quot;.mysql_real_escape_string($_GET['file']).&quot;'
					ON DUPLICATE KEY UPDATE downloads=downloads+1&quot;);

	header(&quot;Location: &quot;.$directory.&quot;/&quot;.$_GET['file']);
	exit;
}
else error(&quot;This file does not exist!&quot;);

/* Helper functions: */

function error($str)
{
	die($str);
}

function is_bot()
{
	/* This function will check whether the visitor is a search engine robot */

	$botlist = array(&quot;Teoma&quot;, &quot;alexa&quot;, &quot;froogle&quot;, &quot;Gigabot&quot;, &quot;inktomi&quot;,
	&quot;looksmart&quot;, &quot;URL_Spider_SQL&quot;, &quot;Firefly&quot;, &quot;NationalDirectory&quot;,
	&quot;Ask Jeeves&quot;, &quot;TECNOSEEK&quot;, &quot;InfoSeek&quot;, &quot;WebFindBot&quot;, &quot;girafabot&quot;,
	&quot;crawler&quot;, &quot;www.galaxy.com&quot;, &quot;Googlebot&quot;, &quot;Scooter&quot;, &quot;Slurp&quot;,
	&quot;msnbot&quot;, &quot;appie&quot;, &quot;FAST&quot;, &quot;WebBug&quot;, &quot;Spade&quot;, &quot;ZyBorg&quot;, &quot;rabaz&quot;,
	&quot;Baiduspider&quot;, &quot;Feedfetcher-Google&quot;, &quot;TechnoratiSnoop&quot;, &quot;Rankivabot&quot;,
	&quot;Mediapartners-Google&quot;, &quot;Sogou web spider&quot;, &quot;WebAlta Crawler&quot;,&quot;TweetmemeBot&quot;,
	&quot;Butterfly&quot;,&quot;Twitturls&quot;,&quot;Me.dium&quot;,&quot;Twiceler&quot;);

	foreach($botlist as $bot)
	{
		if(strpos($_SERVER['HTTP_USER_AGENT'],$bot)!==false)
		return true;	// Is a bot
	}

	return false;	// Not a bot
}
[/php]

Здесь обязательно нужно проверить, не является ли посетитель роботом поисковой системы, сканирующим ваши ссылки. Роботы – это хорошие посетители, поскольку они помогают включить ваш сайт в поисковые сервисы, однако в нашем случае, они могут исказить статистику загрузок. Вот почему база данных обновляется только после того, как посетитель пройдет проверку <strong>is_bot().</strong>

<h3>Шаг 4 – MySQL</h3>
Как мы упоминали в предыдущем шаге, количество загрузок записывается в виде строки, в таблицу download_manager, базы данных MySQL. Сначала, позвольте объяснить как работает эта часть запроса:

<strong>download.php</strong>

[sql]
INSERT INTO download_manager SET filename='filename.doc'
ON DUPLICATE KEY UPDATE downloads=downloads+1
[/sql]

Первая часть запроса говорит MySQL вставить новую строчку в таблицу <strong>download_manager</strong>, и установить значение поля <strong>filename</strong> равным имени запрашиваемого для загрузки файла. Кроме этого, поле <strong>filename</strong> определено как уникальный индекс таблицы. Это значит, что строка с конкретным именем файла, может быть вставлена только один раз, иначе произойдет ошибка дублирования ключевых полей.

Именно в этом случае, вступает в силу вторая часть запроса - <strong>ON DUPLICATE KEY UPDATE</strong>, которая увеличивает значение поля <strong>downloads</strong> на единицу, если этот файл уже записан в базе данных.

Таким образом, новые файлы будут автоматически вставляться в базу данных в первый раз, после того как загружены.

<a href="http://dreamhelg.ru/wp-content/uploads/2010/03/i31.png"><img class="aligncenter size-full wp-image-1924" title="i31" src="http://dreamhelg.ru/wp-content/uploads/2010/03/i31.png" alt="" width="620" height="260" /></a>

<h3>Шаг 5 – jQuery</h3>
Для того, чтобы сделать наш счетчик загрузок более наглядным, было бы неплохо добавить возможность обновлять счетчик, находящийся рядом с именем файла, сразу после того, как пользователь начнет загрузку. Пока что, для того чтобы увидеть новые значения счетчиков, пользователю нужно перезагрузить страницу.

Это можно исправить небольшим фрагментом кода:

<strong>script.js</strong>

[javascript]
$(document).ready(function(){
	/* This code is executed after the DOM has been completely loaded */

	$('ul.manager a').click(function(){

		var countSpan = $('.download-count',this);
		countSpan.text( parseInt(countSpan.text())+1);
	});
});
[/javascript]

Мы просто назначили обработчик события на клик по ссылке. Каждый раз, после того, как пользователь кликнет по ссылке, мы увеличиваем текущее значение загрузок на единицу.

<h3>Шаг 6 – htaccess</h3>
Нам осталось сделать еще одну вещь, прежде чем можно будет назвать работу законченной. Возможно, вы уже заметили, что некоторые типы файлов, браузер по умолчанию пытается сразу же открывать. Вместо этого, нам нужно запускать загрузку файла. Это довольно легко сделать, добавив несколько строчек внутри файла <strong>.htaccess</strong>, расположенного в папке <strong>files</strong>:

[php]
&lt;Files *.*&gt;
ForceType application/octet-stream
&lt;/Files&gt;
[/php]

Вот и все, наш счетчик загрузок готов.
<h3>Заключение</h3>
Чтобы запустить этот пример на своем собственном сервере, вам понадобится создать таблицу download_manager в базе данных MySQL, к которой у вас разумеется есть доступ. В архиве с примером, есть файл <strong>table.sql</strong>, который содержит необходимый SQL-код, который создаст нужную таблицу.

После этого, просто укажите свои данные подключения к базе, в файле <strong>configuration.php</strong>.

<a href="http://demo.tutorialzine.com/2010/02/php-mysql-download-counter/demo.php">Смотреть демо.</a>

<a href="http://dreamhelg.ru/wp-content/uploads/2010/03/counter.zip">Архив с приведенным примером</a>.


Перевод статьи “<a href="http://tutorialzine.com/2010/02/php-mysql-download-counter/">PHP &amp; MySQL File Download Counter</a>”, автор <strong>Martin Angelov</strong>]]></description>
		<wfw:commentRss>http://dreamhelg.ru/2010/03/create-download-counter-with-php-and-mysql/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>15 регулярных выражений PHP в помощь веб-разработчику</title>
		<link>http://dreamhelg.ru/2010/02/15-regular-expression-for-web-developers/</link>
		<comments>http://dreamhelg.ru/2010/02/15-regular-expression-for-web-developers/#comments</comments>
		<pubDate>Fri, 12 Feb 2010 11:49:52 +0000</pubDate>
		<dc:creator>dreamhelg</dc:creator>
				<category><![CDATA[общая]]></category>
		<category><![CDATA[переводы]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://dreamhelg.ru/?p=1881</guid>
		<description><![CDATA[<p><img width="200" height="200" src="http://dreamhelg.ru/wp-content/uploads/2010/02/home.png" class="attachment-200x200 wp-post-image" alt="home" title="home" /></p>Регулярные выражения – это очень полезный инструмент для разработчиков. С их помощью можно находить, определять или заменять текст, слова или любые другие символы. В сегодняшней статье собраны 15 наиболее полезных регулярных выражений, которые пригодятся любому веб-разработчику.<span id="more-1881"></span>
<h3>Введение в регулярные выражения</h3>
Многим начинающим разработчикам кажется, что регулярные выражения очень сложны для понимания и использования. На самом деле, все не так уж сложно, как может показаться. Прежде чем мы непосредственно перейдем к регулярным выражениям, с их полезным и универсальным кодом, давайте взглянем на основы:

<strong>Синтаксис регулярных выражений</strong>
<table border="1" cellspacing="0" cellpadding="2" width="550">
<tbody>
<tr>
<td width="249" valign="top"><strong>Регулярное выражение</strong></td>
<td width="347" valign="top"><strong>Означает</strong></td>
</tr>
<tr>
<td width="249" valign="top">foo</td>
<td width="347" valign="top">Строка “foo”</td>
</tr>
<tr>
<td width="249" valign="top">^foo</td>
<td width="347" valign="top">Строка начинается с “foo”</td>
</tr>
<tr>
<td width="249" valign="top">foo$</td>
<td width="347" valign="top">Строка заканчивается на “foo”</td>
</tr>
<tr>
<td width="249" valign="top">^foo$</td>
<td width="347" valign="top">"foo" встречается в строке только один раз</td>
</tr>
<tr>
<td width="249" valign="top">[abc]</td>
<td width="347" valign="top">a, b, или c</td>
</tr>
<tr>
<td width="249" valign="top">[a-z]</td>
<td width="347" valign="top">любой символ в нижнем регистре</td>
</tr>
<tr>
<td width="249" valign="top">[^A-Z]</td>
<td width="347" valign="top">любой символ, не находящийся в верхнем регистре</td>
</tr>
<tr>
<td width="249" valign="top">(gif|jpg)</td>
<td width="347" valign="top">Означает как "gif” так и “jpeg”</td>
</tr>
<tr>
<td width="249" valign="top">[a-z]+</td>
<td width="347" valign="top">Один или более символов нижнего регистра</td>
</tr>
<tr>
<td width="249" valign="top">[0-9.-]</td>
<td width="347" valign="top">Любая цифра, точка или знак минус</td>
</tr>
<tr>
<td width="249" valign="top">^[a-zA-Z0-9_]{1,}$</td>
<td width="347" valign="top">Любое слово, хотя бы одна буква, число или _</td>
</tr>
<tr>
<td width="249" valign="top">([wx])([yz])</td>
<td width="347" valign="top">wy, wz, xy, или xz</td>
</tr>
<tr>
<td width="249" valign="top">(^A-Za-z0-9)</td>
<td width="347" valign="top">Любой символ (не число и не буква)</td>
</tr>
<tr>
<td width="249" valign="top">([A-Z]{3}|[0-9]{4})</td>
<td width="347" valign="top">Означает три буквы или 4 цифры</td>
</tr>
</tbody>
</table>
<br/><strong>PHP-функции для регулярных выражений</strong>

<table border="1" cellspacing="0" cellpadding="2" width="550">
<tbody>
<tr>
<td width="130" valign="top"><strong>Функция</strong></td>
<td width="468" valign="top"><strong>Описание</strong></td>
</tr>
<tr>
<td width="130" valign="top">preg_match()</td>
<td width="468" valign="top">Функция preg_match() ищет строку по заданному шаблону, возвращает true, если строка находится и false, в остальных случаях</td>
</tr>
<tr>
<td width="130" valign="top">preg_match_all()</td>
<td width="468" valign="top">Функция preg_match_all() находит все вхождения строки, заданной по шаблону</td>
</tr>
<tr>
<td width="130" valign="top">preg_replace()</td>
<td width="468" valign="top">Функция preg_replace(), действует по тому же принципу, что и ereg_replace(), за исключением того, что регулярные выражения можно использовать как для задания шаблона поиска, так и для строки, на которую следует заменить, найденное значение.</td>
</tr>
<tr>
<td width="130" valign="top">preg_split()</td>
<td width="468" valign="top">Функция preg_split(), действует так же как split(), за исключением того, что регулярное выражение можно использовать в качестве параметра для шаблона поиска.</td>
</tr>
<tr>
<td width="130" valign="top">preg_grep()</td>
<td width="468" valign="top">Функция preg_grep() ищет все элементы входного массива, возвращая все элементы, соответствующие шаблону регулярного выражения.</td>
</tr>
<tr>
<td width="130" valign="top">preg_quote()</td>
<td width="468" valign="top">Экранирует символы регулярного выражения</td>
</tr>
</tbody>
</table>
<h3>Проверка доменного имени</h3>
Проверяем, является ли строка правильным доменным именем

[php]
$url = &quot;http://komunitasweb.com/&quot;;
if (preg_match('/^(http|https|ftp)://([A-Z0-9][A-Z0-9_-]*(?:.[A-Z0-9][A-Z0-9_-]*)+):?(d+)?/?/i', $url)) {
    echo &quot;Your url is ok.&quot;;
} else {
    echo &quot;Wrong url.&quot;;
}
[/php]
<h3>Подсветка слова в тексте</h3>
Это очень полезное регулярное выражение, с его помощью вы можете найти нужное слово и подсветить его. Особенно полезно для отображения результатов поиска.

[php]
$text = &quot;Sample sentence from KomunitasWeb, regex has become popular in web programming. Now we learn regex. According to wikipedia, Regular expressions (abbreviated as regex or regexp, with plural forms regexes, regexps, or regexen) are written in a formal language that can be interpreted by a regular expression processor&quot;;
$text = preg_replace(&quot;/b(regex)b/i&quot;, '&lt;span style=&quot;background:#5fc9f6&quot;&gt;1&lt;/span&gt;', $text);
echo $text;
[/php]
<h3>Подсветка результатов поиска в WordPress блоге</h3>
Как уже говорилось в предыдущем примере, этот пример кода, удобно использовать в выдаче поисковых результатов и есть отличный способ внедрить эту функцию в wordpress-блог.

Откройте ваш файл search.php, и найдите функцию the_title(). Замените ее следующим кодом:

[php]
echo $title;
[/php]

Теперь, выше этой строки, добавьте этот код:

[php]
&lt;?php
	$title 	= get_the_title();
	$keys= explode(&quot; &quot;,$s);
	$title 	= preg_replace('/('.implode('|', $keys) .')/iu',
		'&lt;strong class=&quot;search-excerpt&quot;&gt;&#92;&#48;&lt;/strong&gt;',
		$title);
?&gt;
[/php]

Сохраните файл search.php, и откройте style.css. Добавьте следующую строку:

[css]
strong.search-excerpt { background: yellow; }
[/css]
<h3>Получение всех картинок из HTML-документа</h3>
Если вам когда-нибудь требовалось получить все картинки с веб-страницы, этот код должен быть Вы легко сможете создать загрузчик изображений с помощью возможностей <a href="http://www.catswhocode.com/blog/10-awesome-things-to-do-with-curl">cURL</a>

[php]
$images = array();
preg_match_all('/(img|src)=(&quot;|')[^&quot;'&gt;]+/i', $data, $media);
unset($data);
$data=preg_replace('/(img|src)(&quot;|'|=&quot;|=')(.*)/i',&quot;$3&quot;,$media[0]);
foreach($data as $url)
{
	$info = pathinfo($url);
	if (isset($info['extension']))
	{
		if (($info['extension'] == 'jpg') ||
		($info['extension'] == 'jpeg') ||
		($info['extension'] == 'gif') ||
		($info['extension'] == 'png'))
		array_push($images, $url);
	}
}
[/php]
<h3>Удаление повторяющихся слов (не чувствителен к регистру)</h3>
Во время печатания, часто повторяются слова? Поможет это регулярное выражение.

[php]
$text = preg_replace(&quot;/s(w+s)1/i&quot;, &quot;$1&quot;, $text);
[/php]
<h3>Удаление повторяющейся пунктуации</h3>
То же самое, только для пунктуации. Попрощайтесь с двойными запятыми.

[php]
$text = preg_replace(&quot;/.+/i&quot;, &quot;.&quot;, $text);
[/php]
<h3>Поиск XML/HTML тэгов</h3>
Эта простая функция, принимает два аргумента. Первый – это тэг, который вам нужно найти, и второй – это переменная, содержащая XML или HTML. Повторюсь, эту функцию очень удобно использовать вместе с cURL.

[php]
function get_tag( $tag, $xml ) {
  $tag = preg_quote($tag);
  preg_match_all('{&lt;'.$tag.'[^&gt;]*&gt;(.*?)&lt;/'.$tag.'&gt;.'}',
                   $xml,
                   $matches,
                   PREG_PATTERN_ORDER);

  return $matches[1];
}
[/php]
<h3>Поиск XHTML/XML тэгов с определенным значением атрибута</h3>
Эта функция очень похожа на предыдущую, за исключением того, что вы можете задать тегу нужный атрибут. Например, вы легко сможете найти &lt;div id=”header”&gt;.

[php]
function get_tag( $attr, $value, $xml, $tag=null ) {
  if( is_null($tag) )
    $tag = '\w+';
  else
    $tag = preg_quote($tag);

  $attr = preg_quote($attr);
  $value = preg_quote($value);

  $tag_regex = &quot;/&lt;(&quot;.$tag.&quot;)[^&gt;]*$attr\s*=\s*&quot;.
                &quot;(['\&quot;])$value\\2[^&gt;]*&gt;(.*?)&lt;\/\\1&gt;/&quot;

  preg_match_all($tag_regex,
                 $xml,
                 $matches,
                 PREG_PATTERN_ORDER);

  return $matches[3];
}
[/php]
<h3>Поиск шестнадцатеричных значений цветов</h3>
Еще один полезный инструмент для веб-разработчика! Он позволяет вам находить/проверять шестнадцатеричные значение цвета.

[php]
$string = &quot;#555555&quot;;
if (preg_match('/^#(?:(?:[a-fd]{3}){1,2})$/i', $string)) {
echo &quot;example 6 successful.&quot;;
}
[/php]
<h3>Поиск заголовка статьи</h3>
Этот фрагмент кода найдет и выведет на экран текст, находящийся внутри тэгов &lt;title&gt;&lt;/title&gt;, на html-странице.

[php]
$fp = fopen(&quot;http://www.catswhocode.com/blog&quot;,&quot;r&quot;);
while (!feof($fp) ){
    $page .= fgets($fp, 4096);
}

$titre = eregi(&quot;&lt;title&gt;(.*)&lt;/title&gt;&quot;,$page,$regs);
echo $regs[1];
fclose($fp);
[/php]
<h3>Парсинг логов Apache</h3>
Большинство сайтов запущено на всем известном веб-сервере Apache. Если ваш сайт находится в их числе, почему бы не использовать PHP и регулярные выражения для разбора логов апача?

[php]
//Logs: Apache web server
//Successful hits to HTML files only.  Useful for counting the number of page views.
'^((?#client IP or domain name)S+)s+((?#basic authentication)S+s+S+)s+[((?#date and time)[^]]+)]s+&quot;(?:GET|POST|HEAD) ((?#file)/[^ ?&quot;]+?.html?)??((?#parameters)[^ ?&quot;]+)? HTTP/[0-9.]+&quot;s+(?#status code)200s+((?#bytes transferred)[-0-9]+)s+&quot;((?#referrer)[^&quot;]*)&quot;s+&quot;((?#user agent)[^&quot;]*)&quot;$'

//Logs: Apache web server
//404 errors only
'^((?#client IP or domain name)S+)s+((?#basic authentication)S+s+S+)s+[((?#date and time)[^]]+)]s+&quot;(?:GET|POST|HEAD) ((?#file)[^ ?&quot;]+)??((?#parameters)[^ ?&quot;]+)? HTTP/[0-9.]+&quot;s+(?#status code)404s+((?#bytes transferred)[-0-9]+)s+&quot;((?#referrer)[^&quot;]*)&quot;s+&quot;((?#user agent)[^&quot;]*)&quot;$'
[/php]
<h3>Замена двойных кавычек “умными” кавычками</h3>
Если вы любитель типографики, вам понравится это регулярное выражение, заменяющее обычные двойные кавычки, на “умные кавычки”. Похожее регулярное выражение используется в wordpress в контенте страницы.

[php]
preg_replace('B&quot;b([^&quot;x84x93x94rn]+)b&quot;B', '?1?', $text);
[/php]
<h3>Комплексная проверка пароля</h3>
Это регулярное выражение будет следить за тем, чтобы в текстовое поле было введено не менее шести символов, цифры, дефисы и подчеркивания.

Текстовое поле должно содержать как минимум один символ верхнего регистра, один нижнего регистра и одну цифру.

[php]
'A(?=[-_a-zA-Z0-9]*?[A-Z])(?=[-_a-zA-Z0-9]*?[a-z])(?=[-_a-zA-Z0-9]*?[0-9])[-_a-zA-Z0-9]{6,}z'
[/php]
<h3>WordPress: Использование регулярного выражения для получения картинок из записи</h3>
Поскольку многие из вас являются пользователями WordPress, вам возможно пригодится код, который позволяет получить все картинки, из текста статьи, и вывести их.

Для того, чтобы использовать этот код, просто вставьте его в любой файл вашей темы.

[php]
&lt;?php if (have_posts()) : ?&gt;
&lt;?php while (have_posts()) : the_post(); ?&gt;

&lt;?php
$szPostContent = $post-&gt;post_content;
$szSearchPattern = '~&lt;img [^&gt;]* /&gt;~';

// Run preg_match_all to grab all the images and save the results in $aPics
preg_match_all( $szSearchPattern, $szPostContent, $aPics );

// Check to see if we have at least 1 image
$iNumberOfPics = count($aPics[0]);

if ( $iNumberOfPics &gt; 0 ) {
     // Now here you would do whatever you need to do with the images
     // For this example the images are just displayed
     for ( $i=0; $i &lt; $iNumberOfPics ; $i++ ) {
          echo $aPics[0][$i];
     };
};

endwhile;
endif;
?&gt;
[/php]
<h3>Генерация автоматических смайлов</h3>
Другая функция, используемая в wordpress – позволяет автоматически заменять символы смайлов на картинку смайла.

[php]
$texte='A text with a smiley :-)';
echo str_replace(':-)','&lt;img src=&quot;smileys/souriant.png&quot;&gt;',$texte);
[/php]

Перевод статьи “<a href="http://www.catswhocode.com/blog/15-php-regular-expressions-for-web-developers">15 PHP regular expressions for web developers</a>”, автор <strong>Jean-Baptiste Jung</strong>]]></description>
		<wfw:commentRss>http://dreamhelg.ru/2010/02/15-regular-expression-for-web-developers/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Фантастическая CSS3 лайтбокс галерея с помощью jQuery</title>
		<link>http://dreamhelg.ru/2009/12/fancy-lightbox-css3-image-gallery-with-jquery/</link>
		<comments>http://dreamhelg.ru/2009/12/fancy-lightbox-css3-image-gallery-with-jquery/#comments</comments>
		<pubDate>Tue, 22 Dec 2009 11:31:42 +0000</pubDate>
		<dc:creator>dreamhelg</dc:creator>
				<category><![CDATA[верстка]]></category>
		<category><![CDATA[переводы]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[drag-and-drop]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://dreamhelg.ru/?p=1789</guid>
		<description><![CDATA[<p><img width="200" height="200" src="http://dreamhelg.ru/wp-content/uploads/2009/12/home.png" class="attachment-200x200 wp-post-image" alt="home" title="home" /></p>С удовольствием принимаю эстафету по обзору полезных зарубежных ресурсов, предложенную блоггером <a href="http://cuprum.name/">cuprum</a>, и сегодня, хочу представить вашему вниманию англоязычный блог - <a href="http://tutorialzine.com">tutorialzine.com</a>. Этот блог отличается от других, главным образом тем, что в нем регулярно публикуются очень красивые, а главное полезные, готовые решения для веб-разработчика. И сегодняшняя статья – не исключение.<span id="more-1789"></span>

В сегодняшней статье, мы создадим отличную фото-галерею, которая использует новейшие техники <strong>CSS3</strong> и <strong>Jquery</strong>. Созданный нами скрипт, будет сканировать папку с картинками на вашем веб-сервере, и строить на основе полученных данных полноценную drag-and-drop галерею.

Это решение будет SEO-дружелюбным, кроме того оно будет работать даже с браузерами, выпущенными в одно время с IE6 (за исключением потери нескольких красивых эффектов).

Мы будем использовать <strong>jQuery</strong>, <strong>jQuery UI</strong> (для реализации drag-and-drop) и плагин jQuery <a href="http://fancybox.net/">fancybox</a> в дополнение к PHP и CSS, для интерактивности и стилизации.

Прежде чем мы начнем, взгляните на конечный <a href="http://demo.tutorialzine.com/2009/11/hovering-gallery-css3-jquery/demo.php">результат</a>.

Итак, давайте перейдем к первому шагу.
<h3>Шаг 1 – XHTML</h3>
Основная идея в том, чтобы использовать PHP для генерации необходимой XHTML-разметки для каждого  изображения. Сгенерированный код, в дальнейшем будет включен в файл demo.php.

<strong>demo.php</strong>

[html]
&lt;!-- The gallery container: --&gt;
&lt;div id=&quot;gallery&quot;&gt;

&lt;?php
/* PHP code, covered in detail in step 3 */
?&gt;

&lt;!-- The droppable share box --&gt;
&lt;div class=&quot;drop-box&quot;&gt;
&lt;/div&gt;

&lt;/div&gt;

&lt;div class=&quot;clear&quot;&gt;&lt;/div&gt;

&lt;!-- This is later converted to the modal window with the url of the image: --&gt;
&lt;div id=&quot;modal&quot; title=&quot;Share this picture&quot;&gt;
&lt;form&gt;
&lt;fieldset&gt;
&lt;label for=&quot;name&quot;&gt;URL of the image&lt;/label&gt;
&lt;input type=&quot;text&quot; name=&quot;url&quot; id=&quot;url&quot; class=&quot;text ui-widget-content ui-corner-all&quot; onfocus=&quot;this.select()&quot; /&gt;
&lt;/fieldset&gt;
&lt;/form&gt;

&lt;/div&gt;
[/html]

Здесь нет ничего сложного. Обратите внимание на блок с <code>id =”modal” </code> - он используется для создания модального окна, которое отображается, если пользователь перетаскивает изображение на блок "drop to share". Но подробнее об этом, мы поговорим позже.

<a href="http://dreamhelg.ru/wp-content/uploads/2009/12/i12.jpg"><img class="aligncenter size-full wp-image-1795" title="i12" src="http://dreamhelg.ru/wp-content/uploads/2009/12/i12.jpg" alt="" width="600" height="460" /></a>

<h3>Шаг 2 – CSS</h3>
Теперь, когда у нас есть вся необходимая разметка, пришло время ее стилизовать. Сначала, нам нужно включить CSS-файлы в секции <code>head</code> нашей страницы.

<strong>demo.php</strong>

[html]
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;demo.css&quot; /&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/ui-darkness/jquery-ui.css&quot; type=&quot;text/css&quot; media=&quot;all&quot; /&gt;
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;fancybox/jquery.fancybox-1.2.6.css&quot;&gt;
[/html]

После этого, можно перейти к написанию стилей.

<strong>demo.css</strong>

[css]
body{
	/* Styling the body */
	color:white;
	font-size:13px;
	background: #222222;
	font-family:Arial, Helvetica, sans-serif;
}

#gallery{
	/* The pics container */
	width:100%;
	height:580px;
	position:relative;
}

.pic, .pic a{
	/* Each picture and the hyperlink inside it */
	width:100px;
	height:100px;
	overflow:hidden;
}

.pic{
	/* Styles specific to the pic class */
	position:absolute;
	border:5px solid #EEEEEE;
	border-bottom:18px solid #eeeeee;

	/* CSS3 Box Shadow */
	-moz-box-shadow:2px 2px 3px #333333;
	-webkit-box-shadow:2px 2px 3px #333333;
	box-shadow:2px 2px 3px #333333;
}

.pic a{
	/* Specific styles for the hyperlinks */
	text-indent:-999px;
	display:block;
	/* Setting display to block enables advanced styling for links */
}

.drop-box{
	/* The share box */
	width:240px;
	height:130px;
	position:absolute;
	bottom:0;
	right:0;
	z-index:-1;

	background:url(img/drop_box.png) no-repeat;
}

.drop-box.active{
	/* The active style is in effect when there is a pic hovering above the box */
	background-position:bottom left;
}

label, input{
	/* The modal dialog URL field */
	display:block;
	padding:3px;
}

label{
	font-size:10px;
}

fieldset{
	border:0;
	margin-top:10px;
}

#url{
	/* The URL field */
	width:240px;
}
[/css]

Один из представленных выше классов нуждается в пояснении, это CSS-класс <code>pic</code>. Он используется для того картинки выглядели как полароидные снимки. Для достижения такого эффекта, каждому изображению добавляется белая рамка.

Кроме того, в этом классе используется CSS3-свойство <code>box-shadow</code>, благодаря которому, каждый снимок отбрасывает тень.

Если вы посмотрите на демо-страницу, то увидите, что фотографии разбросаны по страницы и развернуты в разные стороны. Такой эффект достигается с помощью CSS, на стороне PHP, как вы скоро увидите.

Остальные стили очень простые, и не нуждаются в детальном объяснении.

<a href="http://dreamhelg.ru/wp-content/uploads/2009/12/images.png"><img class="aligncenter size-full wp-image-1796" title="images" src="http://dreamhelg.ru/wp-content/uploads/2009/12/images.png" alt="" width="600" height="230" /></a>

<h3>Шаг 3 – PHP</h3>
Как вы помните, на шаге 1, мы рассмотрели часть XHTML-разметки, и отметили, что PHP будет использоваться для создания специальной разметки, для каждого изображения. И вот как это делается:

<strong>demo.php</strong>

[php]
/* Configuration Start */
$thumb_directory = 'img/thumbs';
$orig_directory = 'img/original';
$stage_width=600;
$stage_height=400;
/* Configuration end */

$allowed_types=array('jpg','jpeg','gif','png');
$file_parts=array();
$ext='';
$title='';
$i=0;

/* Opening the thumbnail directory and looping through all the thumbs: */
$dir_handle = @opendir($thumb_directory) or die(&quot;There is an error with your image directory!&quot;);
$i=1;

while ($file = readdir($dir_handle))
{
	/* Skipping the system files: */
	if($file=='.' || $file == '..') continue;

	$file_parts = explode('.',$file);
	$ext = strtolower(array_pop($file_parts));

	/* Using the file name (withouth the extension) as a image title: */
	$title = implode('.',$file_parts);
	$title = htmlspecialchars($title);

	/* If the file extension is allowed: */
	if(in_array($ext,$allowed_types))
	{
		/* Generating random values for the position and rotation: */
		$left=rand(0,$stage_width);
		$top=rand(0,400);
		$rot = rand(-40,40);

		if($top&gt;$stage_height-130 &amp;&amp; $left &gt; $stage_width-230)
		{
			/* Prevent the images from hiding the drop box */
			$top-=120+130;
			$left-=230;
		}

		/* Outputting each image: */
		echo '
		&lt;div id=&quot;pic-'.($i++).'&quot; class=&quot;pic&quot; style=&quot;top:'.$top.'px;left:'.$left.'px;background:url('.$thumb_directory.'/'.$file.') no-repeat 50% 50%; -moz-transform:rotate('.$rot.'deg); -webkit-transform:rotate('.$rot.'deg);&quot;&gt;

		&lt;a class=&quot;fancybox&quot; rel=&quot;fncbx&quot; href=&quot;'.$orig_directory.'/'.$file.'&quot; target=&quot;_blank&quot;&gt;'.$title.'&lt;/a&gt;

		&lt;/div&gt;';
	}
}

/* Closing the directory */
closedir($dir_handle);
[/php]

Сначала, мы открываем папку миниатюр с помощью <code>opendir</code> (с помощью модификатора @, мы предотвращаем появление любых возможных проблем, отображаемых пользователю) и проходим циклом по всем картинкам.

В цикле, мы пропускаем файлы, не являющиеся изображениями, и генерируем некоторый XHTML-код для каждого изображения, который выводится непосредственно на экран.

Как уже упоминалось ранее, в части CSS, PHP отвечает за вращение и разброс картинок по странице. Каждое изображение позиционируется по случайным <code>X</code> и <code>Y</code> координатам, и поворачивается в диапазоне от <code>-40</code> до <code>40</code> градусов (для предотвращения переворачивания снимков вверх ногами). Все это генерируется с помощью PHP-функции <code>rand()</code> и включается в качестве CSS-стиля картинки, с помощью атрибута <code>style</code>.

Существуют две папки с картинками, использующиеся галереей – thumbs, в которой содержатся миниатюры картинок, размером 100 х 100 пикселей, и original, которая содержит картинку реального размера. Обратите внимание на важную деталь, изображения в папке thumbnail и original, должны иметь одно и то же имя, иначе галерея будет работать не правильно.

Единственно, что осталось сделать – добавить немного интерактивности.

<h3>Шаг 4 – jQuery</h3>
Итак, у нас на руках отличная CSS-галерея. Но это ничего не значит, если мы не можем перетаскивать понравившиеся картинки по экрану и увеличивать их для более детального просмотра, не так ли?

Пришло время JQuery.

<strong>script.js</strong>

[javascript]
$(document).ready(function(){
	// Executed once all the page elements are loaded
	var preventClick=false;
	$(&quot;.pic a&quot;).bind(&quot;click&quot;,function(e){

		/* This function stops the drag from firing a click event and showing the lightbox */
		if(preventClick)
		{
			e.stopImmediatePropagation();
			e.preventDefault();
		}
	});

	$(&quot;.pic&quot;).draggable({

		/* Converting the images into draggable objects */
		containment: 'parent',
		start: function(e,ui){
			/* This will stop clicks from occuring while dragging */
			preventClick=true;
		},
		stop: function(e, ui) {
			/* Wait for 250 milliseconds before re-enabling the clicks */
			setTimeout(function(){ preventClick=false; }, 250);
		}
	});

	$('.pic').mousedown(function(e){
		/* Executed on image click */
		var maxZ = 0;

		/* Find the max z-index property: */
		$('.pic').each(function(){
			var thisZ = parseInt($(this).css('zIndex'))
			if(thisZ&gt;maxZ) maxZ=thisZ;
		});

		/* Clicks can occur in the picture container (with class pic) and in the link inside it */
		if($(e.target).hasClass(&quot;pic&quot;))
		{
			/* Show the clicked image on top of all the others: */
			$(e.target).css({zIndex:maxZ+1});
		}
		else $(e.target).closest('.pic').css({zIndex:maxZ+1});
	});

	/* Converting all the links to a fancybox gallery */
	$(&quot;a.fancybox&quot;).fancybox({
		zoomSpeedIn: 300,
		zoomSpeedOut: 300,
		overlayShow:false
	});

	/* Converting the share box into a droppable: */
	$('.drop-box').droppable({
		hoverClass: 'active',
		drop:function(event,ui){

			/* Fill the URL text field with the URL of the image. */
			/* The id of the image is appended as a hash #pic-123 */
			$('#url').val(location.href.replace(location.hash,'')+'#' + ui.draggable.attr('id'));
			$('#modal').dialog('open');
		}
	});

	/* Converts the div with id=&quot;modal&quot; into a modal window  */
	$(&quot;#modal&quot;).dialog({
		bgiframe: true,
		modal: true,
		autoOpen:false,

		buttons: {
			Ok: function() {
				$(this).dialog('close');
			}
		}
	});

	if(location.hash.indexOf('#pic-')!=-1)
	{
		/* Checks whether a hash is present in the URL */
		/* and shows the respective image */
		$(location.hash+' a.fancybox').click();
	}
});
[/javascript]

Сначала, мы вешаем, обработчик событий на клик по картинке, с тем, чтобы лайтбокс не срабатывал, когда мы просто перетаскиваем изображение.

После этого, мы делаем все картинки перетаскиваемыми, а затем настраиваем lightbox.

Теперь, нам нужно сделать блок «Drop to share», «принимающим», то есть блок сможет определять, когда к нему подвели и отпустили картинку. Это позволит нам применить специальный стиль к контейнеру, и открыть модальное окно.

Модальное окно – это компонент пользовательского интерфейса, поставляемый вместе с jQuery UI. Он прячет все элементы страницы, под полупрозрачный слой, тем самым блокируя их использование для пользователя. Единственная вещь, полностью привлекающая внимание пользователя – это окно с сообщением, которое в нашем случае, окно содержит URL картинки.

И наконец, у нас есть несколько строк кода, которые проверяют, есть ли строки вида  <code>#pic-123</code> в URL, c помощью которых, лайтбокс показывает соответствующие изображения при загрузке страницы.

Наша CSS3-галерея готова.

<a href="http://demo.tutorialzine.com/2009/11/hovering-gallery-css3-jquery/demo.zip">Скачать архив с примером</a>.

Перевод статьи «<a href="http://tutorialzine.com/2009/11/hovering-gallery-css3-jquery/">An Awesome CSS3 Lightbox Gallery With jQuery</a>», автор <strong>Martin</strong>
<h3><strong> </strong>Другие участники эстафеты:</h3>
<ul>
	<li>Cuprum.name – <a href="http://cuprum.name/page/cvetovaya-model-rgba">Работа с цветовой моделью RGBA</a></li>
	<li>rotorweb.ru — <a href="http://rotorweb.ru/mysli-vslux/saying-goodbye-overflow-hidden.html">Скажем прощай overflow: hidden!</a></li>
</ul>
Хотите принять участие в эстафете? Это очень просто, опубликуйте перевод статьи из представляемого ресурса, сообщите мне, и я с удовольствием поставлю ссылку на ваш блог. Обязательное условие – статьи и ресурсы не должны повторятся.]]></description>
		<wfw:commentRss>http://dreamhelg.ru/2009/12/fancy-lightbox-css3-image-gallery-with-jquery/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>WordPress. Простой шорткод для постоянных ссылок</title>
		<link>http://dreamhelg.ru/2009/12/wordpress-simple-shortcode-for-permalinks/</link>
		<comments>http://dreamhelg.ru/2009/12/wordpress-simple-shortcode-for-permalinks/#comments</comments>
		<pubDate>Tue, 01 Dec 2009 12:48:19 +0000</pubDate>
		<dc:creator>dreamhelg</dc:creator>
				<category><![CDATA[wordpress]]></category>
		<category><![CDATA[переводы]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[shortcode]]></category>

		<guid isPermaLink="false">http://dreamhelg.ru/?p=1728</guid>
		<description><![CDATA[<p><img width="150" height="150" src="http://dreamhelg.ru/wp-content/uploads/2009/12/permalinkthumb.png" class="attachment-200x200 wp-post-image" alt="permalinkthumb" title="permalinkthumb" /></p>Сегодня, публикую перевод небольшой статьи о создании весьма полезного шорткода, кстати если вы еще не слышали о шорткодах, можете прочитать в моей <a href="http://dreamhelg.ru/2009/07/10-отличных-шорткодов-для-wordpress/">предыдущей</a> статье.

<p>Во время создания шаблона для WordPress, у вас может возникнуть необходимость указать ссылку на конкретную страницу прямо в шаблоне. Для этого есть специальная функция, которую вы можете использовать.</p><span id="more-1728"></span>

<strong>Плохой пример:</strong>

[php]
&lt;a href=&quot;/contact/&quot;&gt;Контакты&lt;/a&gt;
[/php]

<strong>Хороший пример:</strong>

[php]
&lt;a href=&quot;&lt;?php echo get_permalink(12); ?&gt;&quot;&gt;Контакты&lt;/a&gt;
[/php]

Здесь «12» - это ID нужной записи или страницы. Почему же этот способ правильней?
<ul>
	<li>ссылка будет работать, даже если вы измените структуру ссылок;</li>
	<li>ссылка будет работать, даже если сайт будет перенесен с субдомена (который вы использовали для тестирования) на домен верхнего уровня.</li>
</ul>

Используя вышеуказанную функцию, ссылки на ваши записи и страницы никогда не изменятся. Это очень удобно использовать, при работе с файлами нашей темы, но как насчет использования ссылок на страницах и записях в визуальном редакторе?

По умолчанию, мы не можем выполнять PHP-код внутри нашей страницы или записи, а следовательно нет возможности использовать функцию <code>get_permalink</code>. Что мы можем сделать, так это создать специальный <strong>шорткод</strong>, с точно такой же функциональностью. И вот он:

[php]
function permalink_thingy($atts) {
	extract(shortcode_atts(array(
		'id' =&gt; 1,
		'text' =&gt; &quot;&quot;  // значение по умолчанию, если ничего не указано
    ), $atts));
    
    if ($text) {
        $url = get_permalink($id);
        return &quot;&lt;a href='$url'&gt;$text&lt;/a&gt;&quot;;
    } else {
	   return get_permalink($id);
	}
}
add_shortcode('permalink', 'permalink_thingy');
[/php]

Этот шорткод можно использовать двумя способами:

<strong>Просто:</strong>

[php]
&lt;a href=&quot;[permalink id=49]&quot;&gt;Использование без текста&lt;/a&gt;
[/php]

Здесь вам нужно просто указать параметр id и шорткод вернет URL. Полученный URL можно использовать любым способом, например, если вам нужно присвоить ссылке определенный класс или еще для чего-нибудь.

<strong>С текстом:</strong>

[php]
[permalink id=49 text='providing text']
[/php]

Этот способ вернет полностью форматированную ссылку, с текстом, который вы указали.

Перевод статьи «<a href="http://digwp.com/2009/09/easy-shortcode-permalinks/">Easy Shortcode Permalinks</a>», автор <strong>Chris Coyier</strong>]]></description>
		<wfw:commentRss>http://dreamhelg.ru/2009/12/wordpress-simple-shortcode-for-permalinks/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Простой, перетаскиваемый элемент на jQuery</title>
		<link>http://dreamhelg.ru/2009/11/simple-draggable-element-with-jquery/</link>
		<comments>http://dreamhelg.ru/2009/11/simple-draggable-element-with-jquery/#comments</comments>
		<pubDate>Mon, 23 Nov 2009 07:54:16 +0000</pubDate>
		<dc:creator>dreamhelg</dc:creator>
				<category><![CDATA[общая]]></category>
		<category><![CDATA[переводы]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://dreamhelg.ru/?p=1713</guid>
		<description><![CDATA[<p><img width="200" height="200" src="http://dreamhelg.ru/wp-content/uploads/2009/11/200x200.jpg" class="attachment-200x200 wp-post-image" alt="200x200" title="200x200" /></p>Бывают случаи, когда вам может понадобиться создать перетаскиваемый элемент внутри вашего веб-приложения. Это отличная функциональность, однако, возможно вы хотите, чтобы элемент оставался на новом месте, после перетаскивания.  В сегодняшней статье вы узнаете, как можно легко перетаскивать и закреплять в новом месте нужный элемент даже после перезагрузки страницы, с помощью захвата и хранения его X и Y координат.<span id="more-1713"></span>

<h3>Сценарий</h3>
Итак, у вас есть элемент на странице. Вы можете перетаскивать его туда-сюда. Но, когда страница перезагружается, элемент возвращается на исходную позицию.  И хотя нам нужно, чтобы элемент был перетаскиваемый, при этом нужно, чтобы наш элемент достаточно было перетащить один раз. Давайте рассмотрим простое решение, реализующее данную функциональность.

<h3>Начало</h3>
Для этого примера нам понадобится библиотека <a href="http://jquery.com/">jQuery</a>, <a href="http://jqueryui.com/">jQuery UI </a>и плагин JQuery-<a href="http://code.google.com/p/jquery-json/">JSON</a>. Кроме этого, мы также будем использовать PHP и базу данных MySQL для разбора и хранения наших данных. Если вы новичок в jQuery, не беспокойтесь. JQuery - это расширяемая, быстрая и легковесная JavaScript-библиотека, которую легко и весело использовать. Библиотека имеет хорошо структурированную документацию и огромное сообщество.

<a href="http://dreamhelg.ru/wp-content/uploads/2009/11/jquery.jpg"><img class="aligncenter size-full wp-image-1716" title="jquery" src="http://dreamhelg.ru/wp-content/uploads/2009/11/jquery.jpg" alt="jquery" width="500" height="200" /></a>

<h3>HTML и CSS</h3>
Начнем с HTML-разметки и стилей для нашего примера. Сначала CSS:

[css]
html, body {   
    background:#151515;   
    margin:0 0 0 0;   
    padding:0 0 0 0;   
}   
  
#glassbox {   
    background:#333;   
    border:1px solid #000;   
    height:400px;   
    margin:30px auto auto auto;   
    position:relative;   
    width:960px;   
    -moz-border-radius: 10px;   
    -webkit-border-radius: 10px;       
}   
  
#element {   
    background:#666;   
    border:1px #000 solid;   
    cursor:move;   
    height:143px;   
    padding:10px 10px 10px 10px;   
    width:202px;   
    -moz-border-radius: 10px;   
    -webkit-border-radius: 10px;   
}   
  
#respond{   
    color:#fff;   
    margin:0 auto 0 auto;   
    width:960px;       
}  
[/css]

CSS – очень простой. Мы назначаем html и body нулевые свойства, для чистки внешних и внутренних отступов, далее устанавливаем значения высоты, ширины и другие свойства для наших элементов. -<code>moz-border-radius</code> и <code>-webkit-border-radius</code> – это два свойства, позволяющие нам создать закругленные углы (работает пока только в Mozilla Firefox и Safari 3) для наших элементов. Теперь, давайте взглянем на HTML:

[html]
&lt;!DOCTYPE html&gt;   
&lt;html&gt;   
&lt;head&gt;   
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot; /&gt;   
&lt;title&gt;Simple Draggable Element Persistence with jQuery&lt;/title&gt;   
  
&lt;link rel=&quot;stylesheet&quot; href=&quot;style.css&quot; type=&quot;text/css&quot; /&gt;   
&lt;script type=&quot;text/javascript&quot; src=&quot;js/jquery-1.3.2.min.js&quot;&gt;&lt;/script&gt;   
&lt;script type=&quot;text/javascript&quot; src=&quot;js/jquery-ui-1.7.2.custom.min.js&quot;&gt;&lt;/script&gt;   
&lt;script type=&quot;text/javascript&quot; src=&quot;js/jquery.json-2.2.min.js&quot;&gt;&lt;/script&gt;   
  
&lt;/head&gt;   
  
&lt;body&gt;   
  
    &lt;div id=&quot;glassbox&quot;&gt;   
        &lt;div id=&quot;element&quot;&gt;&lt;img src=&quot;nettuts.jpg&quot; alt=&quot;Nettuts+&quot; /&gt;Move the Box&lt;p&gt;&lt;/p&gt;&lt;/div&gt;   
    &lt;/div&gt;   
  
    &lt;div id=&quot;respond&quot;&gt;&lt;/div&gt;   
[/html]

Как видите, мы создали очень простую страницу, в которую подключили наш CSS, библиотеку JavaScript и плагины, кроме того, страница содержит элементы, к которым мы будем применять некоторые эффекты и события. Обратите внимание, что файл jquery-ui представляет собой специальную сборку, включающую в себя только ядро и функции перетаскивания элементов.

<a href="http://dreamhelg.ru/wp-content/uploads/2009/11/general.jpg"><img class="aligncenter size-full wp-image-1717" title="general" src="http://dreamhelg.ru/wp-content/uploads/2009/11/general.jpg" alt="general" width="584" height="452" /></a>

<h3>JavaScript</h3>
Теперь самое интересное! Сначала давайте рассмотрим базовые функции, которые мы будем использовать для применения некоторых эффектов к нашим элементам. Разберем все до основания.

[javascript]
&lt;script type=&quot;text/javascript&quot;&gt;   
    $(document).ready(function() {   
        $(&quot;#element&quot;).draggable({    
                containment: '#glassbox',    
                scroll: false   
         })   
[/javascript]

Сначала мы говорим браузеру: «Эй, это код, который мы хотим запустить; это не HTML, это JavaScript». Затем, мы ждем пока документ полностью загрузится, после того как это случилось, вызываем функцию для получения нашего блока <code>#element</code>, и добавляем к нему обработчик перетаскивания с базовыми настройками. Опция <code>containment</code> содержит наш элемент внутри родительского блока, и мы устанавливаем значение <code>scroll</code> в <code>false</code>, потому что, нам не нужен скролл.

Двигаемся дальше:

[javascript]
.mousemove(function(){   
    var coord = $(this).position();   
    $(&quot;p:last&quot;).text( &quot;left: &quot; + coord.left + &quot;, top: &quot; + coord.top );   
})   
[/javascript]

Внутри этого фрагмента, мы вызываем, обработчик события mousemove и говорим ему: «Когда мышь передвигается, установить переменную <code>coord</code> равной значению текущей позиции нашего блока #element» Затем мы получаем последний параграф в блоке <code>#(“p: last”) </code>и печатаем текст, выводящий значения свойств <code>left(x) </code>и <code>top(y)</code> нашего элемента, относительно родительского объекта (которым является блок <code>#glassbox</code>).

[javascript]
.mouseup(function(){    
            var coords=[];   
            var coord = $(this).position();   
            var item={ coordTop:  coord.left, coordLeft: coord.top  };   
            coords.push(item);   
            var order = { coords: coords };   
            $.post('updatecoords.php', 'data='+$.toJSON(order), function(response){   
                    if(response==&quot;success&quot;)   
                        $(&quot;#respond&quot;).html('&lt;div class=&quot;success&quot;&gt;X and Y Coordinates Saved!&lt;/div&gt;').hide().fadeIn(1000);   
                        setTimeout(function(){ $('#respond').fadeOut(1000); }, 2000);   
                    });    
            });   
                       
});   
lt;/script&gt;   
[/javascript]

Ну да, здесь уже сложнее. В этом фрагменте мы собираемся сделать кучу вещей. Сначала, мы устанавливаем пустой массив, а затем получаем некоторые значения для его наполнения. С помощью вызова обработчика событий <code>.mouseup()</code> мы велим браузеру отслеживать событие, когда вы отпускаете кнопку мыши. Мы указываем, что переменная <code>coords</code> – это пустой массив и снова устанавливаем ее значение равной позиции нашего блока <code>#element</code>.

Затем, нам нужно создать список из двух строчек, которыми будут <code>coordTop:</code> и <code>coordLeft:</code>, соответствующие позициям <code>left</code> и <code>top</code>, нашего блока. С помощью строки <code>coords.push(item)</code>, мы заполним наш список массивом из координат. Затем задаем переменную <code>order</code> как новый список, в котором ключ <code>coords</code> будет соответствовать нашему массиву <code>coords</code>. Теперь немного аякса.

<a href="http://dreamhelg.ru/wp-content/uploads/2009/11/dragged.jpg"><img class="aligncenter size-full wp-image-1718" title="dragged" src="http://dreamhelg.ru/wp-content/uploads/2009/11/dragged.jpg" alt="dragged" width="528" height="458" /></a>

<code>$.post</code> – это обработчик запроса AJAX, который загружает удаленную страницу, с помощью метода <code>HTTP POST</code>. Эта функция принимает следующие параметры: url, дата, ответ и тип данных для возврата. В этом примере, мы укажем файле updatecoords.php в качестве нашего URL, потому что, именно этому файлы мы хотим отправить наши данные. Затем, мы опишем тип данных, с помощью включения функции <code>$.toJSON</code>, определенной в плагине JSON и назначим переменную <code>order</code>, в качестве данных, которые должен вернуть <code>.toJSON</code>.

Далее, мы создаем ответ, который проверяет возвращение успешного ответа от нашего PHP-файла. В случае получения успешного ответа, мы отображаем сообщение об успешном сохранении координат, используя метод <code>.fadeIn()</code> и скорость 1000 миллисекунд, затем задаем таймер на 2000 миллисекунд, и снова медленно прячем это сообщение, с помощью метода <code>.fadeOut()</code>. Вот так будет выглядеть наш JavaScript в целом виде:

[javascript]
&lt;script type=&quot;text/javascript&quot;&gt;   
    $(document).ready(function() {   
        $(&quot;#element&quot;).draggable({    
                containment: '#glassbox',    
                scroll: false   
         }).mousemove(function(){   
                var coord = $(this).position();   
                $(&quot;p:last&quot;).text( &quot;left: &quot; + coord.left + &quot;, top: &quot; + coord.top );   
         }).mouseup(function(){    
                var coords=[];   
                var coord = $(this).position();   
                var item={ coordTop:  coord.left, coordLeft: coord.top  };   
                coords.push(item);   
                var order = { coords: coords };   
                $.post('updatecoords.php', 'data='+$.toJSON(order), function(response){   
                        if(response==&quot;success&quot;)   
                            $(&quot;#respond&quot;).html('&lt;div class=&quot;success&quot;&gt;X and Y Coordinates Saved!&lt;/div&gt;').hide().fadeIn(1000);   
                            setTimeout(function(){ $('#respond').fadeOut(1000); }, 2000);   
                        });    
                });   
                           
        });   
&lt;/script&gt;   
[/javascript]

Поместите этот код ниже HTML, сразу после закрывающего тега body.
<h3>PHP</h3>
Хорошо, давайте сделаем что-нибудь с данными, которые приходят от нашего JQuery. Сначала нужно создать простую базу данных, для хранения наших координат, которые мы впоследствии будем использовать для определения позиции нашего элемента. Затем, нам понадобится файл config.php, в котором будут записаны параметры подключения к базе данных, а затем мы перейдем к updatecords.php.

<strong>SQL</strong>

[sql]
Database: 'xycoords'   
  
CREATE TABLE IF NOT EXISTS `coords` (   
  `id` int(11) NOT NULL AUTO_INCREMENT,   
  `x_pos` int(4) NOT NULL,   
  `y_pos` int(4) NOT NULL,   
  PRIMARY KEY (`id`)   
) ENGINE=MyISAM  DEFAULT CHARSET=latin1; 
[/sql]

<strong>Config.php</strong>

[php]
&lt;?php   
/*Database Settings*/   
  
$db_host =&quot;localhost&quot;; //this will likely stay the same   
$db_name = &quot;xycoords&quot;; //name of the database we will be using   
$db_usr = &quot;database_username&quot;; //db username   
$db_pass = &quot;database_password&quot;; //db password   
  
//Connect to the database   
$link = mysqli_connect($db_host, $db_usr, $db_pass) or die(&quot;MySQL Error: &quot; . mysqli_error());   
//Select our database   
mysqli_select_db($link, $db_name) or die(&quot;MySQL Error: &quot; . mysqli_error());   
?&gt;   
[/php]

<strong>updatecoords.php</strong>

[php]
&lt;?php   
if(!$_POST[&quot;data&quot;]){   
    echo &quot;Nothing Sent&quot;;   
    exit;   
}   
  
include ('config.php');   
  
//decode JSON data received from AJAX POST request   
$data = json_decode($_POST[&quot;data&quot;]);   
  
foreach($data-&gt;coords as $item) {   
    //Extract X number for panel   
    $coord_X = preg_replace('/[^\d\s]/', '', $item-&gt;coordTop);   
    //Extract Y number for panel   
    $coord_Y = preg_replace('/[^\d\s]/', '', $item-&gt;coordLeft);   
    //escape our values - as good practice   
    $x_coord = mysqli_real_escape_string($link, $coord_X);   
    $y_coord = mysqli_real_escape_string($link, $coord_Y);   
       
    //Setup our Query   
    $sql = &quot;UPDATE coords SET x_pos = '$x_coord', y_pos = '$y_coord'&quot;;   
       
    //Execute our Query   
    mysqli_query($link, $sql) or die(&quot;Error updating Coords :&quot;.mysqli_error());    
}   
  
//Return Success   
echo &quot;success&quot;;   
  
?&gt;
[/php]

Здесь все довольно просто. Первое, что мы делаем – это проверяем, были ли переданы данные в файл. Если это произошло, мы включаем наш файл с настройками config.php и назначаем переменной <code>$data</code> значение <code>json_decode(passed post variable);</code> <a href="http://us.php.net/manual/en/function.json-decode.php">json_decode</a> – это PHP-функция, представленная в PHP 5.2.0, которая позволяет декодировать строку JSON.

Поскольку наша переменная <code>$data</code> содержит массив данных, нам нужно разобрать его на части, чтобы получить нужные значения. Для этого мы пройдемся по массиву <code>$data-&gt;coords () </code>(который был получен из переменной <code>order</code> в JavaScript) и обработаем каждый элемент. В результате, из каждой пары ключ – значение будет создан объект списка, который мы в дальнейшем укажем и создадим переменную для его вывода. При этом мы будем использовать функцию <code>preg_replace</code>, для исключения ненужных символов. Кроме того, мы подготовим наши значения для вставки в базу данных, путем экранирования кавычек, и апострофов, с помощью функции <code>mysqli_real_escape_string</code>. Если все прошло хорошо, нам нужно будет вернуть успешный результат JavaScript.

<a href="http://dreamhelg.ru/wp-content/uploads/2009/11/response.jpg"><img class="aligncenter size-full wp-image-1719" title="response" src="http://dreamhelg.ru/wp-content/uploads/2009/11/response.jpg" alt="response" width="558" height="466" /></a>
<h3>В заключение</h3>
Теперь, когда у нас уже все готово, для того чтобы получить координаты элемента и передать их в PHP для записи, нам понадобится изменить нашу HTML-разметку для отображения позиции элемента. Для этого, мы удалим простую HTML-разметку и создадим ее с помощью PHP:

[php]
&lt;div id=&quot;glassbox&quot;&gt;   
&lt;?php   
        //Create a query to fetch our values from the database     
        $get_coords = mysqli_query($link, &quot;SELECT * FROM coords&quot;);   
        //We then set variables from the * array that is fetched from the database   
        while($row = mysqli_fetch_array($get_coords)) {   
            $x = $row['x_pos'];   
            $y = $row['y_pos'];   
            //then echo our div element with CSS properties to set the left(x) and top(y) values of the element   
            echo '&lt;div id=&quot;element&quot; style=&quot;left:'.$x.'px; top:'.$y.'px;&quot;&gt;&lt;img src=&quot;nettuts.jpg&quot; alt=&quot;Nettuts+&quot; /&gt;Move the Box&lt;p&gt;&lt;/p&gt;&lt;/div&gt;';   
        }              
?&gt;   
&lt;/div&gt;   
&lt;div id=&quot;respond&quot;&gt;&lt;/div&gt;   
[/php]

Здесь мы исполняем простой запрос к базе данных для выбора всех строк из таблицы coords. Затем мы вызываем цикл while, который определяет каждую выбранную нами строчку как <code>$row</code>. Теперь, мы можем назначить переменные равными каждой, индивидуальной строке, полученной из базы данных, и выводим их в соответствующем месте.

<a href="http://nettuts.s3.amazonaws.com/477_drag/source.zip">Скачать архив с примером</a>.

Перевод статьи «<a href="http://net.tutsplus.com/tutorials/javascript-ajax/simple-draggable-element-persistence-with-jquery/">Simple Draggable Element Persistence with jQuery</a>», автор <strong>Dustin Blake</strong>]]></description>
		<wfw:commentRss>http://dreamhelg.ru/2009/11/simple-draggable-element-with-jquery/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Красивая форма обратной связи на основе AJAX</title>
		<link>http://dreamhelg.ru/2009/11/fancy-ajax-contact-form/</link>
		<comments>http://dreamhelg.ru/2009/11/fancy-ajax-contact-form/#comments</comments>
		<pubDate>Fri, 13 Nov 2009 08:56:14 +0000</pubDate>
		<dc:creator>dreamhelg</dc:creator>
				<category><![CDATA[общая]]></category>
		<category><![CDATA[переводы]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://dreamhelg.ru/?p=1690</guid>
		<description><![CDATA[<p><img width="200" height="150" src="http://dreamhelg.ru/wp-content/uploads/2009/11/home.jpg" class="attachment-200x200 wp-post-image" alt="home" title="home" /></p>Предоставление посетителям сайта простого и надежного средства обратной связи –  это важнейшая часть любого веб-проекта. Наиболее простым и часто используемым каналом обратной связи - являются контактные формы. Посмотреть результат можно <a href="http://dreamhelg.ru/demo/contactform/demo.php">здесь</a>.<span id="more-1690"></span>

В сегодняшней статье, мы создадим <strong>форму обратной связи  на аяксе</strong>, с использованием современных техник веб-разработки.  Для этого мы будем использовать PHP, CSS и jQuery в виде нескольких плагинов. Плагин <a href="http://www.position-absolute.com/articles/jquery-form-validator-because-form-validation-is-a-mess/">formValidator</a> будем использовать для проверки введенных значений, а с помощью плагина <a href="http://www.dfc-e.com/metiers/multimedia/opensource/jqtransform/">jQTransform</a>, будем стилизовать текстовые поля и кнопки нашей формы. В дополнение, мы будем использовать класс <a href="http://sourceforge.net/projects/phpmailer/">PHPMailer</a> для отправки на почту введенных данных.

Кроме того, наша форма будет прекрасно работать даже с выключенным JS.

<em>*Для нормальной работы примера, вам понадобится <strong>PHP5</strong></em>
<h3>Шаг 1 – XHTML</h3>
Сначала нам понадобится XHTML-разметка для формы.

<strong>demo.php</strong>

[html]
&lt;div id=&quot;main-container&quot;&gt;	&lt;!-- The main container element --&gt;

&lt;div id=&quot;form-container&quot;&gt;	&lt;!-- The form container --&gt;

&lt;h1&gt;Fancy Contact Form&lt;/h1&gt;	&lt;!-- Headings --&gt;
&lt;h2&gt;Drop us a line and we will get back to you&lt;/h2&gt;

&lt;form id=&quot;contact-form&quot; name=&quot;contact-form&quot; method=&quot;post&quot; action=&quot;submit.php&quot;&gt;	&lt;!-- The form, sent to submit.php --&gt;

&lt;table width=&quot;100%&quot; border=&quot;0&quot; cellspacing=&quot;0&quot; cellpadding=&quot;5&quot;&gt;

&lt;tr&gt;
&lt;td width=&quot;18%&quot;&gt;&lt;label for=&quot;name&quot;&gt;Name&lt;/label&gt;&lt;/td&gt;	&lt;!-- Text label for the input field --&gt;
&lt;td width=&quot;45%&quot;&gt;&lt;input type=&quot;text&quot; class=&quot;validate[required,custom[onlyLetter]]&quot; name=&quot;name&quot; id=&quot;name&quot; value=&quot;&lt;?=$_SESSION['post']['name']?&gt;&quot; /&gt;&lt;/td&gt;
&lt;!-- We are using session to prevent losing data between page redirects --&gt;

&lt;td width=&quot;37%&quot; id=&quot;errOffset&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;label for=&quot;email&quot;&gt;Email&lt;/label&gt;&lt;/td&gt;
&lt;td&gt;&lt;input type=&quot;text&quot; class=&quot;validate[required,custom[email]]&quot; name=&quot;email&quot; id=&quot;email&quot; value=&quot;&lt;?=$_SESSION['post']['email']?&gt;&quot; /&gt;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;label for=&quot;subject&quot;&gt;Subject&lt;/label&gt;&lt;/td&gt;

&lt;!-- This select is being replaced entirely by the jqtransorm plugin --&gt;

&lt;td&gt;&lt;select name=&quot;subject&quot; id=&quot;subject&quot;&gt;
&lt;option value=&quot;&quot; selected=&quot;selected&quot;&gt; - Choose -&lt;/option&gt;
&lt;option value=&quot;Question&quot;&gt;Question&lt;/option&gt;
&lt;option value=&quot;Business proposal&quot;&gt;Business proposal&lt;/option&gt;
&lt;option value=&quot;Advertisement&quot;&gt;Advertising&lt;/option&gt;
&lt;option value=&quot;Complaint&quot;&gt;Complaint&lt;/option&gt;
&lt;/select&gt;          &lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td valign=&quot;top&quot;&gt;&lt;label for=&quot;message&quot;&gt;Message&lt;/label&gt;&lt;/td&gt;
&lt;td&gt;&lt;textarea name=&quot;message&quot; id=&quot;message&quot; class=&quot;validate[required]&quot; cols=&quot;35&quot; rows=&quot;5&quot;&gt;&lt;?=$_SESSION['post']['message']?&gt;&lt;/textarea&gt;&lt;/td&gt;
&lt;td valign=&quot;top&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;label for=&quot;captcha&quot;&gt;&lt;?=$_SESSION['n1']?&gt; + &lt;?=$_SESSION['n2']?&gt; =&lt;/label&gt;&lt;/td&gt;

&lt;!-- A simple captcha math problem --&gt;

&lt;td&gt;&lt;input type=&quot;text&quot; class=&quot;validate[required,custom[onlyNumber]]&quot; name=&quot;captcha&quot; id=&quot;captcha&quot; /&gt;&lt;/td&gt;
&lt;td valign=&quot;top&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td valign=&quot;top&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;!-- These input buttons are being replaced with button elements --&gt;
&lt;td colspan=&quot;2&quot;&gt;&lt;input type=&quot;submit&quot; name=&quot;button&quot; id=&quot;button&quot; value=&quot;Submit&quot; /&gt;
&lt;input type=&quot;reset&quot; name=&quot;button2&quot; id=&quot;button2&quot; value=&quot;Reset&quot; /&gt;
&lt;?=$str?&gt;

&lt;!-- $str contains the error string if the form is used with JS disabled --&gt;

&lt;img id=&quot;loading&quot; src=&quot;img/ajax-load.gif&quot; width=&quot;16&quot; height=&quot;16&quot; alt=&quot;loading&quot; /&gt;
&lt;!-- the rotating gif animation, hidden by default --&gt;
&lt;/td&gt;&lt;/tr&gt;

&lt;/table&gt;
&lt;/form&gt;

&lt;?=$success?&gt;
&lt;!-- The $success variable contains the message that is shown if JS is disabled and the form is submitted successfully --&gt;

&lt;/div&gt;
&lt;/div&gt;	&lt;!-- closing the containers --&gt;
[/html]

Как вы могли заметить в строке 8, обрабатывать нашу форму будет файл <strong>submit.php</strong>. Мы будем использовать этот файл в обоих случаях – как для обычной отправки формы (для посетителей с выключенным JS), так и для аяксовой отправки формы. Это позволит легко обновлять код, без необходимости объединять изменения между файлами.

Далее, мы можете видеть, что мы используем массив <strong>$_SESSION</strong> для заполнения текстовых полей значениями. Это делается для того, чтобы данные не потерялись во время перенаправления страницы, которое происходит во время отправки формы в <strong>submit.php</strong>.

Другой важный аспект – это классы, назначенный текстовым полям – <strong>classs=”validate[required,custom[onlyLetter]]”</strong>. Эти классы используются плагином валидации для определения правил проверки введенных значений для каждого текстового поля. В нашем примере, мы указываем, что поле обязательное, и разрешено вводить только буквы.

Существует множество доступных правил валидации, вы можете узнать о них на домашней странице плагина.

Теперь взгляните, как будет выглядеть наша форма, с применением плагина <strong>JQtransform</strong>.

<a href="http://dreamhelg.ru/wp-content/uploads/2009/11/1.jpg"><img class="aligncenter size-full wp-image-1694" title="1" src="http://dreamhelg.ru/wp-content/uploads/2009/11/1.jpg" alt="1" width="433" height="468" /></a>
<h3>Шаг 2 – jQuery</h3>
МЫ используем два плагина jQuery – <strong>jQtransform</strong> для стилизации элементов формы, и <strong>formValidator</strong> для проверки введенных значений на клиентской стороне.

Очень важно помнить, что кроме клиентской стороны, введенные данные всегда нужно проверять на серверной стороне.

Итак, для начала нам нужно подключить все необходимые библиотеки.

<strong>demo.php</strong>

[php]
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;jqtransformplugin/jqtransform.css&quot; /&gt;
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;formValidator/validationEngine.jquery.css&quot; /&gt;
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;demo.css&quot; /&gt;

&lt;?=$css?&gt; &lt;!-- Special CSS rules, created by PHP --&gt;

&lt;script type=&quot;text/javascript&quot; src=&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;jqtransformplugin/jquery.jqtransform.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;formValidator/jquery.validationEngine.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;script.js&quot;&gt;&lt;/script&gt;
[/php]

Указанный выше код расположен в секции <em>head</em>, файла <strong>demo.php</strong>. Сначала мы подключаем CSS-файлы, используемые обоими плагинами, а затем уже библиотеку JQuery и плагины. Возможно, вас заинтересовала строка 5 – это специальный набор CSS-правил, который мы создадим с помощью PHP, для отображения подтверждающего сообщения, как вы увидите в дальнейшем.

Теперь, давайте посмотрим на наш файл <strong>script.js</strong>.

<strong>script.js</strong>

[javascript]
$(document).ready(function(){
	/* after the page has finished loading */

	$('#contact-form').jqTransform();
	/* transform the form using the jqtransform plugin */

	$(&quot;button&quot;).click(function(){

		$(&quot;.formError&quot;).hide();
		/* hide all the error tooltips */
	});

	var use_ajax=true;
	$.validationEngine.settings={};
	/* initialize the settings object for the formValidation plugin */

	$(&quot;#contact-form&quot;).validationEngine({	/* create the form validation */
		inlineValidation: false,
		promptPosition: &quot;centerRight&quot;,
		success :  function(){use_ajax=true},	/* if everything is OK enable AJAX */
		failure : function(){use_ajax=false}	/* in case of validation failure disable AJAX */
	 })

	$(&quot;#contact-form&quot;).submit(function(e){

			if(!$('#subject').val().length)
			{
				$.validationEngine.buildPrompt(&quot;.jqTransformSelectWrapper&quot;,&quot;* This field is required&quot;,&quot;error&quot;)
				/* a custom validation tooltip, using the buildPrompt method */

				return false;
			}

			if(use_ajax)
			{
				$('#loading').css('visibility','visible');
				/* show the rotating gif */

				$.post('submit.php',$(this).serialize()+'&amp;ajax=1',
				/* using jQuery's post method to send data */

				function(data){
					if(parseInt(data)==-1)
						$.validationEngine.buildPrompt(&quot;#captcha&quot;,&quot;* Wrong verification number!&quot;,&quot;error&quot;);
						/* if there is an error, build a custom error tooltip for the captcha */
					else
					{
						$(&quot;#contact-form&quot;).hide('slow').after('&lt;h1&gt;Thank you!&lt;/h1&gt;');
						/* show the confirmation message */
					}

					$('#loading').css('visibility','hidden');
					/* hide the rotating gif */
				});
			}

e.preventDefault();	/* stop the default form submit */
})

});
[/javascript]

Весь блок скрипта выполняется внутри метода <strong>$(document).ready</strong>, который гарантирует нам, свое исполнение, только после окончания загрузки страницы.

Далее, мы используем метод <strong>jqTransform()</strong>, который определен в плагине <strong>jqtransform</strong>. Он переделывает и стилизует все элементы формы (тестовые поля, кнопки и др.)

Элемент <em>select</em> заменяется набором дивов и ссылок. Это выглядит здорово, однако влечет за собой некоторые проблемы с плагином валидации, в связи с чем, тултип для селекта нам придется сделать вручную.

После этого, в строке 7, вешаем обработчик событий на нажатие кнопки в нижней части формы, с одной строкой кода, которая прячет отображаемые тултипы с сообщениями об ошибках. Это для того, чтобы страница правильно обновлялась, и подсказки не оставались на странице, если пользователь ввел правильные данные.

Далее, мы инициализируем  плагин <strong>formValidation</strong>, с помощью метода <strong>validationEngine() </strong>и в строке 24 описываем событие формы <strong>onsubmit</strong>. Пара моментов, на которые стоит обратить внимание здесь – отдельный тултип в строке 28, и дополнительный параметр <strong>ajax=1</strong>, в строке 39. Этот параметр использует файл <strong>submit.php</strong>, для того чтобы определить, передан ли запрос с помощью аякса или получен непосредственно через отправку формы.

Также, обратите внимание, что мы используем специальную переменную <strong>use_ajax</strong>, для предотвращения работы аякса, если форма не прошла проверку.

<a href="http://dreamhelg.ru/wp-content/uploads/2009/11/2.png"><img class="aligncenter size-full wp-image-1695" title="2" src="http://dreamhelg.ru/wp-content/uploads/2009/11/2.png" alt="2" width="600" height="460" /></a>
<h3>Шаг 3 – CSS</h3>
Все наши CSS-правила описаны в файле <strong>demo.css</strong>

<strong>demo.css</strong>

[css]
body,h1,h2,h3,p,quote,small,form,input,ul,li,ol,label{
	/* reset some of the page elements */
	margin:0px;
	padding:0px;
}

body{
	color:#555555;
	font-size:13px;
	background: url(img/dark_wood_texture.jpg) #282828;
	font-family:Arial, Helvetica, sans-serif;
}

.clear{
	clear:both;
}

#main-container{
	width:400px;
	margin:30px auto;
}

#form-container{
	background-color:#f5f5f5;
	padding:15px;

	/* rounded corners */
	-moz-border-radius:12px;
	-khtml-border-radius: 12px;
	-webkit-border-radius: 12px;
	border-radius:12px;
}

td{
	/* prevent multiline text */
	white-space:nowrap;
}

a, a:visited {
	color:#00BBFF;
	text-decoration:none;
	outline:none;
}

a:hover{
	text-decoration:underline;
}

h1{
	color:#777777;
	font-size:22px;
	font-weight:normal;
	text-transform:uppercase;
	margin-bottom:5px;
}

h2{
	font-weight:normal;
	font-size:10px;

	text-transform:uppercase;

	color:#aaaaaa;
	margin-bottom:15px;

	border-bottom:1px solid #eeeeee;
	margin-bottom:15px;
	padding-bottom:10px;
}

label{
	text-transform:uppercase;
	font-size:10px;
	font-family:Tahoma,Arial,Sans-serif;
}

textarea{
	color:#404040;
	font-family:Arial,Helvetica,sans-serif;
	font-size:12px;
}

td &gt; button{
	/* A special CSS selector that targets non-IE6 browsers */
	text-indent:8px;
}

.error{
	/* this class is used if JS is disabled */
	background-color:#AB0000;
	color:white;
	font-size:10px;
	font-weight:bold;
	margin-top:10px;
	padding:10px;
	text-transform:uppercase;
	width:300px;
}

#loading{
	/* the loading gif is hidden on page load */
	position:relative;
	bottom:9px;
	visibility:hidden;
}

.tutorial-info{
	color:white;
	text-align:center;
	padding:10px;
	margin-top:10px;
}
[/css]

Обратите внимание на строку 85. Это правило делает кнопки шире, но, к сожалению это плохо выглядит в IE6. Поэтому мы используем специальный CSS-селектор, который игнорируется IE6, но отлично понимают остальные браузеры.

Теперь, все что нам осталось – это PHP.

<a href="http://dreamhelg.ru/wp-content/uploads/2009/11/3.jpg"><img class="aligncenter size-full wp-image-1696" title="3" src="http://dreamhelg.ru/wp-content/uploads/2009/11/3.jpg" alt="3" width="555" height="319" /></a>
<h3>Шаг 4 – PHP</h3>
Сначала давайте рассмотрим код в начале файла <strong>demo.php</strong>

<strong>demo.php</strong>

[php]
session_name(&quot;fancyform&quot;);
session_start();

$_SESSION['n1'] = rand(1,20);	/* generate the first number */
$_SESSION['n2'] = rand(1,20);	/* then the second */
$_SESSION['expect'] = $_SESSION['n1']+$_SESSION['n2'];	/* the expected result */

/* the code below is used if JS has been disabled by the user */
$str='';
if($_SESSION['errStr'])	/* if submit.php returns an error string in the session array */
{
	$str='&lt;div class=&quot;error&quot;&gt;'.$_SESSION['errStr'].'&lt;/div&gt;';
	unset($_SESSION['errStr']);	/* will be shown only once */
}

$success='';
if($_SESSION['sent'])
{
	$success='&lt;h1&gt;Thank you!&lt;/h1&gt;';	/* the success message */

	$css='&lt;style type=&quot;text/css&quot;&gt;#contact-form{display:none;}&lt;/style&gt;';
	/* a special CSS rule that hides our form */

	unset($_SESSION['sent']);
}
[/php]

Как видите, мы используем массив <strong>$_SESSION</strong> для хранения двух случайных чисел и ожидаемого результата. Это будет использоваться в дальнейшем, файлом <strong>submit.php</strong>, для подтверждения того, что капча решена.

Другой интересный момент находится в строке 21, где мы описываем простой CSS-класс. Фактически здесь, мы скрываем форму, и отображаем сообщение об успешной отправке, если у пользователя отключен JS.

<strong>submit.php</strong>

[php]
require &quot;phpmailer/class.phpmailer.php&quot;;

session_name(&quot;fancyform&quot;);	/* starting the session */
session_start();

foreach($_POST as $k=&gt;$v)
{
	/* if magic_quotes is enabled, strip the post array */
	if(ini_get('magic_quotes_gpc'))
	$_POST[$k]=stripslashes($_POST[$k]);

	$_POST[$k]=htmlspecialchars(strip_tags($_POST[$k]));
	/* escape the special chars */
}

$err = array();

/* some error checks */
if(!checkLen('name'))
	$err[]='The name field is too short or empty!';

if(!checkLen('email'))
	$err[]='The email field is too short or empty!';
else if(!checkEmail($_POST['email']))
	$err[]='Your email is not valid!';

if(!checkLen('subject'))
	$err[]='You have not selected a subject!';

if(!checkLen('message'))
	$err[]='The message field is too short or empty!';

/* compare the received captcha code to the one in the session array */
if((int)$_POST['captcha'] != $_SESSION['expect'])
	$err[]='The captcha code is wrong!';

/* if there are errors */
if(count($err))
{
	/* if the form was submitted via AJAX */
	if($_POST['ajax'])
	{
		echo '-1';
	}

	/* else fill the SESSION array and redirect back to the form */
	else if($_SERVER['HTTP_REFERER'])
	{
		$_SESSION['errStr'] = implode('&lt;br /&gt;',$err);
		$_SESSION['post']=$_POST;

		header('Location: '.$_SERVER['HTTP_REFERER']);
	}

	exit;
}

/* the email body */
$msg=
'Name:	'.$_POST['name'].'&lt;br /&gt;
Email:	'.$_POST['email'].'&lt;br /&gt;
IP:	'.$_SERVER['REMOTE_ADDR'].'&lt;br /&gt;&lt;br /&gt;

Message:&lt;br /&gt;&lt;br /&gt;

'.nl2br($_POST['message']).'

';

$mail = new PHPMailer();	/* using PHPMailer */
$mail-&gt;IsMail();

$mail-&gt;AddReplyTo($_POST['email'], $_POST['name']);
$mail-&gt;AddAddress($emailAddress);
$mail-&gt;SetFrom($_POST['email'], $_POST['name']);
$mail-&gt;Subject = &quot;A new &quot;.mb_strtolower($_POST['subject']).&quot; from &quot;.$_POST['name'].&quot; | contact form feedback&quot;;

$mail-&gt;MsgHTML($msg);

$mail-&gt;Send();

unset($_SESSION['post']);	/* unsetting */

/* the form was successfully sent */
if($_POST['ajax'])
{
	echo '1';
}
else
{
	$_SESSION['sent']=1;

	if($_SERVER['HTTP_REFERER'])
		header('Location: '.$_SERVER['HTTP_REFERER']);

	exit;
}

/* some helpful functions */
function checkLen($str,$len=2)
{
	return isset($_POST[$str]) &amp;&amp; mb_strlen(strip_tags($_POST[$str]),&quot;utf-8&quot;) &gt; $len;
}

function checkEmail($str)
{
	return preg_match(&quot;/^[\.A-z0-9_\-\+]+[@][A-z0-9_\-]+([.][A-z0-9_\-]+)+[A-z]{1,4}$/&quot;, $str);
}
[/php]

Обратите внимание как мы проверяем переменную <strong>$_POST[‘ajax’]</strong> на предмет установки и правильной работы. Как вы наверное помните, мы устанавливаем ее ранее, в файле <strong>script.js</strong>, для определения используется ли аякс для извлечения данных.

Две переменные массива <strong>$_SESSION</strong> <strong>errStr</strong> и <strong>post</strong> используются для совместного использования данных между формой и файлом <strong>submit.php</strong>, в случае выключенного JS. Здесь переменная <strong>post</strong> содержит отправленный нами массив <strong>$_POST</strong> и используется для заполнения полей формы, после того как пользователь перенаправляется обратно.

На этом работа над нашей формой обратной связи подошла к концу.

Пример рабочий, за исключением одного маленького недоразумения. Плагин formValidation, создан с целью проводить валидацию только английских символов, так что если вы попытаетесь написать имя по-русски, он выдаст ошибку о том, что нужно вводить только буквы. К счастью это решается путем замены регулярного выражения в файле <strong>jquery.validationEngine.js</strong>. Найдите строчки:

[javascript]
&quot;onlyLetter&quot;:{
	&quot;regex&quot;:&quot;/^[a-zA-Z\ \']+$/&quot;,
}	
[/javascript]

и замените на следующую:

[javascript]
&quot;onlyLetter&quot;:{
	&quot;regex&quot;:&quot;/^[a-zA-Zа-яА-Я' ]+$/&quot;,
}	
[/javascript]

После этого, скрипт перестанет игнорировать русские символы.

<a href="http://dreamhelg.ru/wp-content/uploads/2009/11/contactform.zip">Скачать архив с примером</a>.

<strong>В связи с бесконечными вопросами, специально, отдельно сообщаю: настройка адреса email на который производится отправка писем, находится в файле submit.php, в самом начале файла, выглядит вот так:
</strong>
[php]
/* config start */

$emailAddress = '';

/* config end */
[/php]

Перевод статьи "<a href="http://tutorialzine.com/2009/09/fancy-contact-form/">A Fancy AJAX Contact Form</a>", автор <strong>Martin</strong>]]></description>
		<wfw:commentRss>http://dreamhelg.ru/2009/11/fancy-ajax-contact-form/feed/</wfw:commentRss>
		<slash:comments>92</slash:comments>
		</item>
	</channel>
</rss>

