qooxdoo (произносится [ 'ку: ksdu:]) является объемным и новаторским фреймворком (основой) для создания Rich Internet Applications (RIA). Использование объектно-ориентированного JavaScript-а позволяет разработчикам создавать впечатляющие кросс-браузерные приложения. Никакого HTML, CSS, ни DOM знания не нужны. qooxdoo включает в себя независимую от платформы цепь инструментом развития, оответствующее современным достижениям GUI Toolkit и передовой клиент-сервер-ный слой связи.
qooxdoo целиком состоит из классов и наследовать возможности Объектно Ориентированного JavaScript-a. Он полностью опирается на пространства имен и не наследует стандартные типы Javascript, чтобы легко интегрироваться с другими библиотеками и пользовательским кодом. Большинство современных браузеров(например Firefox, Internet Explorer, Opera, WebKit/Safari) поддерживают его, и он защищен от утечек памяти. Поставляется с обширным API, который автоматически генерируется из Javadoc-подобных комментариев и из синтаксиса кода. Быстрый и полный парсер не только позволяет генерацию доков, но и является неотъемлемой частью процесса автоматической сборки, что делает оптимизацию, сжатие, связывание и развертывание собственных приложений очень удобным для пользователей. Интернационализация и локализация приложений для различных стран и Языки является основной функцией и легки в использовании.
четверг, 24 сентября 2009 г.
суббота, 19 сентября 2009 г.
Vinadium: проверка на стороне клиента
http://vanadiumjs.com/
Простой, интуитивный, и мощный скрипт проверки на стороне клиента.
Нет необходимости в программировании, легко расширяем и настраиваем.
Поддерживает Ajax.
Все очень просто!
<input class=":min_length;4" type="text"/>
<input id="pass" class=":email" type="text"/>
Простой, интуитивный, и мощный скрипт проверки на стороне клиента.
Нет необходимости в программировании, легко расширяем и настраиваем.
Поддерживает Ajax.
Все очень просто!
<input class=":min_length;4" type="text"/>
<input id="pass" class=":email" type="text"/>
четверг, 17 сентября 2009 г.
Простое решение красивых URL
Если Вы просматриваете какую-то запись/пост на Cake-сайте, то скорее всего адрес выглядит так:
/posts/view/5, где posts - модель, а 5 - номер id записи.
Чтобы сгенерировать такую ссылку надо порписать что-то вроде:$html->link('CakePHP Tips', array('controller' => 'Post','action' => 'view',5));
Но вы не будете писать id вручную, скорее всего это будет что-то вроде:
$html->link($post['Post']['title'], array('controller' => 'Post','action' => 'view',$post['Post']['id']));
А сейчас самое интересное:
Вы можете написать дополнительный параметр, и он будет перенаправлен туда же.
То есть /posts/views/5/Cakephp-tips, ведет туда же, куда и /posts/views/5
Все! Нам больше нигде не нужно хранить Slug. Достаточно прописать его в ссылке
$html->link($post['Post']['title'], array('controller' => 'Post', 'action'=>'view', $post['Post']['id'], Inflector::slug($post['Post']['title'], '-')));
Это даст нам что-то вроде: /posts/view/5/cakephp_tips
/posts/view/5, где posts - модель, а 5 - номер id записи.
Чтобы сгенерировать такую ссылку надо порписать что-то вроде:$html->link('CakePHP Tips', array('controller' => 'Post','action' => 'view',5));
Но вы не будете писать id вручную, скорее всего это будет что-то вроде:
$html->link($post['Post']['title'], array('controller' => 'Post','action' => 'view',$post['Post']['id']));
А сейчас самое интересное:
Вы можете написать дополнительный параметр, и он будет перенаправлен туда же.
То есть /posts/views/5/Cakephp-tips, ведет туда же, куда и /posts/views/5
Все! Нам больше нигде не нужно хранить Slug. Достаточно прописать его в ссылке
$html->link($post['Post']['title'], array('controller' => 'Post', 'action'=>'view', $post['Post']['id'], Inflector::slug($post['Post']['title'], '-')));
Это даст нам что-то вроде: /posts/view/5/cakephp_tips
среда, 16 сентября 2009 г.
Cakephp TreeBehavior и отдельная ветка
Сегодня расскажу о замечательном свойстве TreeBehavior-a для Cakephp generatetreelist()
Как правило, он выдает большое дерево с подкатегориями и тому подобное.
чтобы использовать tree behavior, в вашей таблице должны быть хотя бы эти 3 поля:
parent_id, lft, rght
$this->Category->generatetreelist();
и все наше дерево готово!
Оказывается не все! а если я хочу не всю ветку, а начиная с id=5?
сразу скажу что варианты типа
$this->Category->generatetreelist(array('id'=>5));
Не прокатит. т.к. в этом случае он вернет только 'id'=5. а нам нужна ветка.
Ну что ж, пойдем дальше...
заменим $this->Category->generatetreelist(); на $this->Category->find('threaded');
этим мы ничего не изменили, а всего лишь вывели все поля, а не только key=>value
а для чего спросите Вы, здесь lft, rgth? странно. я сам долго не мог понять, а чем им id не понравился для сортировки?
как выяснилось, они вовсе не для сортировки.
пока у строк parent_id=0, т.е все они нулевого уровня, lft+1=rght
до того как Вы для какого нибудь элемента добавите дочерний.
Что же тут происходит? lft и rght продолжают нумерацию дальше, как ни в чем ни бывало, не смотря на то что это уже дочерние элементы.
А вот у родительского lft тот же самый, но вот rght = "последний дочерний rght"+1
и так приступим:
удачного приготовления :-)
Как правило, он выдает большое дерево с подкатегориями и тому подобное.
чтобы использовать tree behavior, в вашей таблице должны быть хотя бы эти 3 поля:
parent_id, lft, rght
$this->Category->generatetreelist();
и все наше дерево готово!
Оказывается не все! а если я хочу не всю ветку, а начиная с id=5?
сразу скажу что варианты типа
$this->Category->generatetreelist(array('id'=>5));
Не прокатит. т.к. в этом случае он вернет только 'id'=5. а нам нужна ветка.
Ну что ж, пойдем дальше...
заменим $this->Category->generatetreelist(); на $this->Category->find('threaded');
этим мы ничего не изменили, а всего лишь вывели все поля, а не только key=>value
а для чего спросите Вы, здесь lft, rgth? странно. я сам долго не мог понять, а чем им id не понравился для сортировки?
как выяснилось, они вовсе не для сортировки.
пока у строк parent_id=0, т.е все они нулевого уровня, lft+1=rght
до того как Вы для какого нибудь элемента добавите дочерний.
Что же тут происходит? lft и rght продолжают нумерацию дальше, как ни в чем ни бывало, не смотря на то что это уже дочерние элементы.
А вот у родительского lft тот же самый, но вот rght = "последний дочерний rght"+1
и так приступим:
$prn = $this->Category->find('first',
array('conditions'=>array('id'=>5))
);
$out = $this->Category->find('threaded', array('conditions'=>array('Category.lft BETWEEN ? AND ?'=> array($prn['Category']['lft'], $prn['Category']['rght'])), 'order'=>'lft');
удачного приготовления :-)
понедельник, 14 сентября 2009 г.
jQuery решает проблему select-to-input
Джефри Олчовый разместил постой способ про использование jQuery для решения проблемы selet-to-input. Способ заключается в том, чтобы показывать или прятать текстовое поле, когда вы выбираете вариант "Другой". Оно использует то же название поля, так что сервер получает только одно значение, и не парится о том было ли оно выбрано в select-е, или введено в поле.
$(document).ready(function(){
$('.leader').each(function(){
var name = $(this).attr('name');
if($(this).val()!='other'){
$(this).next().removeAttr('name').hide();
}
});
$('.leader').change(onChange);
function onChange(){
var desiredName = $(this).attr('name');
if($('#'+desiredname).val()=='other'){
$('#'+desiredname).next().attr('name',desiredName).fadeIn('fast');
}else{
$('#'+desiredname).next().removeAttr('name').fadeOut('fast');
}
}
});
$(document).ready(function(){
$('.leader').each(function(){
var name = $(this).attr('name');
if($(this).val()!='other'){
$(this).next().removeAttr('name').hide();
}
});
$('.leader').change(onChange);
function onChange(){
var desiredName = $(this).attr('name');
if($('#'+desiredname).val()=='other'){
$('#'+desiredname).next().attr('name',desiredName).fadeIn('fast');
}else{
$('#'+desiredname).next().removeAttr('name').fadeOut('fast');
}
}
});
воскресенье, 13 сентября 2009 г.
Выборка релевантных тегов (ярлыков)
Суть проблемы — на нескольких сайтах можно видеть фильтрацию новостей по нескольким тегам: если выбрать один тег — будут показаны новости которые имеют этот тег, а отображаемый список тегов будет уменьшен так, чтобы остались только те теги, которые встречаются в отфильтрованных по первому тегу новостях. И так далее, пока не закончатся теги в результате их «фильтрации». Тоесть, чтобы при выборе нескольких тегов остались только те новости, которые содержат полный их набор.
Хороший пример этому Delicious принадлежащий компании Yahoo!
Как это сделать на ?
Опишу только алгоритм.
Имеются 3 таблицы posts(id,content), tags(id,tag), posts_tags(id,post_id,tag_id).
как Вы поняли, третья таблица соединяет первые две.
1. сначала выбираю статью, со всеми тегами.
2. выбираю остальные статьи с этими же тегами.
3. выбираю список тегов в этих статьях.
4. сортирую этот список тегов, удаляю одинаковые (например через array_unique())
Если Вы хотите хранить теги через запятую, а потом искать их через "tags LIKE '%тег%'", то спешу Вас огорчить. Этот способ плохой до не узнаваемости. Все дело в том, что даже если на поле tags вы повесили index, то при использовании "tags LIKE '%тег%'" этот индекс учтен не будет.
Взято из обсуждения с одного сообщества, а так как это ответ мой, то я смело публикую это здесь.
Хороший пример этому Delicious принадлежащий компании Yahoo!
Как это сделать на ?
Опишу только алгоритм.
Имеются 3 таблицы posts(id,content), tags(id,tag), posts_tags(id,post_id,tag_id).
как Вы поняли, третья таблица соединяет первые две.
1. сначала выбираю статью, со всеми тегами.
2. выбираю остальные статьи с этими же тегами.
3. выбираю список тегов в этих статьях.
4. сортирую этот список тегов, удаляю одинаковые (например через array_unique())
Если Вы хотите хранить теги через запятую, а потом искать их через "tags LIKE '%тег%'", то спешу Вас огорчить. Этот способ плохой до не узнаваемости. Все дело в том, что даже если на поле tags вы повесили index, то при использовании "tags LIKE '%тег%'" этот индекс учтен не будет.
Взято из обсуждения с одного сообщества, а так как это ответ мой, то я смело публикую это здесь.
Как поменять заголовок у Blogger-а
Обычно по умолчанию Blogger в заголовке прописывает title, который мы указали в настройках.
Не то что это не совсем удобно. Я бы сказал это совсем не удобно: каждый раз одно и то же, одно и то же.
Что нам делать?
1. Layout(Макет) -> Edit HTML (изменить HTML)
2. находим строку:
Не то что это не совсем удобно. Я бы сказал это совсем не удобно: каждый раз одно и то же, одно и то же.
Что нам делать?
1. Layout(Макет) -> Edit HTML (изменить HTML)
2. находим строку:
<title> <data:blog.pageTitle/> </title>3. меняем ее на:
<b:if cond='data:blog.pageType == "index"'>4. сохраняемся. и все!
<title> <data:blog.title/> </title>
<b:else/>
<title> <data:blog.pageName/> </title>
</b:if>
Что делать с Ajax, при отключенном Javascript
Все мы знаем чтО такое Ajax.
Для тех кто не знает, вкратце скажу.
Что это такое?
Эта такая система, которая с помощью Javascript, делает запрос на какую-либо страницу и результат выводит на экран.
Зачем это нужно?
Больше не надо грузить всю странице целиком, а только ее часть. Я просто умалчиваю о других бесценных свойствах..
А что если пользователи отключили Javascript?
А вот об этом, я как-раз и хочу рассказать...
Первое что я делаю: все ссылки привожу к виду
<a href="/articles/page:2" onclick="open('/articles/page:2'); return false;">Далее</a>
Далее, в начале страницы, между <script type="text/javascript> и </script> пишем Ajax запрос, который будет доставать ту самую '/articles/page:2', но ссылка не сработает, т.к. мы прописали "return false;"
А если у пользователя отключен Javascript, то он тупо перейдет по ссылке и получит страницу целиком.
Кстати, такой подход полезен и для разных ботов, которые сканируют ваш сайт
Для тех кто не знает, вкратце скажу.
Что это такое?
Эта такая система, которая с помощью Javascript, делает запрос на какую-либо страницу и результат выводит на экран.
Зачем это нужно?
Больше не надо грузить всю странице целиком, а только ее часть. Я просто умалчиваю о других бесценных свойствах..
А что если пользователи отключили Javascript?
А вот об этом, я как-раз и хочу рассказать...
Первое что я делаю: все ссылки привожу к виду
<a href="/articles/page:2" onclick="open('/articles/page:2'); return false;">Далее</a>
Далее, в начале страницы, между <script type="text/javascript> и </script> пишем Ajax запрос, который будет доставать ту самую '/articles/page:2', но ссылка не сработает, т.к. мы прописали "return false;"
А если у пользователя отключен Javascript, то он тупо перейдет по ссылке и получит страницу целиком.
Кстати, такой подход полезен и для разных ботов, которые сканируют ваш сайт
13 сентября - День программиста!
13 сентября (12 в високосные годы) в России официально будет отмечаться День Программиста
Почему именно эта дата? Просто это 256 день года :-)
Существует также День системного администратора (последняя пятница июля). В качестве официального он не принят нигде.Единственным официальным праздником, связанным с информационными технологиями (кроме российского Дня программиста), является Всемирный день информационного общества, принятый Генеральной Ассамблеей ООН. Он празднуется 17 мая.
Таким образом, со вчерашнего дня, Россия стала первой и пока единственной страной в мире со столь ИТ-шным праздником. Можно, конечно, говорить, что данный праздник не несет собой ничего материального, зато он пропагандирует важность программирования в культуре и обществе.
суббота, 12 сентября 2009 г.
Прикручиваем resuestAction к Cache-у
В документации Cakephp 1.2 говорится о том что если requestAction используется без кеширования, то то может уменьшить производительность.
И как истинные политики, они говорят что может произойти, при этом не говоря КАК это избежать.
Привожу пример того, как с этим разбираюсь я. Это не догмат. Потому буду признателен чужим мнениям, тем более, что Вы, дорогие читатели, не чужие!
Коротко, о том как работает requestAction:
requestAction обычно используется вo view-файле (папка views). из view-файла, вы делаете запрос на другую страницу, и получаете значение.
синтаксис requestAction-а таков: $this->requestAction('/articles/home');
который говорит Cakephp что надо сделать запрос по адресу http://адрес.сайта/articles/home
в самом контроллере к которому обращается requestAction надо прописать return;
function home(){
$out = $this->Article->find('all');
Cache::write('articleHome', $out);
return $out;
}
теперь мы можем смело дописать к $this->requestAction('/articles/home'); следующие строки
$out = Cache::read('articlesHome');
if(empty($out)){
$out = $this->requestAction('/articles/home');
}
и теперь при каждом обновлении этого списка, если мы что-то добавили/изменили не забываем перезаписывать: Cache::write('articleHome', $out);
If used without caching requestAction can lead to poor performance. It is rarely appropriate to use in a controller or model.И правда, сами подумайте, каждый раз при просмотре сайта, кроме основнфх запросов к базе, делается куча мелких, с помощью requestAction-ов...И как истинные политики, они говорят что может произойти, при этом не говоря КАК это избежать.
Привожу пример того, как с этим разбираюсь я. Это не догмат. Потому буду признателен чужим мнениям, тем более, что Вы, дорогие читатели, не чужие!
Коротко, о том как работает requestAction:
requestAction обычно используется вo view-файле (папка views). из view-файла, вы делаете запрос на другую страницу, и получаете значение.
синтаксис requestAction-а таков: $this->requestAction('/articles/home');
который говорит Cakephp что надо сделать запрос по адресу http://адрес.сайта/articles/home
в самом контроллере к которому обращается requestAction надо прописать return;
function home(){
$out = $this->Article->find('all');
Cache::write('articleHome', $out);
return $out;
}
теперь мы можем смело дописать к $this->requestAction('/articles/home'); следующие строки
$out = Cache::read('articlesHome');
if(empty($out)){
$out = $this->requestAction('/articles/home');
}
и теперь при каждом обновлении этого списка, если мы что-то добавили/изменили не забываем перезаписывать: Cache::write('articleHome', $out);
Подписаться на:
Сообщения (Atom)