Реализация простого фото-портфолио с back-end’ом и front-end’ом

от автора

Привет, Хабр!

Выделив немного свободного времени, я решил отписать о такой интересной вещи, как портфолио для фотографов (либо простейшая фото-галерея). Здесь я постараюсь рассказать о парочке подводных камней, с которыми я столкнулся и как они были решены. Интересно? Что ж, тогда прошу под кат.

Недавно было получено задание реализовать фото-портфолио с бекэндом и фронтэндом. Начав ковырять готовые фреймворки и CMS я пришел к выводу, что лучше всего использовать связку GalleryCMS, Galleria и плагин к Galleria.

Первое же, которое меня не устроило, это проблемы с поддержкой категорий в GalleryCMS. А именно, ее вообще нету. Есть только альбомы, в которые собственно и загружаются фотографии и «фиды». Вот такой простенький backend. Как решить вопрос с категориями? Я посмотрел в сторону «фидов». Оказывается в них можно добавлять больше, чем один альбом. Что ж, я думаю сойдет. Сделаем «фиды» категориями. Но для этого давайте посмотрим в базу данных. Как же все-таки он сохраняет список альбомов в «фид»?

Структура базы в backend’е довольно простая. Всего в ней 8 таблиц. В них хранятся фиды, альбомы, список пользователей, список изображений и есть то, что нам очень поможет — таблица соответствий между фидами и альбомами. Взглянем в таблицу feed_album.

В этой таблице можно увидеть всего 4 поля: id записи, id «фида», id альбома и порядок отображения. Уже становится ясно, что с этой таблицы можно взять какой альбом в какой «категории» («фиде») лежит. А теперь посмотрим в другие таблицы: album и feed.

Здесь есть все — вот оно — решение проблемы. Зная id альбома и id «фида», в котором лежит этот альбом, можно сгенерировать объект. В этом объекте выстроить структуру Категория -> Альбомы. Что ж, приступим к реализации.

Напишем php-скрипт, который будет выдавать ответ (Категория -> Альбомы, Категория -> Альбомы) в JSON.

<?php //считаем, что к базе мы уже подключились include_once './database.php'; //инициализируем массив ответа $response = array(); //выберем сначала таблицу соответствий $result = mysql_query('SELECT * FROM feed_album'); for ($feed_album = array(); $row = mysql_fetch_assoc($result); $feed_album[] = $row); //затем список наших категорий ("фидов") $result = mysql_query('SELECT * FROM feed'); for ($feed = array(); $row = mysql_fetch_assoc($result); $feed[$row['id']] = $row); //а затем еще и список всех альбомов $result = mysql_query('SELECT * FROM album'); for ($album = array(); $row = mysql_fetch_assoc($result); $album[$row['id']] = $row); //пройдемся по таблице соответствий //и заполним наш response foreach ($feed_album as $value) {     $response[$feed[$value['feed_id']]['name']][$album[$value['album_id']]['name']] = $album[$value['album_id']]['uuid']; } //в итоге мы получим массив такого вида //Категория //--Альбом = uuid альбома //--Альбом = uuid альбома //Категория и т.д.... echo json_encode($response); ?>

С одной проблемой разобрались. На frontend мы уже получаем список категорий и их альбомов. Как же теперь построим меню, на основе этих данных?

Для этого было написаны 2 функции. Одна забирает посредством AJAX данные с нашего скрипта, а вторая формирует HTML на основе этих данных. Что ж, вот код:

//эта ф-ция генерирует HTML-код buildMenu: function() { //сначала инициализируем строку для кода         var html = ''; //аяксом мы сохраняем ответ от php в свойство объекта this.albums //перебрали весь объект с альбомами         for (var feed in this.albums) {             html += '<li>';             html += '<a href="#">' + feed + '</a>';             html += '<ul>';             for (var album in this.albums[feed]) { //каждый альбом это ссылка, в data-uuid храним uuid альбома, а album и feed - это названия категории и альбома                 html += '<li><a href="#" data-uuid="' + this.albums[feed][album] + '">' + album + '</a></li><div class="spacer"></div>';             }             html += '</ul></li>';         } //в итоге добавляем в наш блок с меню этот html         $('#' + Core.Config.idMainMenu).html(html);     }, //а эта ф-ция как раз выступает в роли запроса этих альбомов     getAlbums: function() {         var self = this;         $.ajax({             url: Core.Config.ajxGetAlbumsSrc,             dataType: 'json',             type: 'POST',             cache: false,             error: function() {                 Core.Objects.Design.blockAllPage('Ошибка загрузки<br/>Перезагрузите страницу');             },             success: function(response) { //когда получим альбомы, то сохраним и вызовем ф-цию выше                 self.albums = response;                 self.buildMenu();             }         });     } 

Таким образом мы получаем меню, в котором есть категории и альбомы. Вроде все хорошо, но нужно теперь запустить альбом в галерею по щелчку. Начинаем подключать те самые плагины Galleria и плагин к ней. И да, пока не забыл, Galleria использует jQuery, поэтому его нужно тоже подключать.

В итоге реализуем нажатие по ссылкам нашего меню, возьмем uuid, который мы помещаем в data-uuid и бросаем этот uuid на растерзание плагину к Galleria. Вот код обработки нажатия на ссылку:

$('#' + Core.Config.idMainMenu + ' a').click(function() {             var uuid = $(this).data('uuid');         if (uuid != undefined && uuid != null && uuid != '') { //эта ф-ция переключает альбом на тот, по которому мы щелкнули //ее я опишу ниже             Core.Objects.Gallery.switchAlbum(uuid);         }         }); 

Вот код, которые уже загружает информацию о фотографиях в альбоме и выводит в галерею:

switchAlbum: function(uuid) { //gallerycms - это наш плагин к Galleria.         $('#' + Core.Config.idMainGallery).gallerycms({ //в url мы должны передать путь к ./backend/index.php/api/feed/json/ + наш uuid альбома //в итоге мы вытянем фотографии с этого альбома и загрузим в нашу галерею             url: Core.Config.urlGalleryCMS + uuid,             theme: Core.Config.themeMainGallery         });     } 

Все, проблема решена. Я радуюсь и отдыхаю. Но не тут-то было. При попытке загрузить второй альбом, он снова загружает предыдущий альбом. Все, приехали. Почему он загружает нормально только в первый раз, а вторые разы уже не загружает?

Начал ковырять уже сам код плагина, а в итоге и самой Galleria. Вывод нашелся быстро — после созданий экземпляра галереи, другие фотографии загрузить уже не получится. Нужно брать контроль в свои руки.

Ковыряя код пришел к двум вариантам решения проблемы. Первый вариант — использовать ф-цию load на экземпляре галереи. Она загружает в галерею новые изображения, очищая старые. Второй вариант — использовать ф-цию destroy в экземпляре галереи. Было решено попробовать ф-цию load. Зачем же нам каждый раз уничтожать экземпляр и создавать по новой, правильно?

И после нескольких часов разбора исходников плагина и Galleria пришел к выводу, что проще всего реализовать это не ф-цией load, как все советуют, а очередным запуском run с передачей параметров в json. Давайте отредактируем наш плагин gallerycms к Galleria. Редактируем ф-цию parseAlbum, в которую как раз передается наш uuid альбома:

function parseAlbum() { //объявим массив, в котором будем хранить список изображений для Galleria             var json = [];             $.getJSON(settings.url, function(data) {                 $.each(data.images, function(key, image) { //заполняем наш массив объектами с параметрами фотографий                     json.push({                         thumb: image.thumb,                         image: image.url,                         title: image.caption                     });                 });                 Galleria.loadTheme(settings.theme); //запускаем еще раз галерею, передавая ей наш новый json-объект с фотографиями                 Galleria.run($this, {                     dataSource: json                 });             });         } 

Таким образом было реализовано простейшее фото-портфолио с бекэндом и фронтэндом.
P.S. Можно еще переделать немного backend и вместо Feeds написать Категории и т.д. в таком духе. Чтобы у пользователя не осталось сомнений, что здесь есть категории.
P.P.S. За код сильно не ругайте, у каждого свой стиль написания. Буду прислушиваться к вашим пожеланиям.
Спасибо всем, кто дочитал до этого места и, возможно, почерпнул из этого что-то новое или интересное.

ссылка на оригинал статьи http://habrahabr.ru/post/173289/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *