LINUX.ORG.RU

Markdown блог тред. (Практики, мысли и все такое.)

 , ,


1

2

Приветствую! Есть желание сделать блог, который будет кушать markdown файлы, которые будут разбиты по директориям согласно иерархии рубрик (т.к. локально будет точно также). Потом можно будет на perl или sh написать простой пуш файлов с ПК на ftp, если такого еще никто не делал.

В общем, в чем соль. Хочется максимально простого решения (ага, мечты), но с возможностью сортировки записей по дате и рубрикам. Есть такой движок блога как jekyll и ему подобные, например, kirby. (Хотя последний сложно отнести к платформе блога.) Все они по своему интересны, но не без нюансов. Например, jekyll критичен к наименованию файлов, а рубрики указываются в шапке файлов markdown.

Пока рассматривал разные варианты ради интереса написал простую функцию, которая формирует массив из файлов и каталогов из указанной директории:

function listFolderFiles($dir){
    $files_array = scandir($dir);

    unset($files_array[array_search('.', $files_array, true)]);
    unset($files_array[array_search('..', $files_array, true)]);

    if (count($files_array) > 0) {
        $mass_array = [];

        foreach ($files_array as $files_array_elem) {
            $mass_array_inner = [];
            $mass_array_inner['name'] = $files_array_elem;
            $mass_array_inner['time'] = gmdate("Y-m-d;H:i:s", filemtime($dir . '/' . $files_array_elem));

            if (is_dir($dir . '/' . $files_array_elem)) {
                $mass_array_inner['type'] = 'directory';
                $mass_array_inner['inner'] = listFolderFiles($dir . '/' . $files_array_elem);
            } else {
                $mass_array_inner['type'] = 'file';
            }

            $mass_array[] = $mass_array_inner;
        }

        return $mass_array;
    } else {
        return;
    }
}

Потестил ее на скорость работы, закинув на тестовый сервер с проектом на более, чем 37 000 файлов и вывел массив как html список. Время от запроса сервера до полного формирования страницы заняло около 10 секунд, а только формирование массива - почти пол секунды. Для сравнения wp на другом тестовом с пачкой плагинов и около 100 записей занимает 1,2 секунды. Хотя, вы и без меня все это знаете.

В целом скорость работы устраивает (учитывая, что она снизится при чтении каждого файла в строку, чтобы вытянуть шапку с данными как у jekyll), но печалит то, какая огромная работа будет совершаться каждый раз при открытии страницы блога со списком записей. Именно это заставляет смотреть в сторону БД, чтобы проще было сортировать записи.

И вот теперь не могу определиться с тем каким путем лучше пойти: только file-based или дополнить какой-то БД, например, sqlite для хранения ссылок на файлы, их дат публикации и, возможно, рубрики и какие-то теги. Но тогда (при БД) нужно будет дописать что-то на вроде админки, чтобы раз в какой-то период времени обновлять базу. Хотя, можно разбавить кроном...

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

Заранее благодарю участвующих за советы и критику!

★★★★

Последнее исправление: EmgrtE (всего исправлений: 1)

Что-то не очень понял, ты хочешь статический блог или с динамикой на PHP? Если первое, то время работы не очень важно, так как сервер будет отдавать html. Если второе, то однозначно нужна база данных, чтобы не грузить сервер неэффективным проворачиванием кучи файлов.

DuMOHsmol
()
Ответ на: комментарий от DuMOHsmol

Скорее динамический. Просто при статике будут, грубо говоря, дубли файлов markdown. И даже больше. Не вижу в этом смысла. Хотя, готов выслушать все за в сторону статики. Меня в целом интересуют размышления и практики на тему блога с markdown.

EmgrtE ★★★★
() автор топика

Раньше был на хаскеле блог, который динамически рендерил md -> HTML. Теперь просто генератор сделал, и одну кнопку «upload».

Deleted
()

scandir
2018

Ты с какой пещеры вылез?

огромная работа будет совершаться каждый раз

Кешируй результат (в инклюду с ретурном), перелопачивай только при добавлении-удалении-изменении файлов.

sqlite

Это та, которая все в хлам лочит пока с ней не закончат работать? Она для сингл юзера.

deep-purple ★★★★★
()
Ответ на: комментарий от Deleted

Не подскажешь как такое делают? https://martin-thoma.com/python-style-guide/ Не смотря на то что тут на пеликане сделан блог, я встречал кучу сайтов на джекилл, где не просто MD>HTML рендерится, но и ещё как-то кастомные стили применяют к HTML. Этот момент мне больше всего любопытен.

Xant1k ★★
()

Посмотри в сторону статик цмс. У меня есть в планах в ближайшее время изучать что это из себя представляет. Может даже отпишусь быстрее, чем ты прочтёшь этот пост=)

Xant1k ★★
()
Ответ на: комментарий от Xant1k

Ну, jekyll грубо говоря и есть статическая cms, только это не cms, т.к. никакого управления контентом там нет.

Что это такое? Ну, оно просто из твоих данных создает кучу отдельных html страничек. Вот есть у тебя к примеру главная, три поста и одна страница, то статический движок создаст тебе 5 html файлов, которые меж собой перелинкованы. Ну еще и всякие 400.html сделает.

EmgrtE ★★★★
() автор топика
Ответ на: комментарий от Xant1k

Ну, у каждого движка есть свои способы. Например у jekyll есть шаблоны, которые можно править: https://help.github.com/articles/customizing-css-and-html-in-your-jekyll-theme/ и https://stackoverflow.com/questions/32723405/including-css-stylesheets-in-jek....

А еще, учитвая то, что при парсинге markdown заменяются из него только описанные в документации конструкции, а все остальное идет как plain text, то можно спокойно там писать любую верстку, включая <style>. Но это плохой подход и так делать не стоит.

EmgrtE ★★★★
() автор топика
Ответ на: комментарий от deep-purple

Ты с какой пещеры вылез?

Э, glob, readdir? Или что-то есть новое?

Кешируй результат (в инклюду с ретурном), перелопачивай только при добавлении-удалении-изменении файлов.

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

Это та, которая все в хлам лочит пока с ней не закончат работать? Она для сингл юзера.

Да. Мне большего и не нужно.

EmgrtE ★★★★
() автор топика
Ответ на: комментарий от Anoxemian

Чем интересен grav, кроме того, что эта cms хранит в БД записи в формате markdown?

EmgrtE ★★★★
() автор топика
Ответ на: комментарий от anonymous

Эээ, это предложение сделать блог на ноде или spa фреймворке?

EmgrtE ★★★★
() автор топика
Ответ на: комментарий от Deleted

Интересно, а что стало причиной перехода от динамики к статике?

Были какие-то интересные проблемы за жизнь блога, которые пришлось решать?

EmgrtE ★★★★
() автор топика

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

Tark ★★
()
Ответ на: комментарий от Tark

Планировал такую иерархию:

posts:
  - category_1:
    - article_1:
      - images
      - title.md
    - article_2:
      - ...
    - article_3:
      - ...
  - category_2:
    - ...

Или внутри директорий категорий/рубрик разбить записи еще и по датам:

posts:
  - category_1:
    - 2018.01:
      - article_1:
        - images
        - title.md
      - article_2:
        - ...
      - article_3:
        - ...
    - 2018.03:
      - ...
    - 2018.04:
      - ...
  - category_2:
    - ...
EmgrtE ★★★★
() автор топика

Думаю, могу предложить извращенное решение:

  • Подрубаешь любую базу данных по типу ключ-значение (можешь хоть SQL использовать в этих целях).
  • Пишешь демон, который использует inotify, чтобы отслеживать изменения в рабочей директории и генерировать HTML из измененных Markdown файлов.
  • Базу данных используешь лишь для того, чтобы сохранять хеши файлов Markdown по относительному пути от корня рабочей директории, для которых уже сгенерировал HTML (для того, чтобы не запускать перегенерацию всех статей при перезагрузке компьютера или демона).

То есть работаешь в стиле GOPATH:

$WORKDIR/out - сгенерированный контент (HTML'ки).
$WORKDIR/src - каталоги с Markdown файлами.

Ну и в БД записи вида: path/to/file.md <-> d8f4590320e1343a915b6394170650a8f35d6926

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

Deleted
()
Последнее исправление: merhalak (всего исправлений: 1)
Ответ на: комментарий от EmgrtE

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

Но мои друзья раскритиковали

Странные у тебя друзья.

Мне большего и не нужно

Ну как не нужно? Пока приконнектившийся клиент не закончит получать страницу — остальные будут висеть в очереди ожидания. И все это из-за скулайта.

Клади в инклюд с ретурном. Если предполагается дохрена записей, то записи по сабдиректориям распихать (те же инклюды) и на верхнем уровне рядом с сабдирами «индексный» инклюд, в котором все, но без подробностей, а только ссылка, название.

deep-purple ★★★★★
()
Ответ на: комментарий от EmgrtE

Если уж упарываться до конца, то я бы только по директориям категорий раскидывал, а уж у симлинков таймстамп устанавливал руками просто.
А потом через что-нибудь типа
find category1 category2 category3 -mtime $(date +%s -d"Aug 10, 2013 23:59:59#From date#") -mtime $(date +%s -d"Aug 1, 2013 23:59:59#To date#") | xargs -I {} readlink {} | uniq
доставал бы список файлов за определенный временной интервал и определенных категорий. То что между «#» если что коммент и в find можно через exec вызывать readlink, но мне лень.

Tark ★★
()
Ответ на: комментарий от EmgrtE

Интересно, а что стало причиной перехода от динамики к статике?

Это проще в использовании, даже веб сервер настраивать не нужно.

Были какие-то интересные проблемы за жизнь блога, которые пришлось решать?

Он у меня предельно простой: https://seccomp.ru/

Исходный текст это markdown файлы с $(time +%s) в начале имени файла и с # Заголовком в начале файла.

$ ls
1419033600_c_params.md                   1434499200_ssh_over_ssh.md  1486798591_knockd_over_ssh_with_pam.md  1511774706_gentoo_efi.md
1425686400_dm_crypt_debian_to_gentoo.md  1472515200_gentoo.md        1504674078_how_build_kernel.md          1521700054_bitlor.md
1531038223_chromium_auto_install_plugins.md
$ head 1531038223_chromium_auto_install_plugins.md
# Автоматическая установка плагинов в Google Chrome / Chromium

Необходимо создать файл /etc/chromium/policies/managed/plugins.json со следующим содержанием:

    {
        "ExtensionInstallForcelist": [
            // uBlock Origin
            "cjpalhdlnbpafiamejdnhcphjbkeiagm;https://clients2.google.com/service/update2/crx",
            // uMatrix
            "ogfcmafjalglgifnmanfmnieipoejdcf;https://clients2.google.com/service/update2/crx",
Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от Xant1k

Не подскажешь как такое делают? https://martin-thoma.com/python-style-guide/ Не смотря на то что тут на пеликане сделан блог, я встречал кучу сайтов на джекилл, где не просто MD>HTML рендерится, но и ещё как-то кастомные стили применяют к HTML. Этот момент мне больше всего любопытен.

Со стороны генератора тебе нужно просто получить HTML. Все стили это CSS, и делается это отдельно.

Deleted
()
Ответ на: комментарий от melkor217

Я просто не знал, как сформулировать «единый workspace» посреди ночи.

Deleted
()
Ответ на: комментарий от Deleted

Мне нравится! Спасибо за идею.

EmgrtE ★★★★
() автор топика
Ответ на: комментарий от deep-purple

Ну как минимум глоб. Но тогда не забудь проверить — под фряхой было дело вернул фелс вместо пустого массива.

Так он вроде возвращает false, если ошибка.

Странные у тебя друзья.

¯\_(ツ)_/¯

Пока приконнектившийся клиент не закончит получать страницу — остальные будут висеть в очереди ожидания. И все это из-за скулайта.

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

Если предполагается дохрена записей, то записи по сабдиректориям распихать (те же инклюды) и на верхнем уровне рядом с сабдирами «индексный» инклюд, в котором все, но без подробностей, а только ссылка, название.

А зачем создавать локальные инклюды в дочерних директориях? Чтобы сократь длинну индексного инклюда, если записей будет много?

EmgrtE ★★★★
() автор топика
Ответ на: комментарий от Tark

Ну, директории с указанием дат скорее для меня, чем для блога.

А потом через что-нибудь типа find category1 category2 category3 -mtime $(date +%s -d"Aug 10, 2013 23:59:59#From date#") -mtime $(date +%s -d"Aug 1, 2013 23:59:59#To date#") | xargs -I {} readlink {} | uniq

Хм, задействовать shell_exec() интересная идея.

EmgrtE ★★★★
() автор топика
Ответ на: комментарий от bvn13

Кажется здесь, на ЛОР, была ветка по разработке этого блога. Читал тогда.

EmgrtE ★★★★
() автор топика
Ответ на: комментарий от Deleted

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

EmgrtE ★★★★
() автор топика
Ответ на: комментарий от EmgrtE

false, если ошибка

Под фряхой я натыкался и когда ошибки нет, т.е. просто пусто, но всеравно фелс. Хз толи сборка такая васянская была, толи бага приползла в одной из версий. Я не разбирался, просто добавил проверку.

Чтобы сократь длинну индексного инклюда, если записей будет много?

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

deep-purple ★★★★★
()
Ответ на: комментарий от deep-purple

Понял, спасибо за информацию.

EmgrtE ★★★★
() автор топика
Ответ на: комментарий от EmgrtE

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

Tark ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.