Межпланетная файловая система — Простой блог в IPFS при помощи XSLT

Существует проблема: У сайта в IPFS нет возможности использовать серверные скрипты для формирования страницы. Если использовать генерацию страниц перед загрузкой то добавив новый пункт меню в каждую страницу мы изменим хеш этих страниц. Так что всю сборку страниц нужно производить силами браузера.

Обычно формируют содержание страниц при помощи JavaScript. Это знакомая технология, но у неё есть свои недостатки.

Я буду использовать XSLT. Это древняя технология шаблонов которая давно встроена в браузеры, но мало кто ей пользуется. Возможно потому что шаблоны заставляют писать много текста и из за путаницы с пространствами имён и множества ошибок без внятного объяснения. Также не смотря на то что есть уже XSLT 3.0 в браузерах по прежнему доступен только XSLT 1.0.

XSLT работает так:


  1. Пользователь открывает в браузере XML документ.
  2. В заголовке XML документ содержит ссылку на XSLT шаблон.
  3. Шаблон в браузере на основе XML документа и других данных формирует xHTML документ.
  4. Браузер отображает полученный xHTML документ.

Привязав множество страниц к одному шаблону можно менять отображаемый xHTML документ не меняя XML документы. Таким образом при смене дизайна не будет меняться хеш XML документов, а значит старые их копии будут источниками для новых в IPFS.

Для поисковиков в данном способе тоже есть плюсы. Они ограничиваются обработкой XML документа получая только уникальный контент страницы без элементов навигации и остальных блоков которые повторяются на каждой странице.

image

В XML можно использовать любые теги. Главное не нарушать синтаксис XML который немного строже чем в HTML:


  1. Все теги должны быть закрыты.
    Но есть возможность использовать самозакрытые теги
    .
  2. На верхнем уровне может быть только один тег. Остальные теги должны быть заключены в него.
    <корень>
        <потомок />
        <ещё-один />
        <и-ещё-один />
    
  3. Текст может быть только внутри тегов.
    <корень>
        Здесь текст
    


новая запись.xml

Наша задача сделать простой и понятный для пользователя блог который он сможет самостоятельно пополнять с помощью простого текстового редактора.

XML шаблон блого-записи для заполнения пользователем:
Файл: 'новая запись.xml'



<запись>
    <заголовок>
    <текст>
        <срез>
    

По названию тегов уже понятно что где писать не зная английского. Вопрос может вызвать только тег срез. Его содержимое отправится в meta тег description. А в дальнейшем может использоваться для отображения в ленте.

В тексте мы можем использовать xHTML теги (те же HTML теги) для стилизации текста.

Пример заполнения:


Файл: 'Lorem Ipsum.xml'


<запись>
    <заголовок>Lorem Ipsum
    <текст>

Lorem ipsum dolor sit amet

<срез>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras feugiat orci non orci tincidunt molestie. Donec eget porta metus. Aenean malesuada nunc lacus, a sollicitudin neque fermentum eu. Vestibulum egestas viverra urna, sit amet mollis ipsum commodo imperdiet. Quisque sit amet est eu nibh commodo pharetra. Donec fermentum nisi nec lorem auctor imperdiet. Morbi ultricies at magna ullamcorper malesuada. In eget arcu dapibus, vehicula nunc vel, convallis erat. Cras accumsan lacus vel tellus gravida, eu gravida turpis congue. In ultrices pellentesque odio at hendrerit.

Cras nec lorem facilisis

Cras nec lorem facilisis justo porttitor scelerisque id id ipsum. Duis mattis, sem eu sollicitudin pharetra, diam augue ullamcorper nisl, id dictum turpis ex in nisl. Aliquam venenatis egestas urna eget porttitor. Suspendisse potenti. Curabitur fermentum fermentum nulla, a lobortis ipsum laoreet eget. Duis finibus lacus id tempor elementum. Interdum et malesuada fames ac ante ipsum primis in faucibus. Curabitur tempus eget turpis ut tincidunt. In quis massa et risus tempor luctus quis eu enim. Duis finibus sem sit amet elit scelerisque molestie. Suspendisse laoreet, leo ut accumsan dapibus, nisi tellus dignissim lorem, eu auctor tellus diam vel nisi. Donec sem tortor, suscipit a leo maximus, aliquet dapibus nisl. Integer sodales, dui ut vulputate pharetra, ipsum neque tempor ipsum, sed porta tortor quam a nisl. Sed consequat purus sed porttitor pulvinar. Mauris sollicitudin non sem a malesuada. Vestibulum non velit finibus, elementum purus nec, aliquam lacus. Etiam leo enim, venenatis id luctus ut, ornare sit amet ex. Nunc vel fringilla ante. Cras lobortis scelerisque pulvinar. Ut lectus augue, viverra quis molestie eu, maximus nec leo. Sed facilisis odio ut malesuada mollis. Pellentesque enim lacus, luctus nec velit quis, scelerisque tincidunt magna. Proin laoreet, erat eget porttitor bibendum, odio augue suscipit purus, id commodo magna nibh sed est. Ut dignissim aliquet sem, id suscipit sapien mollis volutpat. Vivamus ac fringilla est, at sagittis diam.


запись.xhtml

Обычно формирование всего xHTML запихивают в XSLT шаблоны. Они от этого со временем будут разрастаться и усложняться. Нечего верстальщику делать в XSLT шаблонах.

Для верстальщика у нас будет xHTML страница в которой он может пометить классами элементы в которые надо вставить содержимое одноимённых тегов из XML.

Файл: 'xhtml/запись.xhtml'



    
        
        Простой блог на XML
        
        
        
    
    
        
        

    Элемент ]]> не содержит текста. Заполните его.


запись.xslt

Теперь надо связать эти два файла (XML и xHTML) при помощи XSLT.

Шаблон читает файл 'запись.xhtml' и заменяет содержимое тегов по классам на содержимое тегов с соответствующими именами в XML. Также он меняет некоторые теги в XML и привязывает к пространству имён xHTML.

Файл: 'xslt/запись.xslt'




    
    

    
    

    
    

    
    
        
        
    

    
    
        
            
        
    

    

    
    
        
            
            
        
    

    
    
        
    

    
    
        
        
    

    
    
        
            
            
        
    

    
    
        
            
            
        
    

    
    
        
            
        
    

    
    
        
        
            
        
    

    
    
        
    

     
    
        
        
            
            
                
            
            
        
    


навигация

Навигация нужна для перемещения между записями блога. К каждой записи мы добавляем список ссылок на другие страницы.


журнал.xml

У нас будет XML файл в котором просто перечислены все записи:

Файл: 'журнал.xml'



<журнал>
    <запись>новая запись

Содержимое тега 'запись' это имя xml файла записи без расширения.

Пример заполнения:



<журнал>
    <запись>Lorem Ipsum 1
    <запись>Lorem Ipsum 2


навигация.xslt

Теперь пишем простенький шаблон который из файла 'журнал.xml' сформирует xHTML список со ссылками на другие страницы.

Файл: 'xslt/навигация.xslt'




    
    
        
  • На этом этапе страницы блога готовы к заполнению и просмотру.


    перенаправление

    Теперь нам нужно посетителей перенаправить на последнюю запись в журнале.


    index.html

    К сожалению в IPFS пока не возможно сделать страницей поумолчанию что то кроме index.html. Поэтому сделаем в ней простое перенаправление на XML страницу.

    Задача этого файла перенаправить пользователя на страницу 'журнал.xml'.

    Файл: 'index.html'

    
    
        
            Перенаправление
            
            
            
        
        
            
            Перенаправление на:
            "журнал"
        
    

    Это HTML оборотень. Он правильный XML и HTML одновременно. Это нам пригодится дальше.


    журнал.xslt

    'журнал.xml' при открытии в браузере вызывает шаблон 'журнал.xslt'. Тот в свою очередь берёт первую запись из 'журнал.xml' и переиспользуя 'index.html' перенаправляет на первую запись.

    Файл: 'xslt/журнал.xslt'

    
    
    
        
    
        
    
        
            
            
        
    
        
        
            
                
            
        
    
        
    
        
        
            
            
    
            
            
        
    
        
        
            
                
            
        
    
    

    Шаблон 'журнал.xslt' можно переработать так что он будет отображать ленту записей вместо простого перенаправления.


    локальное тестирование

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


    Firefox


    1. создаём отдельный профиль
    2. на странице about:config установить пункт security.fileuri.strict_origin_policy в false


    Chrome


    1. создаём отдельный профиль
    2. запускаем с дополнительным флагом --allow-file-access-from-files


    Загрузка в IPFS

    Перед загрузкой естественно надо заполнить блог.


    Генерируем ID для блога

    Нам нужно сгенерировать новый уникальный ключь который мы будем использовать для публикации в блог.

    ipfs key gen -t rsa blog

    В результате будет ID блога


    загружаем


    1. Загружаем блог в ipfs

      ipfs add -r -s rabin --inline --raw-leaves --fscache <каталог блога>

      -r — загружаем каталог
      -s rabin — полезно для дедупликации больших jpeg, mp3 и других файлов в которых есть возможность менять метаданные.
      --inline — встраивает микро блоки в родительский блок.
      --raw-leaves — добавляет совместимость с загрузкой в режиме --nocopy который позволяет загружать большие файлы не копируя их в репозитарий.
      --fscache — если блок уже есть в репозитарии то он не будет копироваться в него заново.


    2. Привязываем хеш полученный на первом этапе к ID блога.

      ipfs name publish -k blog <хеш>


    проверяем

    В браузере открываем два адреса:

    http://127.0.0.1:8080/ipfs/<хеш>
    http://127.0.0.1:8080/ipns/

    И глобально:

    http://gateway.ipfs.io/ipfs/<хеш>
    http://gateway.ipfs.io/ipns/

    Соответственно по хешу будет доступна только определённая версия блога. А по ID самая новая загруженная пользователем версия.

    Готово.


    Заключение

    Естественно дизайн и функциональность этого блога можно и нужно развивать под потребности пользователя. Я задал некоторую базу от которой можно развиваться дальше.


    Ссылки

    Хороший справочник по XSLT
    Код на GitHub

    © Habrahabr.ru