Главное меню
все форумы все темы форума добавить тему
Модуль блога.
Здравствуйте ув. Loki!
LabCMS - действительно классный движок, в среде которого очень приятно программировать, и в тоже время повышать свои навыки программирования.  
Мне кажется что к текущему составу основных модулей было бы круто добавить  написать модуль блога.
Пока ещё я не перешел к активным действиям по его созданию, но планирую приступить в ближайшее время.
На данный момент пытаюсь "устаканить" самые необходимые функции, с которых и начну.
Я думаю, что было бы классно сделать такой модуль, который позволял вести, создавать свой личный блог, для каждого пользователя сайта.
Из основных фишек хочу еще выделить рейтинговую систему, для каждого блога,  
Еще, конечно же, нужно будет прикрепить к нему комментарии, и рейтинг для них же.
Ну вот такие Наполеоновские планы
Только что обновил trunk ветку до версии 3.5. В ней как раз появился класс комментариев (еще не совсем готовый, но основные функции уже работают). Сейчас он подключается к новостям и статичным страницам. В принципе, новости с комментариями вполне могут выступать этаким "блогозаменителем", но если планы действительно "наполеоновские", то лучше их, конечно, реализовать
За прошлую неделю набросал так сказать "чертеж".
Сначала нужно было прийти к логике, как организовать свою работу. Так как опыта у меня еще не слишком много в таких делах, решил делать все "по наростающей".
В принципе, функционал пока крайне примитивный.
При инсталяции модуля, автоматически создается блог для администратора.
Админ имеет права, и уже может добавить категории блогов.
При добавлении топика, соответственно нужно указать в какой блог публикуем, указать метки, ну и саму статью.
В принципе идея самого модуля заключаеться в том, что каждый юзер может вести свой личный блог, или же публиковать записи в определённые категории блогов.
Поэтому сейчас думаю как организовать автоматическое добавление личного блога для юзера, который только зарегистрировался, конечно же если модуль установлен.
Еще нужно обратить внимание на парсинг самого текста перед добавлением в бд.
Во всех формах использую HTML_QuickForm2.
 
Вообще звучит очень здорово. Я уже стал подумывать что вместо раздела форума "заметки на полях" больше бы подошел блог. А раз там может вести его несколько человек, то свои блоги могли бы иметь и разработчики модулей. В общем, звучит все очень вкусно
Loki:
Вообще звучит очень здорово. Я уже стал подумывать что вместо раздела форума "заметки на полях" больше бы подошел блог. А раз там может вести его несколько человек, то свои блоги могли бы иметь и разработчики модулей. В общем, звучит все очень вкусно

Отличная идея
 
Для парсинга текста была выбрана бесплатная библиотека Jevix.
Каким образом добавляем статью в бд:
Для содержания контента топика есть две таблицы:
1. В ней содержится основная информация про топик (заголовок, юзер id, id блога, опубликован ли топик и т.д.).
2. В этой таблице содержится 3 поля (топик id, пропарсенная статья, обрезанная статья).
Сам процесс подачи топика пока таков:
Юзер должен указать тег <more> в статье, после подтверждения скрипт парсит, потом обрезает  статью до этого тега, и ложит в одну ячейку обрезанный текст, а во вторую полный пропарсенный текст.
Соответственно при листинге топиков берем только обрезанный текст, и заголовок
А для чего две таблицы? Пост может быть опубликован в нескольких блогах?
Да, я вот как раз сейчас и думаю об этом. Или лучше весь контент топика всё же держать в одной таблице..
Если пост может быть только в одном блоге, то две таблицы не нужны, если же в нескольких сразу, то логичнее было бы во вторую таблицу вынести так же поля заголовка, user_id и т.п. (то есть все что относится к конкретной записи).
 
И еще, если я правильно понимаю, то в случае отсутствия тега <more> поля записи и анонса будут совпадать?
Loki:
Если пост может быть только в одном блоге, то две таблицы не нужны, если же в нескольких сразу, то логичнее было бы во вторую таблицу вынести так же поля заголовка, user_id и т.п. (то есть все что относится к конкретной записи).

Скорее всего лучше пока отказатся от этой идеи.. 1 пост - в 1 блог, и пока 1 таблица.
При большом кол-ве, наверняка можно легко устроить бардак. Я думаю, что лучше потом подключить это как опцию.
 
Loki:

И еще, если я правильно понимаю, то в случае отсутствия тега <more> поля записи и анонса будут совпадать?

Да, пока так и есть. Нужно будет обновить метод, который парсит текст, и вставлять этот тег, если его нет, через какое-то к-во символов, или же сразу резать без этого тега... скорее всего как-то так.
Честно говоря, я не знаю, сложно ли это со стороны разработчика, но тем не менее... Зачем лишнее поле с обрезанной статьей? Мне просто почему-то пришла аналогия с модулем новостей - можно указать в настройках сколько символов отображать, как превью. Почему тут не зделать что-то подобное? Вообще функционал с тегом "море" интересен... Не знаю, Вам наверное виднее, как в данном случае лучше поступить. Но поле в бд с обрезанной копией текста - как-то не круто чтоли. Модуль (точнее та штука в нём, которая будет парсить) не может определять где находится тег "море" и показать всё до него? А если тега нету брать кол-во символов из настроек. Мб сделать такие настройки для каждого юзера отдельно? В общем это небольшая информация к размышлению. Я не знаю, трудно ли это в коде, но если это блог - нужно дать возможность гибкости настройки модуля и размещения постов.
Мне кажется, что наличие этого самого тега <more> и добавляет большей гибкости
Ну в принципе, сначала я подумывал о том, что бы статья лежала полная, в 1 ячейке.
Но тут есть некие неудобности. Неудобности заключаются с обработкой статьи.
Получается что-то вроде того:
при листинге топиков, нужно каждый раз достать целую статью, для каждого топика, что бы для начала определить где находится тот самый тег, далее отработать с ним, и показать только анонс. Ну а статья, может быть и большая, плюс каждый раз это делать...
Мне показалось проще и логичнее делать это один раз при самом добавлении статьи.
А при самом листинге модуль берет намного меньше информации по объему из БД.
 
На счет того, что если тега <more> нет, сегодня хочу доделать, что бы он вставлялся через стандартное к-во символов.
То есть если человек постит информацию, пусть оформит статью, и поставит "кат" где ему нужно, если же нет, тогда пусть модуль сам обрежет
Мне кажется что вставлять этот тег автоматически не совсем правильно. Вполне допускаю существование блогов без ката вообще - под катом только комментарии остаются.
Кстати, а добавлять <more> планируется при помощи Jevix? Он проследит при этом за корректностью тегов?
Хм, возможно, а если статья уж сильно длинная?
 
Добавлять тег, скорее всего что да, при помощи Jevix. Как мне показалось, это достаточно гибкая в настройках библиотека.
 
Ну так сильно или не сильно, на мой взгляд, решать автору блога, а не разработчику. В крайнем случае, вынести эту опцию в настройки.
Ок, так и сделаю. Если тега нет, тогда нужно добавить его в конце статьи.
Defari:
Ок, так и сделаю. Если тега нет, тогда нужно добавить его в конце статьи.

Хм... а зачем он в конце статьи?
Ну это что бы статья отображалась полностью. Если правильно понял. Ну а если у владельца блога сделать пункт кол-ва символов. тоесть модуль ищет сначала тег море, если его нет - смотрит кол-во символов из настроек. Такое возможно?
Я сейчас занимаюсь листингом топиков. Можно сделать что бы тег распознавался js как ссылка "Подробнее", хотя скорее всего это лишнее...
 
mushtat:
Ну это что бы статья отображалась полностью. Если правильно понял. Ну а если у владельца блога сделать пункт кол-ва символов. тоесть модуль ищет сначала тег море, если его нет - смотрит кол-во символов из настроек. Такое возможно?

 
Скорее всего, что возможно, но неясно или нужно...
Пока пришли к выводу, что если тег есть, то это и будет анонс (все что перед тегом).
В ином случае вся статья и будет отбражатся как анонс. UPD: И автоматически тег подставлятся не будет.
(Это что бы никто не запутался)
mushtat:
Ну это что бы статья отображалась полностью. Если правильно понял. Ну а если у владельца блога сделать пункт кол-ва символов. тоесть модуль ищет сначала тег море, если его нет - смотрит кол-во символов из настроек. Такое возможно?

Потерян один элемент в логической цепочке: если тег будет автоматически подставляться в конец статьи, то в каких же случаях будет срабатывать обрезка по количеству символов?
Имелось в виду, что модуль не будет дописывать тег, если его нету. Но разработчику виднее, я затрудняюсь находить решения в данной области... Но, как бы там нибыло - всегда полезно узнать другое мнение. Стараюсь помочь в силу своих знаний и возможностей.
Ну вот вроде бы листинг по минимуму для начала организован, пейджер подключен.
Появился вопрос
Как лучше организовать ссылки в браузере?
Вот что мне пришло в голову:
На каждый топик есть ссылка "Читать далее". Вот как она пока выглядит:
Smarty

<a href="{url action="detail" var1=$topic.blog_title var2=$topic.topic_id}">Читать дальше</a>
 

Получаем что-то типа
mysite.net/blog-detail.Blog+by+admin/2/
Возможно стоить ввести еще одно поле при добавлении категорий блогов, и назвать его blog_url ?
Соответственно если оно есть, то вставлять его вместо blog_title...
Ну тут Вы разработчик - Вам и карты в руки
Реально на отображение влияет только topic_id, все остальное - сеошно-навигационный балласт. Так что я бы сделал var1=$topic.topic_id, а все остальные - любые другие.
Собственно, у меня так в новостях и сделано на сайте:
http://labcms.ru/news-item.26/kak+hranit+paroli/
Еще момент - надо перевести название в транслит, а то url будет выглядеть очень некрасиво.
 
На этом сайте используется такой модификатор:
PHP
function smarty_modifier_translit($string)
{
    return translit($string);
}

 
Smarty
{url action="item" var1=$new.news_id var2=$new.news_title|translit}
Теперь пришло время поработать с добавлением меток.
Пока работает так:
При добавлении топика, есть поле для меток, метки нужно разделять запятыми.
Модуль обрабатывает их, и ложит каждую метку отдельно в таблицу для них же.
В таблице для меток такие поля: id метки, id топика, id юзера, id блога, сама метка.
Так же, метки лежат и в таблице топика, в том виде, в каком добавлены.
При просмотре или листинге топиков метки берутся из таблицы топиков.
А смарти всё уже разбивает вот так:
Smarty

 {section name=topic loop=$topic_full}
            <h1>{$topic_full[topic].topic_title}</h1>
            <div class="topic_content">
                {$topic_full[topic].topic_text}
            </div>
            {assign var="tag" value=","|explode:$topic_full[topic].topic_tags}
            <ul class="tags">
            {section name=tags loop=$tag}
                {if $smarty.section.tags.last}
                    <li><a>{$tag[tags]}</a>.</li>
                {else}
                    <li><a>{$tag[tags]}</a>,</li>
                {/if}
            {/section}
            </ul>
 {/section}
 

В итоге получается ряд из меток вида: "метка1,метка2,метка3."
Какие есть трудности.
Если оставить эту схему, то нужно наверное проверять в mysql (в табл. для меток), или уже есть такая метка в бд, что бы не добавлять дубликат...
А почему именно такая схема? У каждого пользователя/блога свой набор меток?
Если нет, то я бы предложил такую схему:
таблица меток
tag_id, tag (уникальное)
и таблица связей:
topic_id, tag_id (первичный по двум полям)
 
А id юзера и id блога у Вас и так есть в таблице записей.
При этом получается удобный и быстрый поиск по тегам.
Нет, планируется, что будет общий набор меток, доступный для всех блогов.
Да, Вы правы. Такая схема более удобная.
Upd:
Добавил 2 таблицы:
MySQL

--
-- Все теги
--
CREATE TABLE IF NOT EXISTS ?_blog_tags (
  `tag_id` int(11) NOT NULL AUTO_INCREMENT,
  `tag_text` varchar(50) NOT NULL,
  PRIMARY KEY (`tag_id`),
  UNIQUE KEY `tag_text` (`tag_text`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
 
--
-- Теги топика
--
CREATE TABLE IF NOT EXISTS ?_blog_topic_tags (
  `topic_id` int(11) NOT NULL,
  `tag_id` int(11) NOT NULL,
  PRIMARY KEY (`topic_id`,`tag_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
 

Как при этом сделать правильно INSERT? Получается что нужно положить метку в
?_blog_tags а потом передать этот id в ?_blog_topic_tags..
Да, алгоритм получается примерно такой:
1. добавили запись в таблицу элементов и получили item_id
2. добавляем тег в таблицу тегов
MySQL
INSERT IGNORE INTO ?_blog_tags...

Если тег добавился - в качестве результата получим tag_id, если получили false, значит тег уже есть и надо сделать запрос для получения его id.
А лучше - наоборот, сначала запросить id всех добавляемых тегов одним запросом.
3. добавляем пары значений в ?_blog_topic_tags (можно всей кучей).
 
В случае если запись редактируется, добавится пункт:
2а. Удаляем из таблицы ?_blog_topic_tags все записи с item_id=item_id_редактируемой_записи
Всё, сделал. Спасибо Вам за подсказку
Кстати, во избежание фрагментации можно не все старые связи удалять, а только не актуальные:
MySQL
DELETE FROM ?_blog_topic_tags WHERE item_id=? AND tag_id NOT IN (список id текущих тегов)
Ага, если я Вас правильно понял, тогда список id текущих тегов нужно достать из таблицы
?_blog_tags ?
PHP

$new_tags=array('хлеб', 'зрелища');
//находим id всех существующих тегов
$tag_keys=Db::i()->selectCol("SELECT tag_id AS ARRAY_KEY, tag FROM ?_blog_tags
                              WHERE tag_id IN (?a)"
, $new_tags);
/*
тут сопоставляем теги с их id и добавляем отсутствующие теги в базу
в результате получаем массив $tag_items содержащий перечень tag_id для данной записи
 
добавляем записи в таблицу _blog_topic_tags
*/

 
//оцищаем информацию о тегах, которые были раньше, но не используются сейчас
Db::i()->query("DELETE FROM ?_blog_topic_tags
             WHERE item_id=? AND tag_id NOT IN (?a)"
, $item_id, $tag_items);