Twitter/Facebook-подобная постраничная навигация

Я вот уже больше месяца как делаю социальную сеть pling.ee, которая акцентируется на связи посредством мобильных телефонов (SMS/MMS) и позиционировании людей с их помощью. Достаточно перспективный проект (как твиттер на дрожжах) и популярный среди местной молодёжи тем что можно почти нахаляву общаться.

Но технически возникла небольшая получасовая техническая задачка с навигацией, и раз уж я давно не писал, то может вам тоже будет полезно. Дело в том что в поток сообщений показывается ajax-ом, подгружаясь по X-сообщений  за раз чистым html (для json просто пришлось бы больше писать). Задача - прятать кнопку "ещё" если сообщений больше нет. Очень просто, но как оказывается не всё так очевидно.

Twitter pagination.png Facebook pagination.png

Вот возможные решения (от худшего к лучшему)

  1. При первой загрузке страницы делать второй запрос и узнавать какой ID у последнего сообщения и потом детектить его показ с помощью js. Проблема в том что как правило SQL для запроса и так сложный, а тут надо его продублировать с изменением сортировки. Уже пахнет говнокодом.
  2. Если число подгружаемых результатов меньше ожидаемых X элементов на странице то сразу прятать кнопку. Конечно с вероятностью 1/X она всё-таки будет показываться, зато
  3. Сделать что-бы нажатие кнопки сразу показывало спрятанные закешированные результаты (и если их нет - то не показывать кнопку) + делать ajax-запрос и результаты прятать (а если их нет то тоже прятать кнопку). Тут много игры с js и к тому же подгружаются лишние данные (не факт что пользователь всегда нажимает на продолжение)
  4. Использовать SQL_CALC_FOUND_ROWS что-бы расчитать число всех элементов и если их меньше чем offset + число на странице, то просто отметить последний элемент css-классом и через javascript проверить и спрятать кнопку если класс присутсвует

Unity3d

Unity3D это игровой движок 3D-игр в основном стрелялок и аркад, но при большой сноровке можно реализовать и RPG, RTS, квесты, 2D-игры, встраиваемые в браузер, iPhone и с использованием сети. Движок понимает множество разные форматы файлов

  • 3д модели и анимация из Maya, Cinema 4D, 3ds Max, Cheetah3D, Modo, Lightwave, Blender. Форматы 3ds, fbx и dae
  • практически все растровые изображения для маск и текстур
  • звуковые mp3, wav форматы для эффектов и фона

Профессиональная версия имеет более расширенные возможности по работе с динамическим освещением, сетевыми возможностями. Но даже без наличия блокбастерных игр о которых все бы слышали, unity успешно продвигается в плане комьюнити и «народного движка» и вполне возможно что с бесплатными плагинами можно будет написать игру ничем не уступающую платным.

IDE

Графическая оболочка разработчика (IDE) состоит из 4 основных панелей

  1. Графическое поле, переключающееся / вид игры (Game & Scene)
  2. Иерархия объектов (Hierarchy)
  3. Инспектор объекта (Inspector)
  4. Библиотека доступных ресурсов (Assets)
По используемости самое важное место это Инспектор, потому что именно в нём видны внутренности объекта (GameObject).

Создание карты

Карта (Terrain) создаётся очень просто из меню и по умолчанию уже есть. Курсором как в фотошопе можно изменять высоту рельефа (в том числе используя Shift). Более продвинутые господа придумали как импортировать карты из реального мира с помощью google earth, openTDD, делая так называемые heightmaps. Встроенный импорт работает только с raw форматами, надо использовать хак. Недавно вышел генератор карт.

Игровой объект Unity

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

Свои скрипты добавляются очень легко перетаскиванием в инспектор и публичные переменные сразу переводятся в названия с пробелами и значением по умолчанию. Для игрового объекта добавленные компоненты и с точки зрения ООП являются инкапсулированными объектами, хотя и играют в большинстве своём роль свойств (т.е. прилагательных - движущийся, крутящийся, выбираемый и тп.). По синтаксису скрипты пишутся на Javascript, C# или Boo скриптах со своими прибамбасами - глобальными объектами Unity, некоторыми своими ключевыми словами..

Drag-n-drop file upload

В продолжение статьи о новинках в html5, вот нашёл демо где уже работает загрузка файлов обычным перетаскиванием в браузер Firefox 3.6. Обычный drag-n-drop файлов пока в стабильных браузерах максимально что могут — создать события аналогичные перетаскиванию dom-элементов в определённые контейнеры.

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

event.dataTransfer.files event.dataTransfer.mozTypesAt(0) event.dataTransfer.files[0].getAsBinary()

А для отсылки файла используется обычный аяксный объект у которого появляется метод sendAsBinary(). Вобщем пока это выглядит как хак и видимо что надо больше внимания уделить спецификации html5, что-бы пользователь случайно не загрузил весь C:\Windows, что-бы можно было временно отложить загрузку или отфильтровать что конкретно надо загружать, или до какой глубины надо структуру подгружать и как обрабатывать.

Jquery dnd-upload

Написал два jquery-плагина - один для поддержки Firefox 3.6 (Namoroka) HTML5 загрузки, другой для поддержки Google gears. Можно использовать оба вместе..

Самый простой вариант для gears:

$('#drop_area').uploadg({gate:'http://somesite.com/upload_here_path/'});

Заметьте что ключ получаемого у сервера файла будет "file" (в пхп соответсвенно $_FILES['file']). А вот расширенный пример кода инициализации..

var dragndropConfig={ beforeLoad:function(){ this.gate=some_dynamic_file_upload_url+'?parentID='+SomeOtherDynamicObject.ID; if(SomeDisableReason){ this.can_proceed=false; } }, onProgress:function(event) { if (event.lengthComputable) { var percentage = Math.round((event.loaded * 100) / event.total); if (percentage < 100) { $('#some_progress_div').html('Uploading file..'+percentage+'%'); } } }, onComplete:function(event,txt) { $('#some_progress_div').html('done'); } }; if (window.google && google.gears){ $('#drop_area').uploadg(dragndropConfig); } else{ $('#drop_area').upload5(dragndropConfig); }

Осторожно, Google gears всё ещё имеют баги связанные с такой загрузкой.

PHP frameworks

Как можно уже заметить в моём блоге, я уделяю дотошное внимание используемому языку и смыслу слов, поэтому термин фреймворк мне не нравится, вместо этого по-моему правильней говорить о каркасе или скелете приложения.

Выбор современных каркасов для php достаточно широк. Меня всегда интересовала именно внутренняя структура запуска типичного приложения, поэтому постараюсь описать их именно с этой стороны. 

codeigniter-Web-PHP-framework.png

Codeigniter 1.7.6 - легковесный (1 mb) и простой в освоении. За основу берётся MVC-паттерн, популяризированная в ruby on rails. Основное приложение лежит в application папке, делится в свою очередь на контоллеры, шаблоны и модели, кроме того папки - errors, helpers, language, config и hooks.  Классы контроллеров соответсвенно наследуют Controller и по умолчанию запускается index-метод, шаблоны показываются через this->load->view(имя_шаблона, передаваемые_переменные).

Из полезного замечены классы валидации форм, работы с изображениями (imagemagick, watermark), trackback-запросов для статей в блогах, автогенерация кода (scaffolding). Само собой поддержка разных бд (mssql, mysql, postgre, oracle, sqlite). Итого получается достаточно типично - одно приложение, разбитое по контроллерам. Идеальный фреймворк для минималистов типа меня.

Сайт очень позитивный - вики, видео примеры, форумы и багтрекер.

symfony-Web-PHP-framework.png

Symfony 1.3a от Sensio Labs позиционируется как более тяжёлый каркас (15 mb!). Та же MVC, но теперь с использованием ORM (Propel или Doctrine). Из ещё полезных фишек - кеширование шаблонов, scaffolding, многоязычность, чпу, недоступность исполняемых файлов от публичного каталога апача (как следствие - безопасность), настройка среды где проект вертится (development, testing, production). В минусы я бы отнёс привязку к JS библиотеке (Prototype), достаточная тяжеловесность по оперативке и времени из-за отсутсвия lazy loading классов (sic!) и опять же ORM.

Ещё одной особенностью является использование YAML в качестве файлов настроек. Если смотреть пример установки тестового (sandbox) приложения то видно что есть работа с консолью по автогенерации файлов моделей. Приложения в свою очередь состоят не только из моделей (обеспечивающим интерфейсы к бд), но и из модулей (с CRUD-действиями и интерфейсами).

По запуску процесса мне показалось очень сложным. Надо прописывать настройки в .yml файлах, что-бы сгенерировать всей файлы. Потом по идее грузится front controller, который вызвает модуль и в нём уже метод (по умолчанию - executeIndex) и вызывает шаблон indexSuccess.php

Сайт тоже достаточно путанный и быстрого погружения не даёт, а если распечатать примеры создания приложения, то из них получится более 10 страниц текста.

cakePHP-Web-PHP-framework.png

CakePHP 1.2.6 позиционируется как клон RoR и пожалуй с него слизан был Codeigniter (в том числе и поддержка старого php 4 ). Понимание как работает CakePHP это по сути понимание как работают остальные похожие каркасы или почему они работают неправильно. Почему именно это решение не стало очень популярным - сложно сказать, может дело в названии и не все такие сладкоежки.

"Пирожок" в общем быстрей чем Codeigniter и Yii, весит 7 мб и в общем предполагает тоже определённые названия классов (AppController, AppModel). В шаблон данные из контроллера передаются через $this->set(). Что понравилось - есть возможность юнит тестирования, очистки данных (Sanitize::paranoid), автогенерации кода (Cake bake), использования модели как дерева (и его показ методом generatetreelist)

zend-Web-PHP-framework.png

Zend Framework 1.9 скачать проблематичней - надо регистрироваться на сайте этой Zend-компании которая и имеет то преимущество что выпускает свой IDE, Optimizer и сервер. IDE у них глючный, поэтому к каркасу приложений я так же скептически отношусь. И не зря - этот монстр выпускается в двух версиях и минимальная из них весит 20 мб! Названия классов всюду фигурируют с Zend префиксом. В общем сразу видно отношение к разработчикам.

В плюсы - большая независимость классов. Можно взять тот же Zend_DB и использовать только его в своём проекте, подобно библиотеке PEAR, ещё в Zend_DB уже есть выборка данных методами fetchPairs, fetchAll (которые я давно использую в своём движке), переводы в зависимости от числительности (Zend_Translate::plural), интеграцию с PHPunit, разделение на приватный и публичный каталог, ограничение прав (Zend_Acl).

По структуре.. Контроллеры наследуют Zend_Controller_Action и по умолчанию запускают indexAction метод. Данные в шаблон передаются через переменную контроллера $this->view. Шаблоны хранятся в .phtml файлах.

Одновременно и в плюсы и в минусы можно записать наличие обработки форм и веб-сервисов типа youtube. Не понравилось что в Zend_PDF очень низкоуровневые способы генерации файла, отсутсвие таблиц. В минусы я запишу и интеграцию с Dojo, общую тяжеловесность и дух рационального корпоративизма.

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

akelos-Web-PHP-framework.png

Akelos в основном продвигает Bermi Fermer и сразу признаётся в том что это максимально полный клон RoR и весит приличные 9 мб. Запуск очень аналогичен вышеназванным каркасам, поэтому я не удивляюсь что контроллер наследует ApplicationController и по умолчанию тоже вызывается index-метод. Переводы в контроллере можно получить через AK::t() метод, что странно и непропорционально относительно названий других объектов и методов.

Данные в шаблон летят через $this->saveAttribute(). Вобщем ничего отличительного что вы в руби не видели. Интересная выборка с использованием ActiveRecord и множественностью ассоциаций между моделями (has_one, belongs_to). Использование AdoDB в качестве адаптера к базе данных, хранение сессий в базе.

Минусы - интеграция с Prototype.js и scriptaculous, отсутствие документации, хранение переводов в ассоциативном массиве, практически нулевая популярность и сообщество разработчиков. Вряд ли пока стоит брать на вооружение.

yii-Web-PHP-framework.png

Yii PHP Framework 1.0.9 на удивление хорошо документируется в рунете, целиком объектный и хвастающийся что он быстрей даже чем CodeIgniter, хотя скорость по идее зависит от многих вещей кроме скелета. Развился из Prado, весит неплохие 7 мб.

По запуску - вызывается контроллер который наследует CController, потом в зависимости от запрашиваемого URL вызывается более низкий класс который наследует CAction. Для всяких дополнительных проверок на права можно использовать фильтры - CFilter. Модели могут быть двух типов - Active Record либо CFormModel. Шаблоны показываются в контроллере через $this->render().

Префикс "C" как и с "Zend" даёт какую-никакую совместимость но и добавляет шума. В целом мне показался каркас удобней чем Symfony, но чуть более корпоративный чем CodeIgniter.

Читайте также

Silverlight, JavaFX и Flex

Вчера у нас была очередная встреча девклуба посвящённая базам данных и надо сказать достаточно полезная и успешная. Однако тут я выложу запись декабрьской встречи 2008 г. где видимо только я был с камерой.