LINUX.ORG.RU

Nanoc-а тред

 , nanoc,


1

1

Посматриваю на генератор статических сайтов Nanoc. Нравится тем, что не перегружен лишней функциональностью типа disqus, GA или содержания (TOC), которую некоторые другие чуть-ли не в ядро пихают, что атрибуты страниц можно самому придумывать и обрабатывать, еще вроде работает побыстрее jekyll.

Вопросы такие:

  • Как там получить список страниц? Допустим, надо отобразить на главной заголовки страниц из определенной папки, и еще какой-нибудь текст. eRuby в index.html вообще не обрабатывался, прямо так на странице показывался.
  • Есть ли какой-то ресурс по eRuby, где было бы множество простых примеров того, что может пригодиться на сайте?
  • Более сложная задача: можно ли сделать в Nanoc разделение на страницы как в jekyll? Что-бы указать количество записей на страницу, а он бы сделал все остальное и дал возможность использовать вещи типа paginator.total_pages, paginator.next_page?
  • Кто-нибудь им пользовался? Какие есть еще интересные варианты?
★★★★★

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

это ж просто шаблонизатор с плюшками, открой да посмотри что там под капотом и как

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

Зачем делать лишнюю работу, когда генераторов и так достаточно? Сейчас мне jekyll в общем хватает, хотя скорость генерации было бы хорошо увеличить: пока сайт маленький, компилируется за несколько секунд, но потом может стать медленнее. И архитектура nanoc со стороны нравится, но при попытке углубиться возникают вопросы из ОП.

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

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

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

С первым проблема вроде решается: eRuby не компилировался из-за

compile '/**/*.html' do
  layout '/default.*'
end
в Rules, надо было добавить filer :erb. А в нужный файл в самом простом варианте --
<% @items.find_all('/blog/*').each do |item| %>
<%= item[:title] %>
<% end %>

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

И архитектура nanoc со стороны нравится, но при попытке углубиться возникают вопросы из ОП.

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

umren ★★★★★
()

Более сложная задача: можно ли сделать в Nanoc разделение на страницы как в jekyll?

google://nanoc+pagination, не?

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

Нашел pagination_helper, но судя по коду, он просто вставляет разметку, это я и сам могу сделать. Мне надо сделать автоматическое создание страниц с n элементов на каждой.

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

Накатал на скорую руку (сразу предупреждаю, я этот nanoc сегодня первый раз вижу, так что не уверен, что код получился идиоматическим).

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

Создаём новый сайт:

$ nanoc create sample && cd sample

Генерируем страницы для пагинации:

$ mkdir -p content/kittens
$ for i in {1..42}; do
cat > content/kittens/kitten-$(printf "%02d" $i).html <<CONTENT
---
title: "Kitten #$i"
---
<p>My favourite kitten #${i}:</p>
<img src="http://placekitten.com/450/450?image=$i" />
CONTENT
done

Ложим в lib/pagination.rb код пагинатора:

class Pagination
  attr_reader :page_count
  attr_reader :per_page
  attr_reader :items

  DSL_METHODS = %i(layout slug index)
  DSL_METHODS.each do |name|
    define_method(name) do |value = nil|
      if value.nil?
        instance_variable_get("@#{name}")
      else
        instance_variable_set("@#{name}", value)
      end
    end
  end

  def initialize(items, per_page)
    @items = items
    @per_page = per_page
    @page_count = (items.size / per_page.to_f).ceil
  end
end

class Page
  attr_reader :page_count
  attr_reader :per_page
  attr_reader :number
  attr_reader :items

  attr_accessor :previous
  attr_accessor :next
  attr_accessor :item

  def initialize(items, number, per_page, page_count)
    @items = items
    @number = number
    @per_page = per_page
    @page_count = page_count
  end
end

class Nanoc::RuleDSL::CompilerDSL
  def pagination_for(pattern, per_page: 10, &block)
    raise 'block not given' unless block_given?

    preprocess do
      items = @items.find_all(pattern)
      items = items.sort_by { |i| i[:filename] }
      pagination = Pagination.new(items, per_page)

      if block.arity.zero?
        pagination.instance_eval(&block)
      else
        yield pagination
      end

      Pagination::DSL_METHODS.each do |name|
        raise "#{name} not defined" if pagination.public_send(name).nil?
      end

      layout = @layouts[pagination.layout]
      raise "layout not found: #{pagination.layout}" unless layout
      layout = layout.raw_content

      slug = pagination.slug

      item_slices = pagination.items.each_slice(pagination.per_page)
      pages = item_slices.each_with_index.map do |page_items, index|
        number = index + 1

        page = Page.new(page_items, number, per_page, pagination.page_count)

        attrs = {
          page: page
        }
        identifier = format(slug, page: number)
        @items.create(layout, attrs, identifier)

        page.item = @items[identifier]

        page
      end

      pages.each_cons(2) do |(previous_page, current_page)|
        current_page.previous = previous_page
        previous_page.next = current_page
      end

      index_page = pages.first
      attrs = {
        page: index_page
      }
      @items.create(layout, attrs, pagination.index) if index_page
    end
  end
end

def paginate
  raise 'block not given' unless block_given?
  raise 'nothing to paginate' unless @item[:page]

  yield @item[:page]
end

include Nanoc::Helpers::LinkTo

Прописываем в Rules следующее (дефолт удаляем):

#!/usr/bin/env ruby

pagination_for '/kittens/kitten-*.html', per_page: 5 do
  layout '/kittens.html'
  index '/kittens/index.html'
  slug '/kittens/page/%{page}.html'
end

compile '/kittens/**/*.html' do
  layout '/default.html'
  filter :erb
  write item.identifier.to_s
end

compile '/**/*' do
  write item.identifier.to_s
end

layout '/**/*', :erb

Ложим в layouts/kittens.html:

<h1>My favourite kittens</h1>

<% paginate do |page| %>
  <ul>
    <% page.items.each do |kitten| %>
      <li>
        <%= link_to(kitten[:title], kitten.identifier.to_s) %>
      </li>
    <% end %>
  </ul>

  <nav>
    Displaying page <%= page.number %> of <%= page.page_count %>

    <ul>
      <% if page.previous %>
        <li><%= link_to('Previous', page.previous.item.identifier.to_s) %>
      <% end %>
      <% if page.next %>
        <li><%= link_to('Next', page.next.item.identifier.to_s) %>
      <% end %>
    </ul>
  </nav>
<% end %>

В итоге получаем:

  • N страниц /kittens/page/$i.html с M элементов каждая (M задаётся параметром per_page: для pagination_for, 10 по умолчанию), нумерация страниц начинается с нуля.
  • Страницу /kittens/index.html, которая идентична /kittens/page/1.html, то есть показывает первую страницу.

Как это выглядит у меня:

  • первая страница (/kittens/index.html a.k.a. /kittens/page/1.html), она содержит ссылку на следующую страницу: https://i.imgur.com/AvUDZBe.png
  • последняя страница (/kittens/page/9.html), она содержит ссылку на предыдущую страницу: https://i.imgur.com/NuEUqU4.png
  • страница где-то посередине (/kittens/page/5.html), она содержит ссылки на предыдущую и следующую страницы: https://i.imgur.com/ugUp5kY.png
  • страница самого ресурса (/kittens/kitten-09.html): https://i.imgur.com/CmT3D5w.png
theNamelessOne ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.