четверг, 27 декабря 2012 г.

Zend Router

resources.router.routes.news.type = "Zend_Controller_Router_Route_Regex"
resources.router.routes.news.route = "news/(.*)\.html"
resources.router.routes.news.defaults.controller= "news"
resources.router.routes.news.defaults.action= "index"
resources.router.routes.news.defaults.name = "none"
resources.router.routes.news.map.1 = "name"
resources.router.routes.news.reverse = "news/%s.html"

разберем построчно
с 1ой строкой все понятно;
во 2ой задается регулярное выражение;
3,4,5 настройка контроллера, экшена и значения переменной name по умолчанию;
6 (предпоследняя) маппинг параметров у нас здесь один параметр и он будет присвоен переменной name;
7ая строка при генерации ссылок через вью хэлпер url будет использоватся это выражение.
 







resources.router.routes.id.type = "Zend_Controller_Router_Route_Regex"
resources.router.routes.id.route = "articles/(\w+)"
resources.router.routes.id.defaults.module = default
resources.router.routes.id.defaults.controller = articles
resources.router.routes.id.defaults.action = id
resources.router.routes.id.map.1 = "id"
resources.router.routes.id.reverse = "articles/%s"
Вы укажете Zend Framework при переходе на страницу типа articles/5 определить 5 как id.
Получить значение Вы можете розместив в action:


$this->getRequest()->getParam('id');
Zend router можно реализовать и в другом формате:








resources.router.routes.articles.type = "Zend_Controller_Router_Route_Regex"
resources.router.routes.articles.route = "articles/tag/(\w+)"
resources.router.routes.articles.defaults.module = default
resources.router.routes.articles.defaults.controller = articles
resources.router.routes.articles.defaults.action = tag
resources.router.routes.articles.map.1 = "tag"
resources.router.routes.articles.reverse = "articles/tag/%s"
Тут, соотвественно, данные будут в articles/tag/zend.
 

пятница, 23 ноября 2012 г.

пятница, 16 ноября 2012 г.

Перенос сайта WordPress на новый домен

14 октября 2007 г. Главная WordPress
Иногда может возникнуть ситуация, когда необходимо сайт, работающий на движке WordPress, перенести на новый домен. Т.е. суть данного действа заключается только в изменении имени домена, все содержимое же, равно как и структура ссылок, остается прежним. При этом не маловажный момент - сохранение показателей тИЦ и PR.
К данному вопросу необходимо подходить с полным пониманием дела, ибо обратное может быть чревато неприятными последствиями.

среда, 18 июля 2012 г.

Особенности работы jQuery.live()

На работе столкнулись с “особенностью” работы jQuery.live(), на которую хотелось бы обратить внимание, потому как, судя по всему, отнюдь не все о ней знают (и в результате чего пишут неработающий код).
Итак, простой пример - навешивание двух событий на один и тот же элемент:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
  <meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
  <title>jQuery.live() test pagetitle>
  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js">script>
  <script type="text/javascript">
  jQuery(function() {
    $("a").bind("click", function(e) {
      alert("a");
      return false;
    });
    $("a").bind("click", function(e) {
      alert("b");
      return false;
    });
  });
  script>
head>
<body>
  <a href="http://blog.fxposter.org/">Блог FX-аa>
body>
html>
Пример можно посмотреть здесь. В результате клика на ссылку - получаем 2 alert-а, всё хорошо, ожидаемо и предсказуемо.
Переписываем код для работы с jQuery.live(). Для тех, кто в танке - live() вешает событие не на сам элемент, а на document. В результате bubbling-а событие, которое произошло над каким-либо элементом поднимается вверх по DOM-дереву и соответственно вызывает обработчики всех элементов, которые оно встретит. Если вы и этого не знали - то вам не нужно читать мой блог, а пора идти и покупать книгу по JavaScript-у (мне, кстати, тоже давно пора, но всё никак не соберусь). Итак, в конце концов событие доходит до document-а и обработчики вызываются у него. Обработчик, который устанавливает jQuery.live() проверяет - соответствует ли event.target (а именно здесь хранится обьект DOM-дерева, с которым произошло событие) соответствующему селектору (в данном случае - это селектор “a”) и если соответствует - то выполняет обработчик.
Преимущества и недостатки - это тема отдельной статьи. Если не уклонятся в сторону оптимизации, то основным преимуществом, на мой взгляд, является тот факт, что обработчики, навешенные live()-ом будут запускаться даже для элементов, которые были динамически добавлены на страницу, в отличии от bind()-обработчиков, которые на эти элементы нужно будет навешивать вручную (если непонятно, почему это работает именно так - читаем предыдущий абзац, если все равно непонятно - идем покупать всё ту же книгу).
Далее - зачем нужен “return false” в конце обработчика? Он предотвращает от того, чтобы вызывалось действие по умолчанию (в данном случае - переход по ссылке и событие не поднималось выше). Чаще всего JS-разработчики вообще не думают о bubbling-е и под “return false” понимают только “отмену действия по умолчанию”, ну или они вообще не знают, что именно происходит и пишут “return false”, потому что так работает.
Такое отношение jQuery частенько прощает. Но не в случае с live()-методом. Попробуем запустить следующий пример:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
  <meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
  <title>jQuery.live() test pagetitle>
  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js">script>
  <script type="text/javascript">
  jQuery(function() {
    $("a").live("click", function(e) {
      alert("a");
      return false;
    });
    $("a").live("click", function(e) {
      alert("b");
      return false;
    });
  });
  script>
head>
<body>
  <a href="http://blog.fxposter.org/">Блог FX-аa>
body>
html>
В результате клика теперь выскакивает только один alert. Пора обратится к документации:
# To stop further handlers from executing after one bound using .live(), the handler must return false. Calling .stopPropagation() will not accomplish this.
Хаха. В данном случае jQuery интерпретирует false “несколько иначе”. :)
Для того, чтобы “пофиксить” подобный баг нужно обратится все к тому же bubbling-у и обработке событий и сделать именно то, что предполагается разработчиком - “отменить действие по умолчанию”. Это делается с помощью метода event.preventDefault() (пример):

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
  <meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
  <title>jQuery.live() test pagetitle>
  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js">script>
  <script type="text/javascript">
  jQuery(function() {
    $("a").live("click", function(e) {
      alert("a");
      e.preventDefault();
    });
    $("a").live("click", function(e) {
      alert("b");
      e.preventDefault();
    });
  });
  script>
head>
<body>
  <a href="http://blog.fxposter.org/">Блог FX-аa>
body>
html>
И самое главное (барабанная дробь!) - при использовании bind() для навешивания обработчиков preventDefault() тоже можно использовать!
Наткнулись мы на эту “фичу”, когда у нас почему-то перестали вызываться некоторые обработчики
Напоследок, замечу еще одно - элемент, на который навешено хотя бы один обработчик события через bind() с “правильно работающим return false”, никогда не будет вызывать никакие live()-события. ;)

Источник

суббота, 30 июня 2012 г.

Ошибка при индексировании в Magento

Несколько способов для решения этой проблемы:

Для начало попробуем  через консоль в ручном режиме проиндексировать базу:
First, try to set the index mode to manual:
php indexer.php --mode-manual catalog_product_attribute
php indexer.php --mode-manual catalog_product_price
php indexer.php --mode-manual catalog_url
php indexer.php --mode-manual catalog_product_flat
php indexer.php --mode-manual catalog_category_flat
php indexer.php --mode-manual catalog_category_product
php indexer.php --mode-manual catalogsearch_fulltext
php indexer.php --mode-manual cataloginventory_stock
php indexer.php --mode-manual tag_summary
Then, try to reindex all indexes:
php indexer.php reindexall
And set the mode to realtime again:
php indexer.php --mode-realtime catalog_product_attribute
php indexer.php --mode-realtime catalog_product_price
php indexer.php --mode-realtime catalog_url
php indexer.php --mode-realtime catalog_product_flat
php indexer.php --mode-realtime catalog_category_flat
php indexer.php --mode-realtime catalog_category_product
php indexer.php --mode-realtime catalogsearch_fulltext
php indexer.php --mode-realtime cataloginventory_stock
php indexer.php --mode-realtime tag_summary


среда, 13 июня 2012 г.

Масштабируемые JavaScript приложения

Более месяца назад в статье FAQ по JavaScript: задавайте вопросы был задан вопрос «Подскажите примеры хорошего подхода организации JS кода к сайту на достаточно высоком уровне. Как можно узнать подробнее практики реализации например gmail?».

Пришло время ответить на данный вопрос. Я немного затянул т.к. хотел рассказать доклад на одноименную тему на Я.Субботнике. Доклад был очень коротким многие важные моменты пришлось выкинуть. Статья — более-менее полная версия.

Эта статья о том, как сделать крупное веб-приложение расширяемым и поддерживаемым: архитектура, подходы, правила.

Практический пример использования Backbone

В данной заметке речь пойдет об использовании Backbone, а в частности, примеры кода работающего с сервером.
       Это должен быть некий промежуточный пункт в блужданиях Ищущего, так как иначе начать им пользоваться очень сложно, а вероятность отказаться от идеи перехода стремится к единице.


пятница, 8 июня 2012 г.

Вертикальное выравнивание блока

Требования
— Должна быть известна начальная высота родительского блока;
— Дочерний блок может иметь произвольный размер как по высоте, так и по ширине.

Возможности
— Работает в IE6+, O9+, FF2+, webkit;
— Тру vertical-align выравнивание со всеми допустимыми значениями;
— Одинаковое поведение во всех браузерах (незначительные отклонение при некоторых условиях в ие6 будут оговорены ниже);
— При вырастании дочернего блока выше «папочки», родительский блок расширяется;
— Ни грамма JavaScript.

воскресенье, 20 мая 2012 г.

ZendFramework используем Registry


Сейчас мы рассмотрим, как в ZF можно организовать удобный и быстрый доступ к константам из секции файла application.ini.

Для начала зададим несколько констант:




[constants]
paths.photo = "/photo/"
paths.uploads = "/uploads/"
paths.video = "/video/"
secret_code = «key_for_check»

пятница, 18 мая 2012 г.

Mercurial + Rhodecode + Redmine


Встречаются предприятия, на которых доступ к интернету сильно ограничен или не постоянен, не завидую этим ребятам. Иногда, как в моём случае, политика безопасности предприятия не позволяет хранить исходный код разрабатываемых продуктов на чужом оборудовании. Кроме того, смею предположить, что не каждой группе разработчиков хватает возможностей, предоставляемых например bitbucket. Эти проблемы можно решить, к примеру, связкой RhodeCode и Redmine.

пятница, 17 февраля 2012 г.

CSS файлы Magento

В в папке с темой по умолчанию расположенной по адресу  /skin/frontend/default/default лежит папка  css.
В этой папке находятся файлы стилей, по умолчанию их семь.
  • boxes.css
  • clears.css
  • ie7minus.css
  • iestyles.css
  • menu.css
  • print.css
  • reset.css
     

среда, 15 февраля 2012 г.

Редактирование Excel-файлов с помощью PHPExcel

Уже натасканный программист, который привык не принимать все на веру, а всегда проверять то, что ему подсовывают, тут же задаст вопрос, который указан в заголовке этого абзаца.
На что более матерый программист ему даст следующие пояснения. Когда заказчик хочет сделать экспорт в Excel, то это наверняка делается для автоматизации каких-либо процессов, скорее всего бухгалтерских. У заказчика наверняка есть примеры таблиц, в которые нужно сделать экспорт. Не переводить же все стили, шрифты и формулы ячеек в код.
Можно просто очистить таблицы от всех данных и использовать таблицу, полученную от заказчика в качестве шаблона. Зачастую именно для этого используется чтение таблиц.