<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2russianfull.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" version="2.0">

<channel>
	<title>SimpleCoding.org</title>
	
	<link>http://www.simplecoding.org</link>
	<description>Блог о программировании</description>
	<lastBuildDate>Sun, 25 Jul 2010 20:00:16 +0000</lastBuildDate>
	
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<link xmlns="http://www.w3.org/2005/Atom" rel="http://api.friendfeed.com/2008/03#sup" type="application/json" href="http://friendfeed.com/api/public-sup.json#d217526a2c" />		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/simplecoding" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="simplecoding" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">simplecoding</feedburner:emailServiceId><feedburner:feedburnerHostname xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://feedburner.google.com</feedburner:feedburnerHostname><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2Fsimplecoding" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fsimplecoding" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2Fsimplecoding" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.bloglines.com/sub/http://feeds.feedburner.com/simplecoding" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fsimplecoding" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fsimplecoding" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fsimplecoding" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://lenta.yandex.ru/settings.xml?name=feed&amp;url=http%3A%2F%2Ffeeds.feedburner.com%2Fsimplecoding" src="http://lenta.yandex.ru/i/addfeed.gif">?????? ? ??????.?????</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.pusk.ru/#A:Rfeed=http://feeds.feedburner.com/simplecoding" src="http://blog.pusk.ru/wp-includes/images/rss_icon_neutral.png">Subscribe with pusk.ru</feedburner:feedFlare><item>
		<title>CGridView. Часть вторая. AJAX.</title>
		<link>http://www.simplecoding.org/cgridview-chast-vtoraya-ajax.html</link>
		<comments>http://www.simplecoding.org/cgridview-chast-vtoraya-ajax.html#comments</comments>
		<pubDate>Sun, 25 Jul 2010 13:16:41 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web разработка]]></category>
		<category><![CDATA[Yii]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/?p=1100</guid>
		<description><![CDATA[В этой части я хочу рассказать о некоторых особенностях реализации AJAX запросов в компоненте CGridView.
Предположим, у нас есть таблица, и мы создали для неё модель и скрипты для выполнения CRUD операций (с помощью встроенного генератора Yii).
Пусть таблица называется countries, содержит список стран с двумя полями (id, name).
В этом случае, страница управления записями будет доступна адресу

index.php?r=countries/admin
В [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_1101" class="wp-caption alignnone" style="width: 310px"><img src="http://www.simplecoding.org/wp-content/uploads/2010/07/yii_grid_view1.png" alt="yii grid view" title="yii grid view" width="300" height="169" style="float:left" class="size-full wp-image-1101" /><p class="wp-caption-text"> </p></div>
<p>В этой части я хочу рассказать о некоторых особенностях реализации <acronym title="Asynchronous JavaScript and XML">AJAX</acronym> запросов в компоненте <a href="http://www.yiiframework.com/doc/api/CGridView">CGridView</a>.</p>
<p>Предположим, у нас есть таблица, и мы создали для неё модель и скрипты для выполнения CRUD операций (с помощью встроенного генератора <strong>Yii</strong>).</p>
<p>Пусть таблица называется <code>countries</code>, содержит список стран с двумя полями (<code>id</code>, <code>name</code>).</p>
<p>В этом случае, страница управления записями будет доступна адресу<br />
<span id="more-1100"></span><br />
<code>index.php?r=countries/admin</code></p>
<div id="attachment_1107" class="wp-caption alignnone" style="width: 460px"><img src="http://www.simplecoding.org/wp-content/uploads/2010/07/cgridview_ajax_1.png" alt="cgridview ajax" title="cgridview ajax" width="450" height="249" class="size-full wp-image-1107" /><p class="wp-caption-text"> </p></div>
<p>В нижней части страницы находится <strong>пагинатор</strong> (листалка). Клик по ссылке с номером страницы приведет к отправке <strong>ajax запроса</strong>. Но вот тут появляется одна из особенностей. Этот ajax запрос возвращает не только новую страницу с данными, но и всю страницу целиком. Начиная от <code>doctype</code> и заканчивая закрывающим тегом <code>html</code>.</p>
<p>Если на странице ничего, кроме таблицы нет, то это не проблема. Но если мы разместим на ней несколько виджетов, для формирования которых нам потребуется выполнить дополнительные запросы к БД, то смысла в такой ajax пагинации окажется немного.</p>
<p>В общем, <strong>нужно, чтобы при клике на номер страницы сервер отправлял только фрагмент разметки с таблицей</strong>.</p>
<p>Сделать это несложно. Для начала вынесем из представления <code>views/countries/admin.php</code> код, который выполняет формирование таблицы в отдельный файл &#8211; <code>views/countries/admingrid.php</code>.</p>
<p>Речь идет об этом фрагменте</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">&lt;?php</span> <span class="re0">$this</span>-&gt;<span class="me1">widget</span><span class="br0">&#40;</span><span class="st0">&#039;zii.widgets.grid.CGridView&#039;</span>, <span class="kw3">array</span><span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">&#039;id&#039;</span>=&gt;<span class="st0">&#039;countries-grid&#039;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">&#039;dataProvider&#039;</span>=&gt;<span class="re0">$model</span>-&gt;<span class="me1">search</span><span class="br0">&#40;</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">&#039;filter&#039;</span>=&gt;<span class="re0">$model</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="st0">&#039;columns&#039;</span>=&gt;array<span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#039;c_id&#039;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#039;c_name&#039;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">array</span><span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#039;class&#039;</span>=&gt;<span class="st0">&#039;CButtonColumn&#039;</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#41;</span><span class="br0">&#41;</span>; <span class="kw2">?&gt;</span></div>
</li>
</ol>
</div>
<p>На его место в <code>views/countries/admin.php</code> добавляем следующий код.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">&lt;?php</span></div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$this</span>-&gt;<span class="me1">renderPartial</span><span class="br0">&#40;</span><span class="st0">&#039;admingrid&#039;</span>, <span class="kw3">array</span><span class="br0">&#40;</span><span class="st0">&#039;model&#039;</span>=&gt;<span class="re0">$model</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">?&gt;</span></div>
</li>
</ol>
</div>
<p>Идея в том, что если мы получим ajax запрос, то возвращать будем только содержимое <code>admingrid.php</code>, если запрос будет обычный – всю страницу.</p>
<p>Теперь переделываем метод <code>actionAdmin</code> контроллера.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">public</span> <span class="kw2">function</span> actionAdmin<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$model</span>=<span class="kw2">new</span> Countries<span class="br0">&#40;</span><span class="st0">&#039;search&#039;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$model</span>-&gt;<span class="me1">unsetAttributes</span><span class="br0">&#40;</span><span class="br0">&#41;</span>; &nbsp;<span class="co1">// clear any default values</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span><span class="kw3">isset</span><span class="br0">&#40;</span><span class="re0">$_GET</span><span class="br0">&#91;</span><span class="st0">&#039;Countries&#039;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$model</span>-&gt;<span class="me1">attributes</span>=<span class="re0">$_GET</span><span class="br0">&#91;</span><span class="st0">&#039;Countries&#039;</span><span class="br0">&#93;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw3">isset</span><span class="br0">&#40;</span><span class="re0">$_GET</span><span class="br0">&#91;</span><span class="st0">&#039;ajax&#039;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">renderPartial</span><span class="br0">&#40;</span><span class="st0">&#039;admingrid&#039;</span>,<span class="kw3">array</span><span class="br0">&#40;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#039;model&#039;</span>=&gt;<span class="re0">$model</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">else</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">render</span><span class="br0">&#40;</span><span class="st0">&#039;admin&#039;</span>,<span class="kw3">array</span><span class="br0">&#40;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#039;model&#039;</span>=&gt;<span class="re0">$model</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>Здесь добавлена дополнительная проверка (строка 8). Класс <code>CGridView</code> имеет свойство <code>ajaxVar</code>, которое по-умолчанию равно ajax. Это свойство задает имя GET параметра, который указывает, что данный запрос является ajax запросом.</p>
<p>Если этот параметр установлен, мы используем метод <code>renderPartial</code>, который возвращает браузеру только содержимое представления <code>admingrid</code>. В противном случае, вызываем метод render, который формирует всю страницу целиком.</p>
<p>Внешне в работе страницы ничего не изменилось, но если вы посмотрите с помощью firebug’а ответы сервера на ajax запросы, то разница будет заметной.</p>
<p>Теперь сделаем <strong>просмотр записей с помощью <acronym title="Asynchronous JavaScript and XML">AJAX</acronym></strong>.</p>
<p>По-умолчанию, если мы нажмем на кнопку просмотра (в последней колонке таблицы), то мы попадем на страницу соответствующей записи.</p>
<div id="attachment_1106" class="wp-caption alignnone" style="width: 123px"><img src="http://www.simplecoding.org/wp-content/uploads/2010/07/grid_buttons.png" alt="grid buttons" title="grid buttons" width="113" height="102" class="size-full wp-image-1106" /><p class="wp-caption-text"> </p></div>
<p>Мы изменим это поведение. Добавим под таблицей блок, в котором будут отображаться подробные сведения о выбранной записи, т.е. содержимое представления <code>views/countries/admingrid.php</code>.</p>
<p>Чтобы не менять стандартное поведение кнопок в таблице мы добавим к ней ещё один столбец со ссылками «<code>Предпросмотр</code>».</p>
<p>При клике по этой ссылке под таблицей появится подробная информация о данной записи.</p>
<p>Приступим.</p>
<p>Добавляем новую колонку в таблицу. Для этого изменим файл <code>admingrid.php</code> следующим образом.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">&lt;?php</span></div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$this</span>-&gt;<span class="me1">widget</span><span class="br0">&#40;</span><span class="st0">&#039;zii.widgets.grid.CGridView&#039;</span>, <span class="kw3">array</span><span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">&#039;id&#039;</span>=&gt;<span class="st0">&#039;countries-grid&#039;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">&#039;dataProvider&#039;</span>=&gt;<span class="re0">$model</span>-&gt;<span class="me1">search</span><span class="br0">&#40;</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="st0">&#039;filter&#039;</span>=&gt;<span class="re0">$model</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">&#039;afterAjaxUpdate&#039;</span>=&gt;<span class="st0">&#039;function(id, data) {$.fn.setPreviewLinksHandler(id, data);}&#039;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">&#039;columns&#039;</span>=&gt;array<span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#039;c_id&#039;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#039;c_name&#039;</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">array</span><span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#039;class&#039;</span>=&gt;<span class="st0">&#039;CButtonColumn&#039;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">array</span><span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#039;type&#039;</span>=&gt;<span class="st0">&#039;raw&#039;</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#039;value&#039;</span>=&gt;<span class="st0">&#039;CHtml::link(&quot;Предпросмотр&quot;, array(&quot;countries/view&quot;, &quot;id&quot;=&gt;$data-&gt;c_id, &quot;ajax&quot;=&gt;&quot;preview&quot;), array(&quot;name&quot;=&gt;&quot;previewLink&quot;))&#039;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#41;</span><span class="br0">&#41;</span>; <span class="kw2">?&gt;</span></div>
</li>
</ol>
</div>
<p>Здесь есть нюансы. Во-первых, при добавлении столбца необходимо указать, что он имеет тип <code>raw</code>, иначе по-умолчанию <strong>Yii</strong> применит фильтры к его содержимому.</p>
<p>Во-вторых, нам нужно назначить каждой ссылке обработчик события <code>onClick</code>. Причем, сделать это необходимо как при первоначальной загрузке страницы, так и при «перелистовании».</p>
<p>Для этого мы используем свойство <code>afterAjaxUpdate</code> (строка 6). Ему присваиваем JavaScript функцию, которая будет вызвана после обновления таблицы с помощью ajax метода.</p>
<p>Теперь напишем функцию <code>setPreviewLinksHandler</code>. Для этого создаём файл <code>js/previewlinks.js</code>.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1">$<span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; $.fn.setPreviewLinksHandler = <span class="kw2">function</span><span class="br0">&#40;</span>id, data<span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; $<span class="br0">&#40;</span><span class="st0">&quot;a[name=previewLink]&quot;</span><span class="br0">&#41;</span>.click<span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> <span class="kw3">link</span> = $<span class="br0">&#40;</span>this<span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $.get<span class="br0">&#40;</span><span class="kw3">link</span>.attr<span class="br0">&#40;</span><span class="st0">&#039;href&#039;</span><span class="br0">&#41;</span>, <span class="kw2">function</span><span class="br0">&#40;</span>data<span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $<span class="br0">&#40;</span><span class="st0">&#039;#preview&#039;</span><span class="br0">&#41;</span>.html<span class="br0">&#40;</span>data<span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">false</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; $.fn.setPreviewLinksHandler<span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span><span class="br0">&#41;</span>;</div>
</li>
</ol>
</div>
<p>Эта функция получает в качестве параметров <code>id</code> блока с таблицей и её содержимое (<code>data</code>). Но, т.к. содержимое таблицы мы менять не будем, то и эти параметры нам не нужны.</p>
<p>Наша функция <code>setPreviewLinksHandler</code> ищет все ссылки, у которых атрибут name равен <code>previewLink</code> и назначает им обработчик события <code>onClick</code>.</p>
<p>Этот обработчик формирует и отправляет ajax запрос, который возвращает подробную информацию о записи.</p>
<p>Тут обратите внимание, что при отправке ajax запроса используется атрибут <code>href</code> ссылки, таким образом, при отключенном <acronym title="JavaScript">JS</acronym> клик по ссылке будет отправлять пользователя на страницу с подробной информацией о записи.</p>
<p>Рассмотрим метод <code>actionView</code> контроллера.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">public</span> <span class="kw2">function</span> actionView<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw3">isset</span><span class="br0">&#40;</span><span class="re0">$_GET</span><span class="br0">&#91;</span><span class="st0">&#039;ajax&#039;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">renderPartial</span><span class="br0">&#40;</span><span class="st0">&#039;viewrow&#039;</span>,<span class="kw3">array</span><span class="br0">&#40;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#039;model&#039;</span>=&gt;<span class="re0">$this</span>-&gt;<span class="me1">loadModel</span><span class="br0">&#40;</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">else</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">render</span><span class="br0">&#40;</span><span class="st0">&#039;view&#039;</span>,<span class="kw3">array</span><span class="br0">&#40;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#039;model&#039;</span>=&gt;<span class="re0">$this</span>-&gt;<span class="me1">loadModel</span><span class="br0">&#40;</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>Здесь мы проверяем, есть ли в параметрах запроса атрибут <code>ajax</code>, и если он есть, показываем представление <code>viewrow</code>. При этом используется метод <code>renderPartial</code>. В противном случае, просто показываем представление <code>view</code>.</p>
<p><code>viewrow.php</code> создаём по тому же принципу, что и <code>admingrid.php</code>. Перемещаем код создания виджета <code>CDetailView</code> в <code>viewrow.php</code>.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">&lt;?php</span> <span class="re0">$this</span>-&gt;<span class="me1">widget</span><span class="br0">&#40;</span><span class="st0">&#039;zii.widgets.CDetailView&#039;</span>, <span class="kw3">array</span><span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">&#039;data&#039;</span>=&gt;<span class="re0">$model</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">&#039;attributes&#039;</span>=&gt;array<span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#039;c_id&#039;</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#039;c_name&#039;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#41;</span><span class="br0">&#41;</span>; <span class="kw2">?&gt;</span></div>
</li>
</ol>
</div>
<p>А в <code>view.php</code> добавим</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">&lt;?php</span> <span class="re0">$this</span>-&gt;<span class="me1">renderPartial</span><span class="br0">&#40;</span><span class="st0">&#039;viewrow&#039;</span>, <span class="kw3">array</span><span class="br0">&#40;</span><span class="st0">&#039;model&#039;</span>=&gt;<span class="re0">$model</span><span class="br0">&#41;</span><span class="br0">&#41;</span>; <span class="kw2">?&gt;</span></div>
</li>
</ol>
</div>
<p>В результате этих манипуляций подробные сведения о записи будут появляться под таблицей при клике по ссылке «Предпросмотр».</p>
<p>Я надеюсь, что никого не запутал своими объяснениями <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  Чтобы вам удобнее было экспериментировать, выкладываю архив с исходниками этого примера и дампом базы (предварительно вам нужно будет создать приложение Yii).</p>
<p><a href='http://www.simplecoding.org/wp-content/uploads/2010/07/yii_grid_countries.zip'><img src="http://www.simplecoding.org/wp-content/themes/three_cols/images/download_btn_blue.png" alt="архив с исходным кодом" /></a></p>
<p>Если есть вопросы или замечания, пишите! Особенно интересуют альтернативные варианты решения таких задач <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><strong>Интересно почитать</strong></p>
<p>Компания Intelsib предлагает <a href="http://www.intelsib.ru">продвижение сайта в интернете, поисковиках</a>, а также его аудит.</p><img src="http://www.simplecoding.org/?ak_action=api_record_view&id=1100&type=feed" alt="" /><img src="http://feeds.feedburner.com/~r/simplecoding/~4/H02z3S7uRks" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/cgridview-chast-vtoraya-ajax.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Неожиданное обновление CircleTasks</title>
		<link>http://www.simplecoding.org/circlre-tasks-update.html</link>
		<comments>http://www.simplecoding.org/circlre-tasks-update.html#comments</comments>
		<pubDate>Tue, 13 Jul 2010 18:50:06 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[CodeIgniter]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web разработка]]></category>
		<category><![CDATA[Разное]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/?p=1098</guid>
		<description><![CDATA[Постоянные читатели этого блога, наверное, помнят, что некоторое время назад (прошло почти 10 месяцев   ) я опубликовал несколько постов о разработке TODO скрипта под названием CircleTasks. Там же были выложены исходники и ссылка на демо версию.
Тогда пришло очень много пожеланий и советов по развитию системы. Какие-то я реализовал, какие-то – нет. Ключевой идеей [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_909" class="wp-caption alignnone" style="width: 238px"><img src="http://www.simplecoding.org/wp-content/uploads/2009/09/circle_tasks_logo.png" alt="" title="circle tasks logo" width="228" height="145" class="size-full wp-image-909" style="float:left" /><p class="wp-caption-text"> </p></div>
<p>Постоянные читатели этого блога, наверное, помнят, что некоторое время назад (прошло почти 10 месяцев <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ) я опубликовал несколько постов о разработке <strong>TODO скрипта</strong> под названием <a href="http://www.simplecoding.org/circle-tasks-2-novaya-versiya-moego-todo-skripta.html">CircleTasks</a>. Там же были выложены исходники и ссылка на демо версию.</p>
<p>Тогда пришло очень много пожеланий и советов по развитию системы. Какие-то я реализовал, какие-то – нет. Ключевой идеей была максимальная простота интерфейса, поэтому вводил новые функции я очень аккуратно.</p>
<p>Но, вынужден признаться, что со временем интерес к этому проекту у меня ослабел. Текущий функционал лично меня устраивал, и мотивации что-то менять не было.</p>
<p>И, совсем недавно, я узнал, что оказывается не я один пользуюсь этой системой <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
<span id="more-1098"></span><br />
Читатель этого блога <a href="http://www.vldcrowd.com">Radioact</a> предложил не только очень полезные изменения, но и реализовал их.</p>
<p>Я специально хочу отметить, что эти изменения основаны на опыте регулярного использования и экономят время при повседневной работе.</p>
<p>Кроме того, он поделился исходниками и демо версией.</p>
<p><a href="http://www.vldcrowd.com/todo/"><img src="http://www.simplecoding.org/wp-content/themes/three_cols/images/demo_btn_green.png" alt="демонстрационный пример" /></a></p>
<p>Логин: <code>demo@demo.com</code><br />
Пароль: <code>demodemo</code></p>
<p><a href='http://www.simplecoding.org/wp-content/uploads/2010/07/CircleTasks2.zip'><img src="http://www.simplecoding.org/wp-content/themes/three_cols/images/download_btn_blue.png" alt="архив с исходным кодом" /></a></p>
<p>Перечислю <strong>реализованные изменения</strong></p>
<p>1. Добавлен список статусов и при создании новой задачи. В моей версии этот список появлялся только при изменении задачи. Полезно если вам приходится добавлять начатые или не завершенные задачи.</p>
<p>2. Обнуление прошлых значений полей &#034;Создать задачу&#034;, при неоднократном добавлении задач. В оригинальном варианте данные, введенные в форму, сохранялись и отображались при создании новой задачи. Удобно, если нужно добавлять много задач на разные даты. Но не очень удобно если вам нужно добавить несколько задач на следующий месяц.</p>
<p>3. Сортировка по дате по умолчанию выполняется в убывающем порядке &#8211; новые вверху. Вообще, если вы правильно организовываете свою работу, то список невыполненных задач не должен быть большим <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>4. Повторный клик по статусу задачи закрывает список. Это важный момент, на который я не обращал внимания. Дело в том, что я отлично помню все иконки и статусы (т.к. сам их рисовал). Но новый пользователь сразу все не запомнит и будет открывать список только для того, чтобы посмотреть, что в нём есть.</p>
<p>Кроме того, <a href="http://www.vldcrowd.com">Radioact</a> сделал несколько предложений по <strong>дальнейшему развитию проекта</strong>. Все желающие могут присоединиться к обсуждению.</p>
<p>1. Добавить поддержку групповых операций вроде удаления записей и/или изменения их статусов. Возле каждой записи будет чекбокс.</p>
<p>2. Добавить пагинацию. Я сам стараюсь, чтобы список задач был максимально коротким и удаляю выполненные задачи. Но это мой стиль работы, описания к задачам у меня очень сжатые и через пару месяцев по ним сложно вспомнить, о чем шла речь. Но, возможно, для кого-то история окажется полезной.</p>
<p>3. Доработать оформление списка записей. Например, добавить в шапку треугольники для сортировки.</p>
<p>Все пожелания и замечания пишите в комментариях! Обсудим!</p>
<p><strong>Интересно почитать.</strong></p>
<p><a href="http://inetmarketing.ws">Интернет маркетинг &#8211; покер и видео сайты</a></p><img src="http://www.simplecoding.org/?ak_action=api_record_view&id=1098&type=feed" alt="" /><img src="http://feeds.feedburner.com/~r/simplecoding/~4/Athdot5WrEM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/circlre-tasks-update.html/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Yii PHP фреймворк: оформление административных страниц</title>
		<link>http://www.simplecoding.org/yii-php-frejmvork-oformlenie-administrativnyx-stranic.html</link>
		<comments>http://www.simplecoding.org/yii-php-frejmvork-oformlenie-administrativnyx-stranic.html#comments</comments>
		<pubDate>Tue, 06 Jul 2010 07:33:36 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[HTML]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web разработка]]></category>
		<category><![CDATA[Yii]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/?p=1094</guid>
		<description><![CDATA[Одной из наиболее мощных возможностей фреймворка Yii является генерация кода. Она позволяет сразу после создания таблицы в базе данных получить файлы модели, контроллера и представлений. Т.е. весь необходимый код для выполнения CRUD операций.
Но, естественно, код формируется по стандартному шаблону, дизайн которого вам, возможно, захочется изменить.
Взгляните на обычную страницу управления записями, сформированную с помощью компонента CGridView.

Такая [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_1095" class="wp-caption alignnone" style="width: 310px"><img src="http://www.simplecoding.org/wp-content/uploads/2010/07/yii_grid_view.png" alt="yii grid view" title="yii grid view" width="300" height="169" style="float:left" class="size-full wp-image-1095" /><p class="wp-caption-text"> </p></div>
<p>Одной из наиболее мощных возможностей <strong>фреймворка Yii</strong> является генерация кода. Она позволяет сразу после создания таблицы в базе данных получить файлы модели, контроллера и представлений. Т.е. весь необходимый код для выполнения CRUD операций.</p>
<p>Но, естественно, код формируется по стандартному шаблону, дизайн которого вам, возможно, захочется изменить.</p>
<p>Взгляните на обычную страницу управления записями, сформированную с помощью компонента <a href="http://www.yiiframework.com/doc/api/CGridView">CGridView</a>.<br />
<span id="more-1094"></span><br />
<div id="attachment_1097" class="wp-caption alignnone" style="width: 460px"><a href="http://www.simplecoding.org/wp-content/uploads/2010/07/basic_grid.png" target="_blank"><img src="http://www.simplecoding.org/wp-content/uploads/2010/07/basic_grid_thumb.png" alt="basic grid thumb" title="basic grid thumb" width="450" height="293" class="size-full wp-image-1097" /></a><p class="wp-caption-text"> </p></div></p>
<p>Такая страница доступна по адресу<br />
<code>sitename.domen?r=controller/admin</code></p>
<p>Она состоит из трех частей.</p>
<p>1) Строки с номерами показанных записей и их количеством (<code>summary</code>).</p>
<p>2) Таблицы с данными (<code>items</code>).</p>
<p>3) Листалки (<code>pager</code>). Если записей в таблице меньше, чем отображается на странице, этот элемент показан не будет.</p>
<p>Теперь взгляните на код, который создает такую таблицу.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">&lt;?php</span> <span class="re0">$this</span>-&gt;<span class="me1">widget</span><span class="br0">&#40;</span><span class="st0">&#039;zii.widgets.grid.CGridView&#039;</span>, <span class="kw3">array</span><span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">&#039;id&#039;</span>=&gt;<span class="st0">&#039;cities-grid&#039;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">&#039;dataProvider&#039;</span>=&gt;<span class="re0">$model</span>-&gt;<span class="me1">search</span><span class="br0">&#40;</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">&#039;filter&#039;</span>=&gt;<span class="re0">$model</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="st0">&#039;columns&#039;</span>=&gt;array<span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#039;id&#039;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#039;city&#039;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#039;country&#039;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">array</span><span class="br0">&#40;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#039;class&#039;</span>=&gt;<span class="st0">&#039;CButtonColumn&#039;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#41;</span><span class="br0">&#41;</span>; <span class="kw2">?&gt;</span></div>
</li>
</ol>
</div>
<p>Источником данных служит объект <code>CActiveDataProvider</code>, который создается в контроллере. Но сейчас речь не о данных.</p>
<p>Попробуем <strong>изменить порядок вывода основных элементов</strong>.</p>
<p><code>CGridView</code> имеет параметр <code>template</code>, который позволяет управлять выводом основных элементов страницы. Этот параметр принимает строку, в которой нужно перечислить необходимые элементы страницы.</p>
<p>Например, следующий код покажет листалку сверху и снизу страницы.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">&lt;?php</span> <span class="re0">$this</span>-&gt;<span class="me1">widget</span><span class="br0">&#40;</span><span class="st0">&#039;zii.widgets.grid.CGridView&#039;</span>, <span class="kw3">array</span><span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; …,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">&#039;template&#039;</span>=&gt;<span class="st0">&#039;{summary} {pager} {items} {pager}&#039;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">&#039;columns&#039;</span>=&gt;array<span class="br0">&#40;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; …,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#41;</span><span class="br0">&#41;</span>; <span class="kw2">?&gt;</span></div>
</li>
</ol>
</div>
<p>В шаблон можно вставлять произвольный текст и теги, но это не очень удобный вариант изменения разметки страницы. Лучше менять разметку внутри самих элементов и/или использовать <acronym title="Cascading Style Sheets">CSS</acronym> стили.</p>
<p>Если нужно <strong>изменить дизайн</strong>, то я бы рекомендовал делать в следующей последовательности.</p>
<p>1) Попытаться добиться результата, не меняя разметку, с помощью <acronym title="Cascading Style Sheets">CSS</acronym> стилей. Разметка, которую создаёт фреймворк, достаточна простая и соответствует стандартам.</p>
<p>2) Если необходимо, изменить разметку.</p>
<p>Рассмотрим первый вариант – <strong>использование своих <acronym title="Cascading Style Sheets">CSS</acronym> стилей</strong>.</p>
<p>По-умолчанию, для оформления <code>CGridView</code> используются следующие <acronym title="Cascading Style Sheets">CSS</acronym> файлы:</p>
<p>1) Для оформления таблицы <code>framework/zii/widgets/assets/gridview/styles.css</code> (он автоматически копируется в папку <code>DOCUMENT_ROOT/accets/номер/gridview/styles.css</code>).</p>
<p>2) Для оформления листалки <code>framework/web/widgets/pagers/pager.css</code> (он копируется в <code>assets/номер/pager.css</code>).</p>
<p>Допустим, ваши стили находятся в файлах <code>gridview-styles.css</code> и <code>pager-styles.css</code>, которые расположены в папке <code>DOCUMENT_ROOT/css</code>.</p>
<p>Подключаем файл со стилями таблицы, для этого передаем ссылку на файл в параметре <code>cssFile</code>.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">&lt;?php</span> <span class="re0">$this</span>-&gt;<span class="me1">widget</span><span class="br0">&#40;</span><span class="st0">&#039;zii.widgets.grid.CGridView&#039;</span>, <span class="kw3">array</span><span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; …,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">&#039;cssFile&#039;</span>=&gt;Yii::<span class="me2">app</span><span class="br0">&#40;</span><span class="br0">&#41;</span>-&gt;<span class="me1">getBaseUrl</span><span class="br0">&#40;</span><span class="kw2">true</span><span class="br0">&#41;</span>.<span class="st0">&#039;/css/admin-styles.css&#039;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">&#039;columns&#039;</span>=&gt;array<span class="br0">&#40;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; …,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#41;</span><span class="br0">&#41;</span>; <span class="kw2">?&gt;</span></div>
</li>
</ol>
</div>
<p>В результате, фреймворк будет загружать ваш файл вместо стандартного.</p>
<p>Кроме того, есть несколько параметров (<code>itemsCssClass</code>, <code>rowCssClass</code>, <code>summaryCssClass</code> и др.), которые позволяют указать ваши имена <acronym title="Cascading Style Sheets">CSS</acronym> классов. Но, вы можете использовать и стандартные имена классов, например, взять стандартный файл со стилями и переделывать его под свой дизайн.</p>
<p><strong>Установка стилей для листалки</strong> (<code>pager</code>) немного отличается.</p>
<p>Из <code>CGridView</code> нужно получить доступ к атрибуту pager и устанавливать параметры для него.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">&lt;?php</span> <span class="re0">$this</span>-&gt;<span class="me1">widget</span><span class="br0">&#40;</span><span class="st0">&#039;zii.widgets.grid.CGridView&#039;</span>, <span class="kw3">array</span><span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; …,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">&#039;pager&#039;</span>=&gt;array<span class="br0">&#40;</span><span class="st0">&#039;cssFile&#039;</span>=&gt;Yii::<span class="me2">app</span><span class="br0">&#40;</span><span class="br0">&#41;</span>-&gt;<span class="me1">getBaseUrl</span><span class="br0">&#40;</span><span class="kw2">true</span><span class="br0">&#41;</span>.<span class="st0">&#039;/css/pager-styles.css&#039;</span><span class="br0">&#41;</span>,&nbsp; &nbsp; <span class="st0">&#039;columns&#039;</span>=&gt;array<span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; …,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#41;</span><span class="br0">&#41;</span>; <span class="kw2">?&gt;</span></div>
</li>
</ol>
</div>
<p>Код похожий, но параметр <code>cssFile</code> передается в массиве и присваивается атрибуту <code>pager</code>.</p>
<p>Тут возникает интересный вопрос: «Какие еще параметры мы можем передать в этом массиве?»</p>
<p>Любые атрибуты класса <code>CBasePager</code>, а также его потомков, в том числе и имя класса-потомка, который используется для создания листалки.</p>
<p>В дистрибутив входит два таких класса <code>CLinkPager</code> (создает список ссылок с номерами страниц, используется по-умолчанию) и <code>CListPager</code> (создает выпадающий список с номерами страниц).</p>
<p>Заменить <code>CLinkPager</code> на <code>CListPager</code> можно так.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1">…</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">&#039;pager&#039;</span>=&gt;array<span class="br0">&#40;</span><span class="st0">&#039;class&#039;</span>=&gt;<span class="st0">&#039;CListPager&#039;</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">…</div>
</li>
</ol>
</div>
<p>Тут мы подходим к вопросу <strong>изменения разметки</strong>.</p>
<p>Допустим, нам нужно создать листалку в которой элементы страниц будут находиться внутри тегов <code>span</code>, а не <code>li</code>, как выводит <code>CLinkPager</code>.</p>
<p>Можно, конечно, создать класс, производный от <code>CBasePager</code>, но в данном случае будет удобнее наследовать <code>CLinkPager</code>.</p>
<p>У меня получился такой код (файл <code>protected/components /SpanLinkPager.php</code>).</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">class</span> SpanLinkPager <span class="kw2">extends</span> CLinkPager <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> run<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$buttons</span>=<span class="re0">$this</span>-&gt;<span class="me1">createPageButtons</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span><span class="kw3">empty</span><span class="br0">&#40;</span><span class="re0">$buttons</span><span class="br0">&#41;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">registerClientScript</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">echo</span> <span class="re0">$this</span>-&gt;<span class="me1">header</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">echo</span> CHtml::<span class="me2">tag</span><span class="br0">&#40;</span><span class="st0">&#039;div&#039;</span>,<span class="re0">$this</span>-&gt;<span class="me1">htmlOptions</span>,<span class="kw3">implode</span><span class="br0">&#40;</span><span class="st0">&quot;<span class="es0">\n</span>&quot;</span>,<span class="re0">$buttons</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">echo</span> <span class="re0">$this</span>-&gt;<span class="me1">footer</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; protected <span class="kw2">function</span> createPageButton<span class="br0">&#40;</span><span class="re0">$label</span>,<span class="re0">$page</span>,<span class="re0">$class</span>,<span class="re0">$hidden</span>,<span class="re0">$selected</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span><span class="re0">$hidden</span> || <span class="re0">$selected</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$class</span>.=<span class="st0">&#039; &#039;</span>.<span class="br0">&#40;</span><span class="re0">$hidden</span> ? self::<span class="me2">CSS_HIDDEN_PAGE</span> : self::<span class="me2">CSS_SELECTED_PAGE</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="st0">&#039;&lt;span class=&quot;&#039;</span>.<span class="re0">$class</span>.<span class="st0">&#039;&quot;&gt;&#039;</span>.CHtml::<span class="kw3">link</span><span class="br0">&#40;</span><span class="re0">$label</span>,<span class="re0">$this</span>-&gt;<span class="me1">createPageUrl</span><span class="br0">&#40;</span><span class="re0">$page</span><span class="br0">&#41;</span><span class="br0">&#41;</span>.<span class="st0">&#039;&lt;/span&gt;&#039;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>Я просто нашел в <code>CLinkPager</code> методы, в который формируется разметка и переопределил их. Т.е. код остался тот же, просто <code>ul</code> заменил на <code>div</code> (строка 12), а <code>li</code> &#8211; на <code>span</code> (строка 20).</p>
<p>Используя такой же подход можно переопределить класс <code>CGridView</code> и изменить разметку необходимым вам образом. Вот список основных методов, которые формируют разметку <code>CGridView</code>:<br />
<code>renderItems<br />
renderTableHeader<br />
renderTableFooter<br />
renderTableBody<br />
renderEmptyText<br />
renderFilter<br />
renderTableRow<br />
renderSummary</code> (находится в <code>CBaseListView</code>, который является предком <code>CGridView</code>)</p>
<p>На этом мы остановимся. Конечно, в этой статье рассмотрены далеко не все нюансы использования компонента <code>CGridView</code>. Например, он позволяет управлять выводом данных, а также использовать скины, но об этом как-нибудь в другой раз <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Если у вас возникли вопросы или есть замечания, пишите, постараюсь ответить.</p>
<p>До встречи!</p><img src="http://www.simplecoding.org/?ak_action=api_record_view&id=1094&type=feed" alt="" /><img src="http://feeds.feedburner.com/~r/simplecoding/~4/B6-awW3-8ec" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/yii-php-frejmvork-oformlenie-administrativnyx-stranic.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Yii PHP framework: создание запросов с условием IN</title>
		<link>http://www.simplecoding.org/yii-php-framework-sozdanie-zaprosov-s-usloviem-in.html</link>
		<comments>http://www.simplecoding.org/yii-php-framework-sozdanie-zaprosov-s-usloviem-in.html#comments</comments>
		<pubDate>Sat, 03 Jul 2010 10:27:22 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web разработка]]></category>
		<category><![CDATA[Yii]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/?p=1092</guid>
		<description><![CDATA[Последнее время мне довольно часто приходится работать с фреймворком Yii. И иногда возникают вопросы, ответы на которые не очевидны (во всяком случае для меня).
Попробую объяснить. Сам фреймворк, на мой взгляд, достаточно удобный и документация подробная. Но классов много, и формат передачи данных их методам часто сильно влияет на результат.
Рассмотрим небольшой пример – использование оператора IN.
Т.е. [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_1093" class="wp-caption alignnone" style="width: 294px"><img src="http://www.simplecoding.org/wp-content/uploads/2010/07/yii_in_statement.png" alt="yii in condition" title="yii in condition" width="284" height="148" style="float:left" class="size-full wp-image-1093" /><p class="wp-caption-text"> </p></div>
<p>Последнее время мне довольно часто приходится работать с <strong>фреймворком Yii</strong>. И иногда возникают вопросы, ответы на которые не очевидны (во всяком случае для меня).</p>
<p>Попробую объяснить. Сам фреймворк, на мой взгляд, достаточно удобный и документация подробная. Но классов много, и формат передачи данных их методам часто сильно влияет на результат.</p>
<p>Рассмотрим небольшой пример – <strong>использование оператора IN</strong>.</p>
<p>Т.е. нужно сформировать примерно такой запрос.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">SELECT</span> * <span class="kw1">FROM</span> tbl_users <span class="kw1">WHERE</span> id <span class="kw1">IN</span> <span class="br0">&#40;</span><span class="nu0">1</span>, <span class="nu0">2</span>, <span class="nu0">3</span><span class="br0">&#41;</span></div>
</li>
</ol>
</div>
<p><span id="more-1092"></span><br />
В <a href="http://yiiframework.ru/doc/guide/ru/index">Полном руководстве</a> на эту тему информации я не нашел, а копаться в методах <a href="http://www.yiiframework.com/doc/api/CActiveRecord">CActiveRecord</a> времени не было.</p>
<p>Вообще, я очень не люблю такие ситуации. С одной стороны, понятно как нужно написать запрос, с другой – хочется сделать это красиво, используя встроенную библиотеку. Копаться в документации не хочется, ведь на это уходит время, а запрос можно составить за считанные минуты. Но не все так просто.</p>
<p>Сначала покажу <strong>решение «в лоб»</strong>.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="re0">$ids</span> = <span class="kw3">array</span><span class="br0">&#40;</span><span class="nu0">1</span>, <span class="nu0">2</span>, <span class="nu0">3</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$dataProvider</span>=<span class="kw2">new</span> CActiveDataProvider<span class="br0">&#40;</span><span class="st0">&#039;User&#039;</span>,<span class="kw3">array</span><span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">&#039;criteria&#039;</span>=&gt;array<span class="br0">&#40;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#039;condition&#039;</span>=&gt;<span class="st0">&#039;id IN (&#039;</span>.<span class="kw3">implode</span><span class="br0">&#40;</span><span class="st0">&#039;,&#039;</span>, <span class="re0">$ids</span><span class="br0">&#41;</span>.<span class="st0">&#039;)&#039;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$this</span>-&gt;<span class="me1">render</span><span class="br0">&#40;</span><span class="st0">&#039;admin&#039;</span>,<span class="kw3">array</span><span class="br0">&#40;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="st0">&#039;model&#039;</span>=&gt;<span class="re0">$dataProvider</span>,</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
</ol>
</div>
<p>Тут мы формируем массив со значениями, которые будут перечислены после <code>IN</code>. А затем, с помощью функции <code>implode</code> преобразуем его в строку и просто вставляем в запрос.</p>
<p><strong>Недостатки</strong> такого подхода очевидны.</p>
<p><em>Во-первых</em>, выглядит код не очень красиво.</p>
<p><em>Во-вторых</em>, в реальном приложении значения для массива <code>$ids</code> будут откуда-то поступать, возможно, из параметров запроса. И если массив <code>$ids</code> окажется пустым, то при выполнении запроса возникнет ошибка. </p>
<p><em>В-третьих</em>, полученные значения нужно проверить. А написать что-то вроде</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="st0">&#039;params&#039;</span>=&gt;array<span class="br0">&#40;</span><span class="st0">&#039;:id&#039;</span>=&gt;implode<span class="br0">&#40;</span><span class="st0">&#039;, &#039;</span>, <span class="re0">$ids</span><span class="br0">&#41;</span><span class="br0">&#41;</span>,</div>
</li>
</ol>
</div>
<p>не получится, т.к. результат работы функции <code>implode</code> будет взят в кавычки. Т.е. проверку необходимо сделать предварительно.</p>
<p>Как видите, возникают проблемы практически на пустом месте. Нужно написать код проверок, решить, что делать с пустым массивом, затем протестировать этот код. И все ради решения тривиальной задачи.</p>
<p><strong>Решение с помощью библиотеки Yii.</strong></p>
<p>Оно выглядит гораздо проще.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="re0">$model</span> = User::<span class="me2">model</span><span class="br0">&#40;</span><span class="br0">&#41;</span>-&gt;<span class="me1">findAllByAttributes</span><span class="br0">&#40;</span><span class="kw3">array</span><span class="br0">&#40;</span><span class="st0">&#039;id&#039;</span>=&gt;array<span class="br0">&#40;</span><span class="nu0">1</span>, <span class="nu0">2</span>, <span class="nu0">3</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$dataProvider</span>=<span class="kw2">new</span> CActiveDataProvider<span class="br0">&#40;</span><span class="st0">&#039;User&#039;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$dataProvider</span>-&gt;<span class="me1">setData</span><span class="br0">&#40;</span><span class="re0">$model</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2"><span class="re0">$this</span>-&gt;<span class="me1">render</span><span class="br0">&#40;</span><span class="st0">&#039;index&#039;</span>,<span class="kw3">array</span><span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">&#039;dataProvider&#039;</span>=&gt;<span class="re0">$dataProvider</span>,</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
</ol>
</div>
<p>Метод <code>findAllByAttributes</code> класса <code>CActiveRecord</code> позволяет искать записи в БД по названию поля и значению. При этом если значение является массивом, то используется оператор <code>IN</code>.</p>
<p>Этот же самый код можно записать немного иначе.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="re0">$dataProvider</span>=<span class="kw2">new</span> CActiveDataProvider<span class="br0">&#40;</span><span class="st0">&#039;User&#039;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$dataProvider</span>-&gt;<span class="me1">criteria</span>-&gt;<span class="me1">addInCondition</span><span class="br0">&#40;</span><span class="st0">&#039;id&#039;</span>, <span class="kw3">array</span><span class="br0">&#40;</span><span class="nu0">1</span>,<span class="nu0">2</span>,<span class="nu0">3</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$this</span>-&gt;<span class="me1">render</span><span class="br0">&#40;</span><span class="st0">&#039;index&#039;</span>,<span class="kw3">array</span><span class="br0">&#40;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="st0">&#039;dataProvider&#039;</span>=&gt;<span class="re0">$dataProvider</span>,</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
</ol>
</div>
<p>Тут уже используется метод <code>addInCondition</code> класса <code>CDbCriteria</code>. Если вы работаете с <code>CActiveDataProvider</code>, то получить доступ к объекту <code>CDbCriteria</code> можно с помощью свойства <code>criteria</code>.</p>
<p>Теперь проведем несколько экспериментов.</p>
<p>Попробуем в массиве передать строку.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="re0">$dataProvider</span>-&gt;<span class="me1">criteria</span>-&gt;<span class="me1">addInCondition</span><span class="br0">&#40;</span><span class="st0">&#039;id&#039;</span>, <span class="kw3">array</span><span class="br0">&#40;</span><span class="nu0">1</span>,<span class="nu0">2</span>,<span class="st0">&#039;test&#039;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
</ol>
</div>
<p>В результате будет выполнен следующий запрос.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">SELECT</span> * <span class="kw1">FROM</span> <span class="st0">&#039;tbl_user&#039;</span> <span class="kw1">WHERE</span> <span class="st0">&quot;id&quot;</span> <span class="kw1">IN</span> <span class="br0">&#40;</span><span class="nu0">1</span>, <span class="nu0">2</span>, <span class="nu0">0</span><span class="br0">&#41;</span></div>
</li>
</ol>
</div>
<p>Т.е. текстовое значение было заменено нулем, что вполне логично, т.к. поле <code>id</code> имеет тип <code>INT</code>.</p>
<p>Если запрос будет выполняться к полю текстового типа, то текстовые и числовые значения будут вставлены в кавычках.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="re0">$dataProvider</span>-&gt;<span class="me1">criteria</span>-&gt;<span class="me1">addInCondition</span><span class="br0">&#40;</span><span class="st0">&#039;id&#039;</span>, <span class="kw3">array</span><span class="br0">&#40;</span><span class="nu0">1</span>, <span class="st0">&#039;admin&#039;</span>,<span class="st0">&#039;user&#039;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
</ol>
</div>
<p>сформирует такой запрос</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">SELECT</span> * <span class="kw1">FROM</span> <span class="st0">&#039;tbl_user&#039;</span> <span class="kw1">WHERE</span> <span class="st0">&quot;id&quot;</span> <span class="kw1">IN</span> <span class="br0">&#40;</span><span class="st0">&#039;1&#039;</span>,<span class="st0">&#039;admin&#039;</span>, <span class="st0">&#039;user&#039;</span><span class="br0">&#41;</span></div>
</li>
</ol>
</div>
<p>А если массив окажется пуст, то фреймворк гарантирует, что из таблицы не будет выбрана ни одна запись.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="re0">$dataProvider</span>-&gt;<span class="me1">criteria</span>-&gt;<span class="me1">addInCondition</span><span class="br0">&#40;</span><span class="st0">&#039;id&#039;</span>, <span class="kw3">array</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
</ol>
</div>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">SELECT</span> * <span class="kw1">FROM</span> <span class="st0">&#039;tbl_user&#039;</span> <span class="kw1">WHERE</span> <span class="nu0">0</span>=<span class="nu0">1</span></div>
</li>
</ol>
</div>
<p>Как видите, использование встроенных библиотек всё-таки оправдывает время, потраченное на их изучение <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Только не забывайте при работе с документацией Yii учитывать один момент. Классы библиотеки тесно связаны между собой, поэтому искать нужно не только в методах класса, с которым вы непосредственно работаете, но и в методах объектов, которые использует этот класс.</p>
<p>Так <code>CActiveDataProvider</code> использует <code>CDbCriteria</code> для формирования условий, <code>CPagination</code> – для разбивки на страницы, CSort – для сортировки и т.д.</p>
<p>Вообще, я заметил, чем больше работаешь с фреймворком, тем логичнее кажутся решения разработчиков и тем проще ориентироваться в документации <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Удачи!</p><img src="http://www.simplecoding.org/?ak_action=api_record_view&id=1092&type=feed" alt="" /><img src="http://feeds.feedburner.com/~r/simplecoding/~4/_G4wbEusnIU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/yii-php-framework-sozdanie-zaprosov-s-usloviem-in.html/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>WordPress плагин для внутренней перелинковки страниц сайта. Версия 3.</title>
		<link>http://www.simplecoding.org/wordpress-plagin-dlya-vnutrennej-perelinkovki-stranic-sajta-versiya-3.html</link>
		<comments>http://www.simplecoding.org/wordpress-plagin-dlya-vnutrennej-perelinkovki-stranic-sajta-versiya-3.html#comments</comments>
		<pubDate>Thu, 24 Jun 2010 08:30:24 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web разработка]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/?p=1089</guid>
		<description><![CDATA[Знаете, всегда очень приятно, когда кто-то проявляет внимание к твоей работе и помогает полезными советами. Сразу появляется желание что-нибудь сделать  
Так примерно месяц назад я написал и выложил первую версию плагина Terms Descriptions. Практически сразу же появилось множество отзывов и пожеланий, были найдены баги.
Примечание. Этот плагин предназначен для автоматической внутренней перелинковки сайта. Вы создаёте [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_1090" class="wp-caption alignnone" style="width: 310px"><img src="http://www.simplecoding.org/wp-content/uploads/2010/06/wp_terms_descriptions_3_logo.png" alt="wp terms descriptions 3 logo" title="wp terms descriptions 3 logo" width="300" height="250" class="size-full wp-image-1090" style="float:left" /><p class="wp-caption-text"> </p></div>
<p>Знаете, всегда очень приятно, когда кто-то проявляет внимание к твоей работе и <strong>помогает полезными советами</strong>. Сразу появляется желание что-нибудь сделать <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Так примерно месяц назад я написал и выложил первую версию плагина <a href="http://www.simplecoding.org/wordpress-plagin-dlya-vnutrennej-perelinkovki-stranic-sajta.html">Terms Descriptions</a>. Практически сразу же появилось множество отзывов и пожеланий, были найдены баги.</p>
<p><em>Примечание</em>. Этот плагин предназначен для автоматической внутренней перелинковки сайта. Вы создаёте перечень ключевых слов и указываете ссылки для них. Плагин ищет ключевые слова в записях блога и преобразует их в ссылки.</p>
<p>В результате, через неделю вышла <a href="http://www.simplecoding.org/wordpress-plagin-dlya-vnutrennej-perelinkovki-stranic-sajta-versiya-2.html">вторая версия плагина</a>, которая значительно гибче позволяла управлять созданием ссылок. Например, была добавлена возможность ограничить их количество на одной странице.</p>
<p>В общем-то, я думал, что плагин решает свою узкую задачу в полном объеме… Но один из читателей этого блога (по имени <strong>Турист</strong>) объяснил мне, что это не так <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
<span id="more-1089"></span><br />
Представьте, что у вас есть несколько сайтов схожей тематики, и вы хотите поставить ссылки с одного сайта на другой. Т.е. нужна возможность <strong>задавать произвольные ссылки</strong>.</p>
<p>Именно эта функция и добавлена в новой (третьей) версии плагина.</p>
<div id="attachment_1088" class="wp-caption alignnone" style="width: 413px"><img src="http://www.simplecoding.org/wp-content/uploads/2010/06/wp_terms_descriptions_3.png" alt="wp terms descriptions 3" title="wp terms descriptions 3" width="403" height="459" class="size-full wp-image-1088" /><p class="wp-caption-text"> </p></div>
<p>Как видно на скриноште, появилась дополнительная опция при выборе типа ссылки. Вы можете поставить ссылку на пост (Post), страницу (Page) данного блога или указать произвольную ссылку.</p>
<p>При выборе последнего варианта список с перечнем страниц будет заменен на обычное текстовое поле, в котором можно указать ссылку.</p>
<p>Остальные функции плагина по сравнению с предыдущей версией не изменились, было исправлено несколько мелких багов.</p>
<p>Надеюсь, нововведение окажется полезным, и, как всегда, жду ваши отзывы и комментарии.</p>
<p><strong>Скачать</strong> новую версию плагина.</p>
<p><a href='http://www.simplecoding.org/wp-content/uploads/2010/05/terms-descriptions.zip'><img src="http://www.simplecoding.org/wp-content/themes/three_cols/images/download_btn_blue.png" alt="архив с исходным кодом" /></a></p>
<p><strong>P.S.</strong> Я сделал <a href="http://www.simplecoding.org/plagin-wordpress-terms-descriptions">отдельную страницу</a> для этого плагина, теперь все новые версии будут выкладываться там.</p><img src="http://www.simplecoding.org/?ak_action=api_record_view&id=1089&type=feed" alt="" /><img src="http://feeds.feedburner.com/~r/simplecoding/~4/WQQXtSS0G4Q" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/wordpress-plagin-dlya-vnutrennej-perelinkovki-stranic-sajta-versiya-3.html/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Yii фреймворк: получение статистики перехода по ссылкам от сервиса Bit.ly</title>
		<link>http://www.simplecoding.org/yii-frejmvork-poluchenie-statistiki-perexoda-po-ssylkam-ot-servisa-bit-ly.html</link>
		<comments>http://www.simplecoding.org/yii-frejmvork-poluchenie-statistiki-perexoda-po-ssylkam-ot-servisa-bit-ly.html#comments</comments>
		<pubDate>Tue, 15 Jun 2010 08:19:22 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web разработка]]></category>
		<category><![CDATA[Yii]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/?p=1083</guid>
		<description><![CDATA[Сегодня продолжим тему использования сервиса Bit.ly вместе с PHP фреймворком Yii. В прошлой части мы рассмотрели создание коротких ссылок для страниц вымышленного сайта с новостями.
В этой части мы создадим отдельную страницу, на которой будет отображаться статистика переходов по коротким ссылкам.
Приступим.

Шаг первый. Добавляем новое поле в модель.
На данный момент у нас есть модель News, которая содержит [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_1081" class="wp-caption alignnone" style="width: 270px"><img src="http://www.simplecoding.org/wp-content/uploads/2010/06/yii_bitly.png" alt="yii bitly" title="yii bitly" width="260" height="196" class="size-full wp-image-1081" style="float:left" /><p class="wp-caption-text"> </p></div>
<p>Сегодня продолжим тему использования сервиса Bit.ly вместе с <acronym title="PHP: Hypertext Preprocessor">PHP</acronym> фреймворком Yii. В <a href="http://www.simplecoding.org/ispolzovanie-servisa-bit-ly-vmeste-s-php-frejmvorkom-yii.html">прошлой части</a> мы рассмотрели создание коротких ссылок для страниц вымышленного сайта с новостями.</p>
<p>В этой части мы создадим отдельную страницу, на которой будет отображаться <strong>статистика переходов по коротким ссылкам</strong>.</p>
<p>Приступим.<br />
<span id="more-1083"></span><br />
<strong>Шаг первый. Добавляем новое поле в модель.</strong></p>
<p>На данный момент у нас есть модель <code>News</code>, которая содержит следующие поля:</p>
<p><code>n_id</code> – первичный ключ;<br />
<code>n_title</code> – заголовок новости;<br />
<code>n_content</code> – текст новости;<br />
<code>n_short_url</code> – короткая ссылка (не обязательное поле).</p>
<p>Мы добавим ещё одно поле <code>n_clicks</code>, в которое будем записывать количество переходов по короткой ссылке.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">class</span> News <span class="kw2">extends</span> CActiveRecord</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw2">public</span> <span class="re0">$n_clicks</span>;</div>
</li>
<li class="li1">
<div class="de1">&#8230;</div>
</li>
</ol>
</div>
<p>Сохранять значение этого поля в базе данных не нужно, ведь оно будет очень быстро устаревать, поэтому мы будем получать его с сервиса <em>Bit.ly</em> при каждой загрузке страницы со статистикой.</p>
<p><strong>Шаг второй. Создаём метод для получения статистики.</strong></p>
<p>В прошлой части мы создали компонент <code>BitLyShortener</code> с методом получения короткой ссылки. Используем этот же компонент и добавим в него новый метод.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">public</span> <span class="kw3">static</span> <span class="kw2">function</span> getStatistics<span class="br0">&#40;</span>&amp;amp;<span class="re0">$models</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">//если массив пуст &#8211; не делаем ничего</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="nu0">0</span> == <span class="kw3">count</span><span class="br0">&#40;</span><span class="re0">$models</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="coMULTI">/*</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp; &nbsp; &nbsp;В запросе к Bit.ly можно передать до 15 ссылок.</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp; &nbsp; &nbsp;Поэтому сначала формируем общую часть запроса, а</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp; &nbsp; &nbsp;затем &#8211; добавляем в цикле ссылки, для которых</span></div>
</li>
<li class="li2">
<div class="de2"><span class="coMULTI">&nbsp; &nbsp; &nbsp;нужно получить статистику.</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp; &nbsp; */</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$requestBase</span> = <span class="st0">&#039;http://api.bit.ly/v3/clicks?&#039;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; .<span class="st0">&#039;login=&#039;</span>.self::<span class="me2">LOGIN</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; .<span class="st0">&#039;&amp;amp;apiKey=&#039;</span>.self::<span class="me2">APIKEY</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; .<span class="st0">&#039;&amp;amp;format=json&#039;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">//разбиваем массив с моделями на блоки по 15 элементов</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$modelsChunks</span> = <span class="kw3">array_chunk</span><span class="br0">&#40;</span><span class="re0">$models</span>, <span class="nu0">15</span>, <span class="kw2">true</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">//для каждого блока формируем и отправляем запрос</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">foreach</span> <span class="br0">&#40;</span><span class="re0">$modelsChunks</span> <span class="kw1">as</span> <span class="re0">$i</span> =&gt; <span class="re0">$chunk</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$request</span> = <span class="re0">$requestBase</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">foreach</span> <span class="br0">&#40;</span><span class="re0">$chunk</span> <span class="kw1">as</span> <span class="re0">$key</span> =&gt; <span class="re0">$model</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$request</span> .= <span class="st0">&#039;&amp;amp;shortUrl=&#039;</span>.<span class="kw3">urlencode</span><span class="br0">&#40;</span><span class="re0">$model</span>-&gt;<span class="me1">n_short_url</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$response</span> = <span class="kw3">file_get_contents</span><span class="br0">&#40;</span><span class="re0">$request</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$res</span> = json_decode<span class="br0">&#40;</span><span class="re0">$response</span>, <span class="kw2">true</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//сохраняем результаты</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">foreach</span> <span class="br0">&#40;</span><span class="re0">$chunk</span> <span class="kw1">as</span> <span class="re0">$key</span> =&gt; <span class="re0">$model</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$models</span><span class="br0">&#91;</span><span class="re0">$key</span><span class="br0">&#93;</span>-&gt;<span class="me1">n_clicks</span> = <span class="re0">$res</span><span class="br0">&#91;</span><span class="st0">&#039;data&#039;</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st0">&#039;clicks&#039;</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="re0">$key</span> &#8211; <span class="re0">$i</span>*<span class="nu0">15</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st0">&#039;global_clicks&#039;</span><span class="br0">&#93;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>Принцип получения статистики такой же, как и принцип создания короткой ссылки. Нужно отправить специальным образом сформированный запрос. Но есть нюанс.</p>
<p>Сервис Bit.ly накладывает ограничение на количество ссылок, для которых можно получить статистику. На данный момент обрабатывается не более 15 ссылок на запрос.</p>
<p>Поэтому мы разбиваем массив с короткими ссылками на блоки по 15 штук, и для каждого блока отправляем отдельный запрос.</p>
<p>Вообще сервис возвращает несколько значений</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="st0">&quot;clicks&quot;</span>: <span class="br0">&#91;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;short_url&quot;</span>: <span class="st0">&quot;http://tcrn.ch/a4MSUH&quot;</span>, <span class="co1">//короткая ссылка</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;global_hash&quot;</span>: <span class="st0">&quot;bWw49z&quot;</span>, <span class="co1">//глобальный хеш идентификатора bit.ly</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;user_clicks&quot;</span>: <span class="nu0">0</span>, <span class="co1">//количество кликов по данной ссылке</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;user_hash&quot;</span>: <span class="st0">&quot;a4MSUH&quot;</span>, <span class="co1">//идентификатор пользователя bit.ly</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;global_clicks&quot;</span>: <span class="nu0">1105</span> <span class="co1">//количество кликов по всем коротким ссылкам, которые соответствуют данному полному <acronym title="Uniform Resource Locator">URL</acronym></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>,</div>
</li>
</ol>
</div>
<p>Из всех этих параметров нам нужен только <code>global_clicks</code>. Его мы и записываем в исходный массив с новостями.</p>
<p><strong>Шаг третий. Создаём страницу со статистикой.</strong></p>
<p>Для этого добавим в контроллер метод <code>actionStatistics</code></p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">public</span> <span class="kw2">function</span> actionStatistics<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$criteria</span> = <span class="kw2">new</span> CDbCriteria;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$pages</span> = <span class="kw2">new</span> CPagination<span class="br0">&#40;</span>News::<span class="me2">model</span><span class="br0">&#40;</span><span class="br0">&#41;</span>-&gt;<span class="me1">count</span><span class="br0">&#40;</span><span class="re0">$criteria</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$pages</span>-&gt;<span class="me1">pageSize</span> = self::<span class="me2">PAGE_SIZE</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$models</span> = News::<span class="me2">model</span><span class="br0">&#40;</span><span class="br0">&#41;</span>-&gt;<span class="me1">findAll</span><span class="br0">&#40;</span><span class="re0">$criteria</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">//получаем данные о посещаемости от Bit.ly</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; BitLyShortener::<span class="me2">getStatistics</span><span class="br0">&#40;</span><span class="re0">$models</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">render</span><span class="br0">&#40;</span><span class="st0">&#039;statistics&#039;</span>, <span class="kw3">array</span><span class="br0">&#40;</span><span class="st0">&#039;models&#039;</span>=&gt;<span class="re0">$models</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>И создаём представление <code>protected/views/news/statistics.php</code></p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">&lt;?php</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">foreach</span> <span class="br0">&#40;</span><span class="re0">$models</span> <span class="kw1">as</span> <span class="re0">$model</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">?&gt;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &lt;p&gt;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &lt;strong&gt;&lt;?php <span class="kw3">echo</span> <span class="re0">$model</span>-&gt;<span class="me1">n_title</span>; ?&gt;&lt;/strong&gt;&lt;br /&gt;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; Короткая ссылка: <span class="kw2">&lt;?php</span> <span class="kw3">echo</span> <span class="re0">$model</span>-&gt;<span class="me1">n_short_url</span>; ?&gt;&lt;br /&gt;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; Количество переходов: <span class="kw2">&lt;?php</span> <span class="kw3">echo</span> <span class="re0">$model</span>-&gt;<span class="me1">n_clicks</span>; <span class="kw2">?&gt;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &lt;/p&gt;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">&lt;?php</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="co1">//TODO добавить листалку страниц</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="co1">//end of statistics.php</span></div>
</li>
</ol>
</div>
<p>В результате, по адресу <code>index.php?r=news/statistics</code> должна появиться страница со статистикой.</p>
<p>Как видите, ничего сложного. Главное, не ошибиться при составлении запроса для Bit.ly.</p>
<p>Архив с файлами для этого примера (необходимо распаковать в папку protected).</p>
<p><a href='http://www.simplecoding.org/wp-content/uploads/2010/06/bit_ly_statistics.zip'><img src="http://www.simplecoding.org/wp-content/themes/three_cols/images/download_btn_blue.png" alt="архив с исходным кодом" /></a></p>
<p>Все вопросы и замечания пишите в комментариях. Постараюсь ответить <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p><strong>Интересно почитать</strong></p>
<p>В магазине gamesdealer.ru  есть <a href="http://gamesdealer.ru/">все для покера:</a> карты, фишки и покерные наборы.</p>
<p>Магазин Irobot-home.ru: лучшие <a href="http://www.irobot-home.ru/">роботы пылесосы</a> от iRobot.</p><img src="http://www.simplecoding.org/?ak_action=api_record_view&id=1083&type=feed" alt="" /><img src="http://feeds.feedburner.com/~r/simplecoding/~4/ETv1MyF7f0A" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/yii-frejmvork-poluchenie-statistiki-perexoda-po-ssylkam-ot-servisa-bit-ly.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Использование сервиса Bit.ly вместе с PHP фреймворком Yii</title>
		<link>http://www.simplecoding.org/ispolzovanie-servisa-bit-ly-vmeste-s-php-frejmvorkom-yii.html</link>
		<comments>http://www.simplecoding.org/ispolzovanie-servisa-bit-ly-vmeste-s-php-frejmvorkom-yii.html#comments</comments>
		<pubDate>Sat, 12 Jun 2010 17:42:09 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web разработка]]></category>
		<category><![CDATA[Yii]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/?p=1080</guid>
		<description><![CDATA[Думаю, о твиттере и о том, какую роль в нем играют короткие ссылки, слышали все. В принципе, можно вообще не заморачиваться, т.к. twitter сам создаст их для вас, но при таком подходе возникнет несколько проблем.
Во-первых, длина ссылки и текста может превысить 140 символов. Т.е. ссылку лучше сразу сократить.
Во-вторых, будет сложнее отслеживать статистику переходов.
Поэтому гораздо удобнее [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_1081" class="wp-caption alignnone" style="width: 270px"><img src="http://www.simplecoding.org/wp-content/uploads/2010/06/yii_bitly.png" alt="yii bitly" title="yii bitly" width="260" height="196" class="size-full wp-image-1081" style="float:left" /><p class="wp-caption-text"> </p></div>
<p>Думаю, о твиттере и о том, какую роль в нем играют <strong>короткие ссылки</strong>, слышали все. В принципе, можно вообще не заморачиваться, т.к. <strong>twitter</strong> сам создаст их для вас, но при таком подходе возникнет несколько проблем.</p>
<p><em>Во-первых</em>, длина ссылки и текста может превысить 140 символов. Т.е. ссылку лучше сразу сократить.</p>
<p><em>Во-вторых</em>, будет сложнее отслеживать статистику переходов.</p>
<p>Поэтому гораздо удобнее использовать специализированные сервисы, например, <strong>Bit.ly</strong>. Этот сервис предоставляет <a href="http://code.google.com/p/bitly-api/wiki/ApiDocumentation"><acronym title="Application Programming Interface">API</acronym></a> как для создания ссылок, так и для получения статистики переходов по ним.</p>
<p>Теперь рассмотрим небольшой пример.<br />
<span id="more-1080"></span><br />
Допустим, вы <strong>разрабатываете сайт с использованием <acronym title="PHP: Hypertext Preprocessor">PHP</acronym> фреймворка Yii</strong>. На котором у вас есть раздел с новостями. Необходимо на странице каждой новости создать кнопку «Опубликовать в твиттере», а текст сообщения должен состоять из заголовка новости и короткой ссылки на неё.</p>
<p>Код создания самой кнопки мы сейчас рассматривать не будем, т.к. это немного другая тема. Мы напишем компонент, позволяющий получать сокращенный <acronym title="Uniform Resource Locator">URL</acronym> страницы, и рассмотрим его подключение к фреймворку.</p>
<p><strong>Шаг первый. Подготовим площадку для экспериментов.</strong></p>
<p>1) Создаем приложение</p>
<p><code>yiic webapp .</code></p>
<p>2) Создаем таблицу в БД. Я использовал стандартную sqlite базу.</p>
<p>Название таблицы <code>tbl_news</code></p>
<p>Поля:</p>
<p><code>n_id</code> – первичный ключ;<br />
<code>n_title</code> – заголовок новости;<br />
<code>n_content</code> – текст новости;<br />
<code>n_short_url</code> – короткая ссылка (не обязательное поле).</p>
<p>3) Создаем контроллер и модель</p>
<p>Для этого последовательно выполняем три команды</p>
<p><code>yiic shell<br />
model News tbl_news<br />
crud News</code></p>
<p>Теперь у нас есть работающий сайт. Страница с новостями будет доступна по адресу.</p>
<p><code>site_name.domen/index.php?r=news/index</code></p>
<p>На этой странице в сайдбаре будут ссылки на страницы создания и управления новостями.</p>
<p><strong>Шаг второй. Регистрируемся на сервисе Bit.ly.</strong></p>
<p>В принципе, короткие ссылки можно получить и без регистрации, но тогда вы не сможете смотреть статистику.</p>
<p>Регистрация осуществляется на <a href="http://bit.ly/account/register">этой</a> странице.</p>
<p>Затем необходимо получить <a href="http://bit.ly/account/your_api_key"><acronym title="Application Programming Interface">API</acronym>-ключ</a>.</p>
<p>Ваши логин и ключ <acronym title="Application Programming Interface">API</acronym> будут использоваться при всех обращениях к сервису.</p>
<p><strong>Шаг третий. Если необходимо, настраиваем urlManager.</strong></p>
<p>Этот компонент позволяет превращать ссылки вида<br />
<code>localhost/sites/yii_bit_ly/public_html/index.php?r=news/view&amp;id=1</code><br />
в<br />
<code>localhost/sites/yii_bit_ly/public_html/index.php/news/1</code></p>
<p>Настройка выполняется в файле <code>protected/config/main.php</code>, подробнее о ней можно почитать в статье <a href="http://yiiframework.ru/doc/guide/ru/topics.url">Красивые адреса <acronym title="Uniform Resource Locator">URL</acronym></a>.</p>
<p>Дело в том, что если вы измените формат ссылок, то сокращенные ссылки нужно будет создавать заново, поэтому лучше определиться с ним заранее.</p>
<p><strong>Шаг четвертый. Создаём компонент для работы с сервисом.</strong></p>
<p>Назовем его <code>BitLyShortener</code>. Он должен находиться в файле (<code>protected/components/BitLyShortener.php</code>).</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">&lt;?php</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">/**</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* Этот компонент предназначен для создания ссылок с помощью</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* сервиса Bit.ly</span></div>
</li>
<li class="li2">
<div class="de2"><span class="coMULTI">&nbsp;*/</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">class</span> BitLyShortener <span class="kw2">extends</span> CComponent <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; const LOGIN = <span class="st0">&#039;ваш_логин&#039;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; const APIKEY = <span class="st0">&#039;ваш_API_ключ&#039;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="coMULTI">/**</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp; &nbsp; &nbsp;* Укорачивает заданнй <acronym title="Uniform Resource Locator">URL</acronym> с помощью сервиса Bit.ly</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp; &nbsp; &nbsp;*</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp; &nbsp; &nbsp;* @param $fullUrl string &#8211; <acronym title="Uniform Resource Locator">URL</acronym> для которого нужно получить короткую ссылку</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp; &nbsp; &nbsp;* @return string короткая ссылка</span></div>
</li>
<li class="li2">
<div class="de2"><span class="coMULTI">&nbsp; &nbsp; &nbsp;*/</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw3">static</span> <span class="kw2">function</span> getShortUrl<span class="br0">&#40;</span><span class="re0">$fullUrl</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//формируем запрос</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$request</span> = <span class="st0">&#039;http://api.bit.ly/v3/shorten?&#039;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .<span class="st0">&#039;login=&#039;</span>.self::<span class="me2">LOGIN</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .<span class="st0">&#039;&amp;amp;apiKey=&#039;</span>.self::<span class="me2">APIKEY</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .<span class="st0">&#039;&amp;amp;longUrl=&#039;</span>.<span class="kw3">urlencode</span><span class="br0">&#40;</span><span class="re0">$fullUrl</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .<span class="st0">&#039;&amp;amp;format=json&#039;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//отправляем запрос</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$response</span> = <span class="kw3">file_get_contents</span><span class="br0">&#40;</span><span class="re0">$request</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$res</span> = json_decode<span class="br0">&#40;</span><span class="re0">$response</span>, <span class="kw2">true</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="re0">$res</span><span class="br0">&#91;</span><span class="st0">&#039;data&#039;</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st0">&#039;url&#039;</span><span class="br0">&#93;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="co1">//end of BitLyshortener.php</span></div>
</li>
</ol>
</div>
<p>Архив с этим компонентом</p>
<p><a href='http://www.simplecoding.org/wp-content/uploads/2010/06/BitLyShortener.zip'><img src="http://www.simplecoding.org/wp-content/themes/three_cols/images/download_btn_blue.png" alt="архив с исходным кодом" /></a></p>
<p>Как видите, перед использованием нужно указать ваши логин и <acronym title="Application Programming Interface">API</acronym> ключ для работы с Bit.ly. Затем, для получения короткой ссылки достаточно вызвать метод <code>getShortUrl</code> и передать ему ссылку страницы в первом параметре.</p>
<p><acronym title="Application Programming Interface">API</acronym> у Bit.ly достаточно прост. Для получения короткой ссылки достаточно сформировать и отправить обычный <acronym title="HyperText Transfer Protocol">HTTP</acronym> запрос. Ответ можно получить как в JSON, так и в <acronym title="eXtensible Markup Language">XML</acronym> формате. На мой взгляд, работать с JSON немного проще, но это не принципиально.</p>
<p>В случае успешного создания короткой ссылки сервис возвращает следующие данные</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw3">array</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="st0">&#039;status_code&#039;</span> =&gt; int <span class="nu0">200</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="st0">&#039;status_txt&#039;</span> =&gt; string <span class="st0">&#039;OK&#039;</span> <span class="br0">&#40;</span>length=<span class="nu0">2</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="st0">&#039;data&#039;</span> =&gt; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw3">array</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="st0">&#039;long_url&#039;</span> =&gt; string <span class="st0">&#039;http://site_name.domen/index.php?r=news/view&amp;amp;id=2&#039;</span> <span class="br0">&#40;</span>length=<span class="nu0">72</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="st0">&#039;url&#039;</span> =&gt; string <span class="st0">&#039;http://bit.ly/short_link&#039;</span> <span class="br0">&#40;</span>length=<span class="nu0">20</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="st0">&#039;hash&#039;</span> =&gt; string <span class="st0">&#039;c86mVl&#039;</span> <span class="br0">&#40;</span>length=<span class="nu0">6</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="st0">&#039;global_hash&#039;</span> =&gt; string <span class="st0">&#039;9mLuyJ&#039;</span> <span class="br0">&#40;</span>length=<span class="nu0">6</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; <span class="st0">&#039;new_hash&#039;</span> =&gt; int <span class="nu0">1</span></div>
</li>
</ol>
</div>
<p><strong>Шаг пятый. Добавляем код создания ссылки в контроллер.</strong></p>
<p>В случае с фреймворком Yii ссылку сокращать удобнее всего в методе <code>loadModel()</code> контроллера <code>News</code>, т.к. сразу после создания новости будет выполнен редирект на новую страницы и, соответственно, вызван метод <code>loadModel()</code>.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">public</span> <span class="kw2">function</span> loadModel<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;_model===<span class="kw2">null</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span><span class="kw3">isset</span><span class="br0">&#40;</span><span class="re0">$_GET</span><span class="br0">&#91;</span><span class="st0">&#039;id&#039;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;_model=News::<span class="me2">model</span><span class="br0">&#40;</span><span class="br0">&#41;</span>-&gt;<span class="me1">findbyPk</span><span class="br0">&#40;</span><span class="re0">$_GET</span><span class="br0">&#91;</span><span class="st0">&#039;id&#039;</span><span class="br0">&#93;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//проверяем, создана ли короткая ссылка для данной новости</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>!<span class="kw3">isset</span><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;_model-&gt;<span class="me1">n_short_url</span><span class="br0">&#41;</span> || <span class="re0">$this</span>-&gt;_model-&gt;<span class="me1">n_short_url</span> == <span class="st0">&#034;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//получаем адрес текущей страницы</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$request</span> = Yii::<span class="me2">app</span><span class="br0">&#40;</span><span class="br0">&#41;</span>-&gt;<span class="me1">getRequest</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$link</span> = <span class="re0">$request</span>-&gt;<span class="me1">getHostInfo</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="re0">$request</span>-&gt;<span class="me1">getUrl</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;_model-&gt;<span class="me1">n_short_url</span> = BitLyShortener::<span class="me2">getShortUrl</span><span class="br0">&#40;</span><span class="re0">$link</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//сохраняем короткую ссылку</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;_model-&gt;<span class="me1">save</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;_model===<span class="kw2">null</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw <span class="kw2">new</span> CHttpException<span class="br0">&#40;</span><span class="nu0">404</span>,<span class="st0">&#039;The requested page does not exist.&#039;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">return</span> <span class="re0">$this</span>-&gt;_model;</div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>Здесь мы проверяем, создана ли для данной записи короткая ссылка, и если нет – создаём её. Предварительно получаем <acronym title="Uniform Resource Locator">URL</acronym> текущей страницы. Затем, присваиваем короткую ссылку атрибуту <code>n_short_url</code> и сохраняем модель.</p>
<p>Таким образом, запрос на создание короткой ссылки будет отправляться только один раз для каждой страницы.</p>
<p>Вывести полученную ссылку можно точно так же, как и любой другой атрибут модели.</p>
<p>Вот и всё! Если у вас появились вопросы или есть замечания, пишите, обсудим <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p><strong>Интересно почитать</strong></p>
<p>Лучшие предложения на <a href="http://www.skladmetalla.ru/">металлопрокат в москве</a> на<br />
skladmetalla.ru  .</p>
<p>Уют и тепло ваше квартире дадут <a href="http://mc-140-500.ru/">чугунные радиаторы</a> для надежного отопления вашей квартиры.</p>
<p>Манго фитнес-центр и <a href="http://salonmango.ru/">салон красоты в цао</a>, все под одной крышей.</p><img src="http://www.simplecoding.org/?ak_action=api_record_view&id=1080&type=feed" alt="" /><img src="http://feeds.feedburner.com/~r/simplecoding/~4/654P_r_MFQQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/ispolzovanie-servisa-bit-ly-vmeste-s-php-frejmvorkom-yii.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>WordPress плагин для внутренней перелинковки страниц сайта. Версия 2.</title>
		<link>http://www.simplecoding.org/wordpress-plagin-dlya-vnutrennej-perelinkovki-stranic-sajta-versiya-2.html</link>
		<comments>http://www.simplecoding.org/wordpress-plagin-dlya-vnutrennej-perelinkovki-stranic-sajta-versiya-2.html#comments</comments>
		<pubDate>Wed, 02 Jun 2010 08:41:17 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[HTML]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web разработка]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/?p=1074</guid>
		<description><![CDATA[Приветствую!
Прежде всего, хочу поблагодарить всех, кто участвовал в обсуждении и тестировании моего плагина «Terms Descriptions». Вы подсказали мне несколько хороших идей, которые я реализовал в новой версии плагина.
Сразу даю ссылку на архив.

Новые возможности.

1) Изменились имена файлов и папки плагина. Поэтому перед обновлением необходимо деактивировать и удалить старую версию, а затем установить новую. Все ваши термины [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_1075" class="wp-caption alignnone" style="width: 310px"><img src="http://www.simplecoding.org/wp-content/uploads/2010/05/wp_terms_descriptions_2_logo.png" alt="wp terms descriptions 2" title="wp terms descriptions 2" width="300" height="250" class="size-full wp-image-1075" style="float:left" /><p class="wp-caption-text"> </p></div>
<p><strong>Приветствую!</strong></p>
<p>Прежде всего, хочу поблагодарить всех, кто участвовал в обсуждении и тестировании моего плагина «<a href="http://www.simplecoding.org/wordpress-plagin-dlya-vnutrennej-perelinkovki-stranic-sajta.html">Terms Descriptions</a>». Вы подсказали мне несколько хороших идей, которые я реализовал в новой версии плагина.</p>
<p>Сразу даю ссылку на архив.</p>
<p><a href='http://www.simplecoding.org/wp-content/uploads/2010/05/terms-descriptions.zip'><img src="http://www.simplecoding.org/wp-content/themes/three_cols/images/download_btn_blue.png" alt="архив с исходным кодом" /></a></p>
<p>Новые возможности.<br />
<span id="more-1074"></span><br />
<em>1) Изменились имена файлов и папки плагина.</em> Поэтому перед обновлением необходимо деактивировать и удалить старую версию, а затем установить новую. Все ваши термины и настройки сохранятся.</p>
<p>Если вы устанавливаете плагин в первый раз, просто распакуйте архив в папку <code>wp-content/plugins</code> и активируйте плагин в админке.</p>
<p><em>2) Добавлена возможность создавать ссылки не только на страницы блога, но и на посты.</em></p>
<p><em>3) Добавлена возможность ограничить количество замен терминов.</em> Например, если в поле «Преобразовывать первые &#8230; терминов» установить значение равное трём, ссылки будут поставлены на первые три термина. Если вы не хотите использовать это ограничение, установите в этом поле значение «-1».</p>
<p>Обратите внимание, что термины в постах и комментариях подсчитываются отдельно.</p>
<p><em>4) Теперь плагин сверяет id страницы (поста) на которую ведёт ссылка и id текущей страницы (поста). Если они равны, то ссылка не ставится.</em></p>
<p>Например, у вас есть два термина: <code>php</code> и <code>mysql</code>. Ссылка для первого установлена на страницу <code>myblog.domen/php.html</code>, для второго – на <code>myblog.domen/mysql.html</code>. На странице <code>myblog.domen/php.html</code> встречаются оба термина (и <code>php</code>, и <code>mysql</code>), но только <code>mysql</code> будет преобразован в ссылку, т.к. ссылка для термина <code>php</code> указывает на текущую страницу.</p>
<p>Взгляните на скриншот админки.</p>
<div id="attachment_1078" class="wp-caption alignnone" style="width: 460px"><a href="http://www.simplecoding.org/wp-content/uploads/2010/05/terms_descriptions_2_admin.png" target="_blank"><img src="http://www.simplecoding.org/wp-content/uploads/2010/05/terms_descriptions_2_admin_thumb.png" alt="terms descriptions 2 admin thumb" title="terms descriptions 2 admin thumb" width="450" height="290" class="size-full wp-image-1078" /></a><p class="wp-caption-text"> </p></div>
<p>Думаю, вы легко определите, где какие параметры нужно указывать <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>И, как всегда, буду рад выслушать ваши замечания и пожелания!</p>
<p><strong>UPD 23.06.2010</strong> Я сделал <a href="http://www.simplecoding.org/plagin-wordpress-terms-descriptions">отдельную страницу</a> для этого плагина, теперь все новые версии будут выкладываться там.</p>
<p><strong>Интересно почитать</strong></p>
<p>Новая модель: <a href="http://www.onyx-inter.ru/bankovskaya-telezhka-onyx.html ">банковская тележка для перевозки денег</a> отечественной разработки.</p><img src="http://www.simplecoding.org/?ak_action=api_record_view&id=1074&type=feed" alt="" /><img src="http://feeds.feedburner.com/~r/simplecoding/~4/Y3Br5VkN6CY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/wordpress-plagin-dlya-vnutrennej-perelinkovki-stranic-sajta-versiya-2.html/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Ограничения фреймворков (на примере Yii)</title>
		<link>http://www.simplecoding.org/ogranicheniya-frejmvorkov-na-primere-yii.html</link>
		<comments>http://www.simplecoding.org/ogranicheniya-frejmvorkov-na-primere-yii.html#comments</comments>
		<pubDate>Mon, 31 May 2010 13:38:04 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web разработка]]></category>
		<category><![CDATA[Yii]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/?p=1073</guid>
		<description><![CDATA[О том, что фреймворки позволяют сократить время разработки, знают все. Но иногда при этом появляются самые неожиданные ограничения.
По-идее, так и должно быть. Каким бы универсальным не пытались сделать фреймворк разработчики, всегда чем-то приходится жертвовать. Точнее искать компромисс между количеством кода, который должен написать пользователь и гибкостью.
В этой статье я хочу показать пример такой ситуации, и, [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_1061" class="wp-caption alignnone" style="width: 281px"><img src="http://www.simplecoding.org/wp-content/uploads/2010/05/yii_php_framework_autocomplete.png" alt="yii php framework autocomplete" title="yii php framework autocomplete" width="271" height="166" class="size-full wp-image-1061" style="float:left" /><p class="wp-caption-text"> </p></div>
<p>О том, что фреймворки позволяют сократить время разработки, знают все. Но иногда при этом появляются самые неожиданные ограничения.</p>
<p>По-идее, так и должно быть. Каким бы универсальным не пытались сделать фреймворк разработчики, всегда чем-то приходится жертвовать. Точнее искать компромисс между количеством кода, который должен написать пользователь и гибкостью.</p>
<p>В этой статье я хочу показать пример такой ситуации, и, естественно, её решение.<br />
<span id="more-1073"></span></p>
<p><strong>UPD</strong>: <em>Более удачное решение данной проблемы приведено в комментариях.</em></p>
<p>Не так давно я опубликовал статью <a href="http://www.simplecoding.org/yii-php-frejmvork-sozdaem-pole-s-avtozapolneniem.html">Yii <acronym title="PHP: Hypertext Preprocessor">PHP</acronym> фреймворк: создаем поле с автозаполнением</a>, в которой рассказывал об использовании виджета <a href="http://www.yiiframework.com/doc/api/CAutoComplete">CAutoComplete</a>.</p>
<p><strong>Алгоритм его работы</strong> довольно прост.</p>
<p>1) Создать текстовое поле (тег <code>input</code>).<br />
2) Подключить плагин jQuery <a href="http://plugins.jquery.com/project/autocompletex">Autocomplete</a> и файлы <acronym title="Cascading Style Sheets">CSS</acronym> стилей.<br />
3) Подключить плагин к текстовому полю.</p>
<p>При этом, все настройки виджета <code>CAutoComplete</code> задаются при его подключении в <strong><acronym title="PHP: Hypertext Preprocessor">PHP</acronym></strong> массиве.</p>
<p>Т.к. основную работу выполняет <strong>Autocomplete</strong>, то логично было бы предположить, что в настройках виджета можно задать все параметры этого плагина. Для большинства параметров, так оно и есть, но с параметром <code>extraParams</code> возникли проблемы.</p>
<p>В документации сказано.</p>
<blockquote><p>Extra parameters for the backend. If you were to specify <code>{bar:4}</code>, the autocompleter would call <code>my_autocomplete_backend.php?q=foo&#038;bar=4</code> (assuming the input box contains &#034;foo&#034;). The param can be a function that is called to calculate the param before each request.</p></blockquote>
<blockquote><p>Дополнительный параметр для бэкенда. Если вы указали <code>{bar:4}</code>, плагин отправит запрос <code>my_autocomplete_backend.php?q=foo&#038;bar=4</code> (предполагается, что текстовое поле содержит текст &#034;foo&#034;). Параметр может быть функцией, которая вызывается чтобы рассчитать значение параметра перед отправкой каждого запроса.</p></blockquote>
<p>Т.е. вы можете задать настройки для <code>CAutoComplete</code> следующим образом.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1">$this-&gt;widget(&#039;CAutoComplete&#039;,
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp;array(
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#039;extraParams&#039;=&gt;array(&#039;mypar&#039;=&gt;&#039;myval&#039;),
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#039;url&#039;=&gt;array(&#039;countries/autocomplete&#039;),
</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp;)
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;);</div>
</li>
</ol>
</div>
<p>И такой вариант будет работать.</p>
<p>Но если вы захотите использовать в качестве значения функцию, например</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="st0">&#039;extraParams&#039;</span>=&gt;array<span class="br0">&#40;</span><span class="st0">&#039;mypar&#039;</span>=&gt;<span class="st0">&#039;function() {return $(&quot;#myselect&quot;).val();}&#039;</span><span class="br0">&#41;</span>,</div>
</li>
</ol>
</div>
<p>то этот <acronym title="JavaScript">JS</acronym> код выполняться не будет.</p>
<p><em>Примечание</em>. Показанная здесь функция возвращает значение из выпадающего списка (<code>myselect</code>).</p>
<p>Дело в том, что функция передается в виде стоки (в кавычках) и <acronym title="JavaScript">JS</acronym> код при этом, естественно, не выполняется.</p>
<p><strong>Решить проблему</strong> можно так.</p>
<p>1) Создаём js файл с таким кодом.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1">jQuery<span class="br0">&#40;</span><span class="st0">&quot;#country&quot;</span><span class="br0">&#41;</span>.<span class="me1">setOptions</span><span class="br0">&#40;</span><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="st0">&#039;extraParams&#039;</span>:<span class="br0">&#123;</span><span class="st0">&#039;mypar&#039;</span>:<span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><span class="kw1">return</span> $<span class="br0">&#40;</span><span class="st0">&quot;#myselect&quot;</span><span class="br0">&#41;</span>.<span class="me1">val</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<span class="br0">&#125;</span><span class="br0">&#125;</span><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#41;</span>;</div>
</li>
</ol>
</div>
<p>2) Подключаем его к нужной странице.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="re0">$cs</span> = Yii::<span class="me2">app</span><span class="br0">&#40;</span><span class="br0">&#41;</span>-&gt;<span class="me1">clientScript</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$cs</span>-&gt;<span class="me1">registerScriptFile</span><span class="br0">&#40;</span>Yii::<span class="me2">app</span><span class="br0">&#40;</span><span class="br0">&#41;</span>-&gt;<span class="me1">request</span>-&gt;<span class="me1">baseUrl</span>.<span class="st0">&#039;/js/autocomplete_config.js&#039;</span>, CClientScript::<span class="me2">POS_END</span><span class="br0">&#41;</span>;</div>
</li>
</ol>
</div>
<p>Здесь <code>autocomplete_config.js</code> – название вашего скрипта.</p>
<p>Как видите, решение достаточно простое, но не очень красивое. Часть настроек виджета будет задана в <acronym title="PHP: Hypertext Preprocessor">PHP</acronym> файле, часть в <acronym title="JavaScript">JS</acronym>.</p>
<p>Если вы знаете более удачные варианты, буду рад выслушать и обсудить <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>До встречи!</p>
<p><strong>Интересно почитать</strong></p>
<p>Удобный и недорогой <a href="http://www.onyx-inter.ru/stol-i-tumba-kassira-onyx.html ">стол для кассы</a> отечественной разработки</p><img src="http://www.simplecoding.org/?ak_action=api_record_view&id=1073&type=feed" alt="" /><img src="http://feeds.feedburner.com/~r/simplecoding/~4/pPL3TsDGvVo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/ogranicheniya-frejmvorkov-na-primere-yii.html/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Создание файлов переводов для плагинов и тем WordPress</title>
		<link>http://www.simplecoding.org/sozdanie-fajlov-perevodov-dlya-plaginov-i-tem-wordpress.html</link>
		<comments>http://www.simplecoding.org/sozdanie-fajlov-perevodov-dlya-plaginov-i-tem-wordpress.html#comments</comments>
		<pubDate>Sat, 29 May 2010 10:37:36 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web разработка]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/?p=1067</guid>
		<description><![CDATA[Всегда приятно, когда можно без особых усилий перевести плагин или тему для движка WordPress на свой язык. Под «особыми усилиями» я подразумеваю необходимость ковыряться в исходных файлах.
WordPress предоставляет механизм для работы с файлами переводов, который, по-идее, должен использовать каждый разработчик. Если, конечно, он хочет распространять свою работу.
В этой статье я постараюсь рассказать о создании и [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_1068" class="wp-caption alignnone" style="width: 269px"><img src="http://www.simplecoding.org/wp-content/uploads/2010/05/wp_translations_logo.png" alt="wp translations logo" title="wp translations logo" width="259" height="124" style="float:left" class="size-full wp-image-1068" /><p class="wp-caption-text"> </p></div>
<p>Всегда приятно, когда можно без особых усилий перевести плагин или тему для движка WordPress на свой язык. Под «особыми усилиями» я подразумеваю необходимость ковыряться в исходных файлах.</p>
<p><strong>WordPress</strong> предоставляет механизм для работы с файлами переводов, который, по-идее, должен использовать каждый разработчик. Если, конечно, он хочет распространять свою работу.</p>
<p>В этой статье я постараюсь рассказать о создании и использовании файлов переводов, а также о программах, которые позволяют упростить работу.</p>
<p><strong>Шаг первый. Определяем, какие строки нужно перевести.</strong><br />
<span id="more-1067"></span><br />
Для этого, в исходных файлах плагина или темы все текстовые строки, которые нужно перевести, помещаем внутрь функций: </p>
<p><code>_e()</code> – выводит (<code>echo</code>) текст;<br />
<code>__()</code> – возвращает (<code>return</code>) текст;<br />
<code>_n()</code> – позволяет работать с единственным и множественным числом;<br />
<code>_x()</code> – работает аналогично <code>__()</code>, но имеет дополнительный параметр – контекст.</p>
<p>Подробно их использование описано в статье <a href="http://codex.wordpress.org/I18n_for_WordPress_Developers">I18n for WordPress Developers</a>. Повторять их примеры я не буду, но советую обратить внимание на два момента.</p>
<p>1) Очень желательно использовать второй параметр в этих функцих (<code>domain</code>). Для плагинов обычно используют название плагина, для темы &#8211; название папки в которой она расположена (а вообще, подойдет любая уникальная строка).</p>
<p>2) Символы окончания строк (<acronym title="End of line">EOL</acronym>) должны быть в Unix-формате, т.е. <code>\n</code>, а не <code>\r\n</code>, как принято в windows. Иначе могут быть проблемы при использовании утилиты <strong>gettext</strong>. Большинство редакторов вроде notepad++ позволяют легко заменить окончания.</p>
<p><strong>Шаг второй. Создаём файлы переводов.</strong></p>
<p>Тут вам нужно сначала создать <code>.po</code> файлы, в которых будут находиться оригинальные строки и переводы, а затем, скомпилировать их в <code>.mo</code> файлы, с которыми работает WordPress.</p>
<p>Вообще для этих целей предназначена утилита <a href="http://www.gnu.org/software/gettext/">gettext</a>, но она консольная и пользоваться ей не очень удобно.</p>
<p>Гораздо приятнее работать с программой <a href="http://www.poedit.net/">Poedit</a>, т.к. она сделает все рутинные операции за вас.</p>
<p>При её первом запуске желательно сразу указать личные данные (Меню Файл -&gt; Установки), т.к. они сохраняются в файлах переводов.</p>
<div id="attachment_1069" class="wp-caption alignnone" style="width: 473px"><img src="http://www.simplecoding.org/wp-content/uploads/2010/05/poedit_options.png" alt="poedit options" title="poedit options" width="463" height="515" class="size-full wp-image-1069" /><p class="wp-caption-text"> </p></div>
<p>После этого можно приступать к <strong>созданию файлов переводов</strong>.</p>
<p>Заходим в меню Файл -&gt; Создать каталог и в открывшемся окне внимательно заполняем настройки.</p>
<p><em>Общие данные о проекте</em></p>
<div id="attachment_1070" class="wp-caption alignnone" style="width: 421px"><img src="http://www.simplecoding.org/wp-content/uploads/2010/05/poedit_project_options.png" alt="poedit project options" title="poedit project options" width="411" height="344" class="size-full wp-image-1070" /><p class="wp-caption-text"> </p></div>
<p>Тут всё довольно просто, главное не ошибиться с кодировкой.</p>
<p><em>Вкладка «Путь»</em>. Тут нужно указать путь к папке плагина или темы.</p>
<div id="attachment_1071" class="wp-caption alignnone" style="width: 422px"><img src="http://www.simplecoding.org/wp-content/uploads/2010/05/poedit_project_options_2.png" alt="poedit project options 2" title="poedit project options 2" width="412" height="344" class="size-full wp-image-1071" /><p class="wp-caption-text"> </p></div>
<p><strong>PoEdit</strong> будет просматривать файлы в этих папках и выбирать строки, которые нужно перевести.</p>
<p><em>Вкладка «Ключевые слова»</em>. Это важный момент. Тут нужно перечислить название функций, которые вы использовали для перевода строк. Без скобок!!!</p>
<div id="attachment_1072" class="wp-caption alignnone" style="width: 421px"><img src="http://www.simplecoding.org/wp-content/uploads/2010/05/poedit_project_options_3.png" alt="poedit project options 3" title="poedit project options 3" width="411" height="344" class="size-full wp-image-1072" /><p class="wp-caption-text"> </p></div>
<p>После этого, программа импортирует строки из файлов с исходым кодом.</p>
<p>Если строки нужно обновить, выбираем в меню &#034;Каталог&#034; пункт &#034;Обновить из исходного кода&#034;.</p>
<p>После импорта строк <strong>можно приступать к переводу</strong>.</p>
<p>Сам перевод особой сложности не представляет. Если, конечно, вы хорошо знаете язык <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  Выбираете строку и пишите в нижней части экрана перевод для неё.</p>
<p><strong>Сохраняем файл</strong>. Poedit автоматически создает два файла .po и .mo.</p>
<p>Важный момент &#8211; <em>имя файла</em>.</p>
<p>Обычно формируется следующим образом</p>
<p><code>pluginname-locale.po<br />
pluginname-locale.mo</code></p>
<p>Например<br />
<code>termdescription-ru_RU.mo</code></p>
<p><strong>Шаг третий. Загружаем файлы переводов в плагине.</strong></p>
<p>Для этого можно использовать следующий код.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">function</span> myplugin_init<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">…</div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$plugin_dir</span> = <span class="kw3">basename</span><span class="br0">&#40;</span><span class="kw3">dirname</span><span class="br0">&#40;</span><span class="kw2">__FILE__</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">load_plugin_textdomain<span class="br0">&#40;</span> <span class="re0">$domain</span>, <span class="st0">&#039;/wp-content/plugins/&#039;</span>.<span class="re0">$plugin_dir</span>, <span class="re0">$plugin_dir</span> <span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">…</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>Тут предполагается, что плагин и файлы переводов находятся в папке <code>pluginname</code>.</p>
<p>Этот код должен быть вызван при инициализации плагина. Например, в функции, которая вызывается действием <code>init</code> или <code>admin_init</code> (если переводы нужны только для админки)</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1">add_action<span class="br0">&#40;</span> <span class="st0">&#039;init&#039;</span>, <span class="st0">&#039;myplugin_init&#039;</span> <span class="br0">&#41;</span>;</div>
</li>
</ol>
</div>
<p>В случае с темами, подключение файлов переводов немного проще. В файл <code>functions.php</code> добавьте вызов</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1">load_theme_textdomain<span class="br0">&#40;</span>domain-name<span class="br0">&#41;</span>;</div>
</li>
</ol>
</div>
<p>Имя файла при этом должно иметь вид:</p>
<p><code>locale.mo</code></p>
<p>например, <code>ru_RU.mo</code>. И находиться он должен в папке с темой.</p>
<p><strong>Шаг четвёртый. Выбор файла перевода.</strong></p>
<p>WordPress должен определить, какой именно перевод использовать. Указать это можно в настройках блога (файл wp-config.php). Найдите строку в которой определена константа WPLANG и установите нужное значение.</p>
<p>Например, так</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw3">define</span> <span class="br0">&#40;</span><span class="st0">&#039;WPLANG&#039;</span>, <span class="st0">&#039;ru_RU&#039;</span><span class="br0">&#41;</span>;</div>
</li>
</ol>
</div>
<p>Если у вас возникли вопросы или замечания, пишите, постараюсь ответить.</p>
<p>Удачи!</p>
<p><strong>Интересно почитать</strong></p>
<p>Как установить и настроить <a href="http://www.getwifi.ru/">wifi сеть</a> в вашем доме.</p>
<p>Банкам и службам инкассации: <a href="http://www.onyx-inter.ru/1-3.html">инкассаторские сумки собственной разработки</a>, возможна печать вашего логотипа</p><img src="http://www.simplecoding.org/?ak_action=api_record_view&id=1067&type=feed" alt="" /><img src="http://feeds.feedburner.com/~r/simplecoding/~4/TQ4dWNy2LeU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/sozdanie-fajlov-perevodov-dlya-plaginov-i-tem-wordpress.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
