среда, 14 декабря 2011 г.

Простая установка RVM, Rails3 в Linux

Установка последней версии rails с использованием Ruby Version Manager (RVM):

$ bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)
$ echo '[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm" # Load RVM function' >> ~/.bash_profile
$ source ~/.bash_profile
$ rvm install 1.9.2
$ rvm use 1.9.2 --default
$ ruby -v
ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-linux]
$ gem install rails
$ rails -v
Rails 3.1.3


проверял на Linux Mint 11

четверг, 22 сентября 2011 г.

jQuery.css(display:'none') vs jQuery.hide()

Меня заинтересовал вопрос: какой метод быстрее скрывает элемент на страничке(и востанавливает)
$(container).css('display', 'none') или $(container).hide()

Нашел замечательный сайт http://jsperf.com/jquery-css-display-none-vs-hide/2, на котором проводится тестирование всех возможных способов спрятать элемент под разными браузерами. Вы можете сами запустить тесты или просмотреть уже готовые результаты.

Быстрее: $(container).css("display", "none");
ну а на низком уровне (без jQuery) будет намного быстрее: document.getElementById("hide-me").style.display = "none";

вторник, 20 сентября 2011 г.

jQuery. Исключающий фильтр :not

Постановка задачи: необходимо выбрать все элементы "li" у которых отсутствует класс "test":
  items = $("li:not(.test)");
  //или:
  items = $("li").not(".test")

  //Вывод результата:
  console.log('Items:', items);

Основное применение - исключить по селектору нежелательные вхождения из результирующего набора выборки.

Ссылка на статью в официальной документации: http://api.jquery.com/not/

Для противоположной задачи - уточнить результаты выборки - существует метод .filter() (http://api.jquery.com/filter/). Я опишу его в следующей статье.

пятница, 9 сентября 2011 г.

jQuery. Особенности использования .parent(), .parents(), .closest(), .siblings()

Для того чтобы найти родительский элемент(ы) выбранного узла, можно пользоваться похожими методами: .parent(), .parents(), .closest(). Для поиска соседних узлов пользуются .siblings().

Рассмотрим различия между ними:

Первый метод .parent([selector]) -  находит родителя строго на один уровень вверх.
Пример: $(this).parent()

Для того чтобы получить родителя от родителя нужно применять цепочку вызовов (произвольной глубины): $(this).parent().parent()....

Второй метод .parents([selector])  - возвращает список всех родительских узлов, и,  может содержать селектор, для уточнения набора родителей. 
Пример: $(this).parents("li.test")

Третий метод .closest(selector, [context]) - возвращает первый ближайший родительский узел или же текущий узел - которые удовлетворяют условию в селекторе (селектор обязательный). Может принимать контекст для уточнения поиска (набор узлов заранее выбранных).
Основные отличия его от .parents():
    - может вернуть и текущий узел
    - обязательный селектор
   - возвращает только первый элемент который попал под условие, поиск ведется тоже вверх по дереву.
Пример: $(this).closest("li.test") или $(this).closest("li.test", itemsList)

Ну и наконец последний метод .siblings([selector]) - возвращает набор соседних узлов (тех, которые имеют того же родителя что и текущий), может принимать уточняющий селектор.
Пример: $("ul li#id1").siblings()

пятница, 26 августа 2011 г.

jQuery. Проверить видимость элемента на странице (видимый/невидимый)

Для того чтобы проверить видимый элемент или нет, можно воспользоваться двумя способами:

Допустим, у нас есть скрытый элемент с id="test":
$("#test").is(":visible") => false
или:
$("#test").is(":hidden")  => true

вторник, 23 августа 2011 г.

Перевод документации по jQuery

Представляю вашему вниманию ресурс, который содержит перевод документации jQuery с примерами: jQuery page2page

Ресурс также предоставляет интересные решения типовых задач (рецептов).

Если есть желание поучаствовать, детальнее читать тут

среда, 17 августа 2011 г.

Сравнение языковых конструкций PHP, Perl, Python, Ruby

Предлагаю вашему вниманию статью, в которой в удобной табличной форме представлены особенности реализации конструкций языков (таких как циклы, условные операторы, логические операторы, и многие другие) для PHP, Perl, Python, Ruby.

Будет очень полезно для сравнения языков и для тех, кто зная несколько из выше перечисленных языков - хочет быстро сориентироваться в другом.

Scripting Languages: PHP, Perl, Python, Ruby

понедельник, 15 августа 2011 г.

JavaScript. Получить длину строки в байтах

Мне потребовалась функция подсчета количества байтов в строке (в UTF8 разные символы имеют длину от 1 до 6 байтов). Как источник - использовал статью на Википедии: UTF-8, там я подсмотрел в таблицу, в которой указано сколько байтов занимает символ, в зависимости от порядкового номера. Потом расширил стандартный класс String - новой удобной функцией, которая, корректно находит длину строки в байтах, а не символах:
String.prototype.byteLength = function(){
   var str = this, length = str.length, count = 0, i = 0, ch = 0;
   for(i; i < length; i++){
     ch = str.charCodeAt(i);
     if(ch <= 127){
        count++;
     }else if(ch <= 2047){
        count += 2;
     }else if(ch <= 65535){
        count += 3;
     }else if(ch <= 2097151){
        count += 4;
     }else if(ch <= 67108863){
        count += 5;
     }else{
        count += 6;
     }    
  }
  return count;
};
Пример использования:
var str = "Строка";
console.log('Length: ', str.byteLength(), ' byte(s)');
А можно поступить проще:
var str = "Строка";
count = unescape(encodeURIComponent(str)).length

четверг, 11 августа 2011 г.

Купить читалку Kindle 3 в Украине

Хочу купить Kindle 3, но не хочу заказывать на Amazon (стремно с карты снимать лимиты для платежа зарубеж).

 Подсказали интернет-магазин в Киеве: http://pro-store.kiev.ua/, цены вроде без накрутки совершенно:
 Amazon Kindle 3 Wi-Fi+3G - 1576 грн.
 Amazon Kindle 3 Wi-Fi - 1352 грн.
 Amazon Kindle 3 Wi-Fi Special Edition (модель с рекламой) - 1224 грн.

Габариты посылки для Киндле 3 Wi-Fi: 1.10 lbs (0.5 kg) 10"×9"×3" (26×23×8 cm)

Оплата или через Укрсоцбанк или при получении через "Новая почта"

Стоимость доставки пробовал вычислить используя спец. сервис "Новой почтой", зная габариты посылки, получилось для меня (в Черкассы) около 50 грн. (посмотрим ;) )

На следующей неделе закажу, отпишу сколько обошлась доставка Киев-Черкассы (если не передумаю и не закажу таки на Амазоне).

среда, 10 августа 2011 г.

JavaScript. Простой шаблонизатор

Когда работаешь с JavaScript, то приходиться часто работать с DOM страницы. Есть задачи, когда нужно вставить в какой-то узел документа - кусочек готового шаблона с подстановкой в него данных. Самым простым вариантом будет склейка готового текста из кусочков, например:
var classname = "myclass";
var value = "test";
var content = "
  • "+value+"
    "+"
  • "; $("#div_id").append(content);

    Но это не совсем удобно, особенно если "склеивать" большое количество частей. jQuery 1.6.x предлагает свой шаблонизатор, но он пока в бета-версии. Есть куча сторонних решений, но они, как правило, громоздкие и надо всегда оценивать целесообразность их применения. Когда-то нашел интересный пример реализации шаблонизатора, который и покажу в действии.

    Расширяем стандартный класс String:
    String.prototype.supplant = function(o) {
       return this.replace(/\{([^{}]*)\}/g, function(a, b) {
          var r = o[b];
          return typeof r === 'string' || typeof r === 'number' ? r : a;
       });
    };
    

    Пример его использования:
    var template = "
    
  • {value}
  • "; var content = template.supplant({classname: 'myclass', value: 'test'});

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

    Такой шаблон сохраняется один раз и используется для всего приложения, что также исключает повторную реализацию одинакового кода. Операция замены ключей шаблона значениями входящего объекта не является ресурсоемкой.


    JavaScript. Простой assert

    Часто бывает полезно поставить в коде некоторые проверки целостности кода, для этого очень хорошо подходит методо assert стандартной console, которая поддерживается всеми современными браузерами (с IE8+ для мелкософта). Так можно реализовать простейшее тестирование кода.

    Применение:
    var x = 1;
    console.assert(x == 1, "X should be eqaul 1");
    

    Первым аргументом идет проверяемое утверждение (результатом должно быть логическое значение TRUE/FALSE), вторым - подсказка отображаемая в консоли.

    Если интересно почитать о консоли глубже - выкладываю ссылку на хабру.

    JavaScript. Получить timestamp из даты

    Для того чтобы получить timestamp из объекта даты, нужно воспользоваться методом valueOf():
    var dateObject = new Date;
    var timestamp = dateObject.valueOf();
    console.log(timestamp);
    
    // Или проще
    var timestamp1 = +dateObject;
    
    // Еще проще
    var timestamp2 = +new Date;
    

    пятница, 15 июля 2011 г.

    jQuery. Проверить существование элемента на странице

    Для того, чтобы проверить существует или нет заданный элемент, можно использовать 2 способа. В основе всего, лежит тот факт, что jQuery селекторы возвращают массив и мы можем искать его длину. Даже если найден только 1 элемент (когда мы конкретный элемент ищем) то размер ответа будет равен 1.

    Способ первый - стандартный:
    if($("#findID").length>0) {
      // exists
    }
    //еще проще:
    if($("#findID").length) {
      // exists
    }
    // Еще вариант:
    if($('#findID')[0]) {
     // exists
    }
    

    Способ второй - удобный (создадим пользовательскую функцию exists() ):
    // Один раз объявляем функцию, потом используем так, как в примере
    jQuery.fn.exists = function() {
       return $(this).length;
    }
    // Пример использования:
    if($("#findID").exists()) {
       // exists
    }
    

    Можно и так:
    jQuery.exists = function(selector) {
       return ($(selector).length > 0);
    }
    
    // Пример использования:
    if ($.exists(selector)) {
      // exists
    }
    

    вторник, 12 июля 2011 г.

    jQuery, CSS. Как отключить выделение мышкой текста для отдельного блока

    Иногда нужно запретить выделение текста в некоторых блоках - например при динамическом изменении размера, текст блока будет выделяться, что не есть красиво.

    Решений тут два: используем jQuery либо CSS.

    jQuery:
    $(".classname").attr('unselectable','on').css('MozUserSelect','none');
    

    CSS:
    .classname{
      -moz-user-select: none;
      -khtml-user-select: none;
      -webkit-user-select: none;
      -o-user-select: none;
      user-select: none;
    }
    
    Учитывая пожелания высказанные в комментариях, привожу пример яваскриптового отключения выделения (организованного в плагин), с явным отключением самого ивента 'onselectstart', а также содержащий весь уже выше перечисленный функционал:
    jQuery.fn.extend({ 
        disableSelection : function() { 
                this.each(function() { 
                        this.onselectstart = function() { return false; }; 
                        this.unselectable = "on"; 
                        jQuery(this).css({
                          '-moz-user-select': 'none',
                          '-khtml-user-select': 'none',
                          '-webkit-user-select': 'none',
                          '-o-user-select': 'none',
                          'user-select': 'none'
                        });
    
                }); 
        },
        enableSelection : function() { 
                this.each(function() { 
                        this.onselectstart = function() {}; 
                        this.unselectable = "off";
                        jQuery(this).css({
                          '-moz-user-select': 'auto',
                          '-khtml-user-select': 'auto',
                          '-webkit-user-select': 'auto',
                          '-o-user-select': 'auto',
                          'user-select': 'auto'
                        });
                }); 
        } 
    });
    
    // Example:
    var selector = "td, span, div";
    $(selector).disableSelection(); // disable
    ....
    $(selector).enableSelection(); // enable
    

    среда, 29 июня 2011 г.

    Yii. Настройка логирования SQL запросов

    В этой статье я расскажу как можно вывести в дебаг SQL которые генерит фреймворк Yii.

    Все изменения будут производится в главном конфиге,  который находиться тут: /protected/config/main.php
    Найдем в нем строчку
    'components' => array(
    
    Наша основная задача - настроить компонент логирования и компонет работы с БД, укажем параметры компоненту log и допишем параметры компоненту db:
    'components' => array(
       'db' => array(
          ..., 
          'enableProfiling' => true,
          'enableParamLogging' => true
        ),
        'log' => array(
          'class' => 'CLogRouter',
          'routes' => array(
             'db' => array(
             'class' => 'CWebLogRoute',
             'categories' => 'system.db.CDbCommand',
             'showInFireBug' => true //Показывать в FireBug или внизу каждой страницы
           )
        ),
        ...
    )
    
    Теперь в любом месте кода, например в каком-то контроллере нужно указать какой блок кода профилировать. В следующем примере выведутся те запросы которые генерит фреймворк для кода замкнутого в блок профилирования:
       Yii::beginProfile('blockId');
       $users = Users::model()->findAll("id>2");
       Yii::endProfile('blockId');
    

    пятница, 10 июня 2011 г.

    jQuery. Как найти и удалить класс по паттерну

    Постановка задачи: есть элемент страницы у которого есть много классов, необходимо удалить из этого списка классы которые попадают под определенный шаблон. Необходимо удалить те имена классов которые содержать суффикс "-find".

    some content

    Я предлагаю два способа решения задачи: первый способ заключается в том, чтобы получить массив классов, пройти по нему последовательно сравнивая элементы с заданным шаблоном, второй способ заключается в том, чтобы сразу искать совпадения классов шаблонов по строке (если к тегу применяется несколько классов, то они разделяются пробелами)

    Пример 1:
    $.fn.removeClassesByPattern = function(pattern) {
       var el = $(this);
       var items = [];
       var re = new RegExp(pattern);            
       $.each(el.attr('class').split(/\s+/), function(index, item){
         if(re.test(item)){
           items.push(item);
         }
       });
       el.removeClass(items.join(' '));
       return el;
    }
    
    Использование:
    $("#div1").removeClassesByPattern(/-find/);
    

    Пример 2
    $.fn.removeClassesByPattern2 = function(pattern) {
      var el = $(this);
      el.removeClass(function (index, _class) {
        var matches = _class.match (pattern) || [];                
        return (matches.join(' '));
      });
      return el;
    }
    
    Использование:
    $("#div1").removeClassesByPattern2(/\s?(\w+-find)/);
    

    Как видно на примерах - оба способа работают неодинаково. В первом случае мы проводим поиск по именам классов и сравниваем их с шаблоном на предмет соответствия. Второй способ заставляет нас писать шаблон поиска названий классов, таким образом шаблон получился значительно сложнее если сравнивать с примером 1. Но в тоже самое время, второй способ позволяет более гибко находить совпадение (если вы владеете регулярными выражениями в нужной степени).

    Какой способ использовать - зависит от поставленной задачи.

    Примечания:
     -  функция removeClass() принимает либо единичное имя класса, либо список имен разделенных пробелами
    - каждая из функций в конце работы возвращают элемент к которому она применяется. Таким образом, мы можем дальше выполнять цепочку вызовов



    вторник, 19 апреля 2011 г.

    PHP. Как узнать количество страниц в PDF файле

    Нашел интересный пример, как узнать количество страниц в документе PDF, достаточно применить регулярное выражение:
    $pdf_content = file_get_contents($pdf_filename);
    $count = preg_match_all("/\/Page\W/", $pdf_content, $matches);
    echo "Count: {$count}";

    Где $pdf_filename - путь к файлу

    Но оказалось, что тут просто считывается весь файл (может и очень большой), после чего, мы считаем количество страниц в файле с помощь регулярного выражения. Каждая страница будет содержать ключик Page и номер страницы. Это очень расточительный путь.

    Гораздо правильнее поискать в файле параметр где указано количество страниц, а не самим подсчитывать:
    $f = fopen($pdf_filename, "r");
    while(!feof($f)) {
      $line = fgets($f,255);
      if (preg_match('/\/Count [0-9]+/', $line, $matches)){
        preg_match('/[0-9]+/',$matches[0], $matches2);
        if ($count<$matches2[0]) $count=$matches2[0]; 
      } 
    }
    fclose($f);
    echo "Count: {$count}";

    Считываем файл построчно и анализируем пока не найдем искомое

    понедельник, 18 апреля 2011 г.

    PHP. Создать multi-page PDF на основне набора SVG файлов

    Появилась интересная задача: как на основе SVG файла создать PDF. SVG файл должен содержать картинки с подписями и  background  (создаваться может в сторонней программе).

    Путем проб и ошибок выяснил: ImageMagic еще не умеет обрабатывать картинки при конвертации   SVG, если они задаются относительным путем или ссылкой. 

    Выбор пал на Inscape - открытый редактор векторной графики. Кроме графической оболочки он предоставляет для работы консоль с набором команд (что собственно и требовалось). Кроме того, он полностью кросс-платформенный.

    Устанавливаем его, если под Winndows то прописываем в Path путь к приложению.

    Теперь из PHP можно юзать следующим образом:

    $filename = "svg_dir/test.svg"; //path to SVG file
    $pdf_filename="pdf_dir/test.pdf"; // output PDF

    if(!file_exists($filename)){
      throw new Exception("{$filename} not exists!");
    }

    system("inkscape -T $filename -A $pdf_filename",$success);
    if($success!=0){
      throw new Exception('Error inkscape convertation!');
    }

    На Хабре предлагают не создавать PDF c помощью Inkscape, так как они большого размера и предлагают сначала конвертировать в PostScript формат, а потом использовать утилиту  ps2pdf из пакета GhostScript для генерации непосредственно PDF. Размер такого файла действительно намного меньше чем прямая генерация PDF. Но у меня в задачи было условие создать много страничный PDF (inkscape и ps2pdf этого не умеют как оказалось).

    Потому я поступил проще: с помощью Inkscape я генерю отдельные PDF файлы, например с именами page1.pdf, page2.pdf, ...., pageN.pdf.

    Дальше я скачал утилиту pdftk,  которая умеет генрить мульти-страничные PDF и многое другое. Более детально по этому вопросу смотрим тут.

    Пример использования:

    pdftk pdf1.pdf pdf2.pdf ... pdfn.pdf cat output multipage.pdf

    или по маске:

    pdftk *.pdf cat output multipage.pdf

    для вызова из PHP нужно вызывать в контексте system("pdftk....")


    Если необходимо, то теперь можем с помощью pdf2ps и  ps2pdf  утилит (пакет GhostScript) оптимизировать получившийся PDF (оптимизация ухудшает качество, и как по мне, может только для предварительного просмотра использоваться или для особых задач- когда клиент получает высокое разрешение картинки только за отдельную плату).

    Пример очень прост (незабываем, команды в ПХП прогоняем через оператор system или exec):

    pdf2ps multipage.pdf multipage.ps
    ps2pdf multipage.ps multipage.pdf

    суббота, 16 апреля 2011 г.

    PHP. Как получить список установленных расширений (extensions)

    Для того чтобы получить список установленных extensions для php, существует отдельная функция: get_loaded_extensions(). Она возвращает массив, в котором присутствует список установленых расширений.

    Пример:
    $list = get_loaded_extensions();
    print_r($list);

    Ответ:
    Array
    (
      [0] => Core
      [1] => bcmath
      [2] => calendar
      [3] => com_dotnet
      [4] => ctype
      [5] => date
      ....
    )

    Еще пример:
    if(!in_array("gd", $list)){
      echo "GD extension not installed!";
    }

    Установка ImageMagic под Windows

    Заходим сюда: http://www.imagemagick.org/script/binary-releases.php#windows, качаем бинарник и ставим

    пятница, 8 апреля 2011 г.

    среда, 30 марта 2011 г.

    Yii. Автоматическое заполнение полей created и modified

    Если в Yii нужно в таблице создать поля для хранения даты/времени последней модификации и дату/время создания записи, удобно автоматизировать заполнение этих полей. В модель которая будет работать с данной таблицей, просто добавим фильтр перед записью в БД:

    public function beforeSave() {
      if ($this->isNewRecord)
        $this->created = new CDbExpression('NOW()');
      $this->modified = new CDbExpression('NOW()');
      return parent::beforeSave();
    }

    DateTime тип данных для Postgres

    Для Postgres аналогом DateTime(MySQL) будет тип "timestamp without time zone"

    Yii. Список базовых типов данных. List of supported data types

    Типы данных, которые поддерживаються валидатором Yii:

    • integer: 32-битные целые числа
    • float: с плавающей запятой, двойной точности
    • string: строка
    • array: массив
    • date: дата
    • time: время
    • datetime: дата-время

    среда, 16 марта 2011 г.

    вторник, 15 марта 2011 г.

    Ubuntu. Установить пароль для Postgres

    По-умолчанию под Ubuntu - Postgres не устанавливает пароль для пользователя. Выставим пароль для стандартного пользователя postgres, для дефотного шаблона:

    sudo -u postgres psql template1


    Теперь укажем для какого пользователя (имя пользователя тут postgres) будем менять пароль.
    Мы получим приглашение на ввод команд, и введем:

    \password postgres


    понедельник, 14 марта 2011 г.

    Установка и настройка приложения на JRuby on Rails3 на NetBeans

    Поиск по данной теме привел к очень исчерпывающему туториалу, чем и спешу поделится:

    Заранее скажу, что для windows будут проблемы с гемом mysql2, который написан не на руби, и соответственно работать под JRuby не будет (будут работать только библиотеки на чистом руби).

    Некоторый специалисты (в туториале тоже) предлагают для windows использовать sqlite3, а продакт уже на Unix сможет запустить и mysql.

    вторник, 22 февраля 2011 г.

    Rails 3 vs Rails 2. Защита от XSS атак

    В отличии от Rails 2, где для защиты от XSS атак нужно было явно экранировать переменные в шаблонах с помощью h() метода, в Rails 3 наоборотавтоматически, всегда включен режим экранирования. Если необходимо явным образом отключить экранирование - используется функция raw.

    Для того чтобы явно проверить/установить строке атрибут "безопасна", используются соответственно методы html_safe? и html_safe. Но в таком случае, обязательно следите сами за данными пришедшими с форм (тут уже используем h() ). Такие инструменты могут понадобится при создании методов хелперов.

    Rails 2:
    <%=h @title %>
    
    Rails 3:
    <%=@title %>
    
    <%=raw @title %>
    
    
    

    четверг, 17 февраля 2011 г.

    Silverstripe ошибка: Uncaught Exception: Object->__call(): the method 'getdestdir' does not exist on 'Page'

    Если в Silverstripe, после попытки генерировать кеш (http://mysite.com/dev/buildcache/) возникает ошибка:
    Error at sapphire/core/Object.php line 724: Uncaught Exception: Object->__call(): the method 'getdestdir' does not exist on 'Page'


    Значит добавить строку в /mysite/_config.php, которая включит механизм кеширования на сайте:

    Object::add_extension("SiteTree", "FilesystemPublisher('assets/cache/', 'html')");

    Я предпочитаю размещать кеш-файлы в папке assets

    вторник, 8 февраля 2011 г.

    Установка Google Chrome под Ubuntu

    Только недавно узнал для себя, что можно установить под Ubuntu браузер Google Chrome. Что позволяет под linux (в какой-то мере) тестировать WebKit (Safari именно на нем)

    sudo apt-get install chromium-browser


    пятница, 4 февраля 2011 г.

    Ruby on Rails модуль исключили из NetBeans IDE 7.0

    В новой версии NetBeans IDE 7.0, больше не будет поддерживаться Ruby on Rails модуль, точнее его просто выбросили... Так сообщает официальный сайт NetBeans. 

    Придется переходить на альтернативные IDE либо юзать старые версии NetBeans < 7.0

    Из платных IDE хвалят RubyMine (корпортаивная лицензия $150, персональная $29 + $49 за обновления), перечитав список бесплатных - то уж лучше старый NetBeans юзать чем кривую Аптану и ей же подобные...

    вторник, 1 февраля 2011 г.

    Добавить обязательный слеш в конце URL с помощью htaccess

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_URI} !example.php
    RewriteCond %{REQUEST_URI} !(.*)/$
    RewriteRule ^(.*[^/])$ $1/ [L,R=301]

    Последняя строка осуществляет переход со страницы без замыкающего слеша на страницу со слешем. Данный трюк важен для SEO, чтобы рейтинг страницы не расщеплялся на две страницы: со слешем и без него






    P.S. Для nginx:
    Добавить слеш если нету: rewrite ^(.*[^/])$ $1/ permanent;
    Как убрать все двойные слеши (nginx)

    пятница, 28 января 2011 г.

    Как обновить favicon.ico в Firefox

    Иногда, встречается проблема обновления favicon.ico для Firefox, из-за чего трудно протестировать его при редизайне. Даже после сбрасывания кеша, Firefox часто продолжает отображать старый favicon. В таком случае, помогает такой прием:

    зайдите на корневую страницу сайта (например http://www.mysite.com/), после чего перейдите по прямой ссылке на ваш фавикон: http://www.mysite.com/favicon.ico

    После чего, в окне браузера отобразится обновленная картинка фавикона. Дальше, перейдите назад на корневую страницу вашего сайта и вы увидите что фавикон обновился успешно.

    Для очистки кеша, куки и т.д. в Firefox - нажмите Right Ctrl+Right Shift+Del, выберите нужные галочки, период времени за которое нужно все очистить и нажмите "Очистить сейчас". Комбинация работает в IE8+, Chrome


    среда, 12 января 2011 г.

    Проверка версии браузера с помощью htaccess

    Постановка задачи: 
    Необходимо перенаправлять пользователей, которые используют устаревшие браузеры на специальную информационную страницу.

    Решение: 
    Такая задача возникает, если вы отказываетесь поддерживать старые версии браузеров и тратить на них время. Создаем html страницу, на которой выводим информацию, о том, что браузер пользователя устарел, и новую версию можно скачать перейдя по ссылке(ам).

    Задачу можно решить с помощью javascript (пример реализации использует jquery), создаем javascript файл и подключаем его в главный шаблон сайта:

    jQuery(document).ready(function(){
      if(jQuery.browser.msie && jQuery.browser.version < 7){
        location.href("update-browser.html");
      }
    });


    Тут проверка проводится для ИЕ6, но не составит труда дописать проверку для других браузеров.

    В таком подходе есть негативная сторона - необходима поддержка javascript, небольшая задержка на его выполнение и дополнительный редирект на инфо-страницу. Для избежания всего этого можно осуществлять проверку на уровне Апача, в правилах htaccess.

    Пример:

    RewriteCond %{HTTP_USER_AGENT} MSIE\ ([56])\.
    RewriteRule !\.(css|png|js|gif)$ update-browser.html [L]

    С первой строкой все ясно: тут определяем версию ИЕ. Вторая строка заставляет редиректить пользователся на страницу с информацией во всех случаях, кроме тех когда загружаются картинки, стили и скрипты. Если не исключать такие файлы по маске - тогда никогда не подгрузится оформление страницы update-browser.html.

    Для остальных браузеров похожие правила:

    RewriteCond %{HTTP_USER_AGENT} Firefox/2.* # Firefox > 2
    RewriteCond %{HTTP_USER_AGENT} Safari/[0-3] # Safari > 3
    RewriteCond %{HTTP_USER_AGENT} Opera/[0-9] # Opera > 9
    ...