2012-11-30 9 views
12

Cóż, jest to prawdopodobnie rodzaj głupiego pytania, ale zastanawiam się, czy istnieje sposób na wygenerowanie znaczników w Jekyll, aby zachować wcięcie znacznika Liquid. Świat nie kończy się, jeśli nie da się go rozwiązać. Jestem ciekawy, ponieważ podoba mi się, że mój kod wygląda porządnie, nawet jeśli został skompilowany. :)Wcięcie wygenerowanego znacznika w Jekyll/Ruby

Na przykład, że te dwie:

base.html:

<body> 
    <div id="page"> 
     {{content}} 
    </div> 
</body> 

index.md:

--- 
layout: base 
--- 
<div id="recent_articles"> 
    {% for post in site.posts %} 
    <div class="article_puff"> 
     <img src="/resources/images/fancyi.jpg" alt="" /> 
     <h2><a href="{{post.url}}">{{post.title}}</a></h2> 
     <p>{{post.description}}</p> 
     <a href="{{post.url}}" class="read_more">Read more</a> 
    </div> 
    {% endfor %}  
</div> 

problem jest importowany {{zawartość}} - znacznik jest renderowany bez powyższego indeksu.

Więc zamiast

<body> 
    <div id="page"> 
     <div id="recent_articles"> 
      <div class="article_puff"> 
       <img src="/resources/images/fancyimage.jpg" alt="" /> 
       <h2><a href="/articles/2012/11/14/gettin-down-with-rwd.html">Gettin' down with responsive web design</a></h2> 
       <p>Everyone's talking about it. Your client wants it. You need to code it.</p> 
       <a href="/articles/2012/11/14/gettin-down-with-rwd.html" class="read_more">Read more</a> 
      </div> 
     </div> 
    </div> 
</body> 

uzyskać

<body> 
    <div id="page"> 
     <div id="recent_articles"> 
<div class="article_puff"> 
<img src="/resources/images/fancyimage.jpg" alt="" /> 
    <h2><a href="/articles/2012/11/14/gettin-down-with-rwd.html">Gettin' down with responsive web design</a></h2> 
    <p>Everyone's talking about it. Your client wants it. You need to code it.</p> 
    <a href="/articles/2012/11/14/gettin-down-with-rwd.html" class="read_more">Read more</a> 
</div> 
</div> 
    </div> 
</body> 

Wydaje się tylko pierwszy wiersz jest wcięty poprawnie. Reszta zaczyna się na początku linii ... A więc wielowarstwowy import do szablonów? :)

+0

Czy ktoś kiedykolwiek wymyślił rozwiązanie, które bezpośrednio produkuje odpowiednio wcięty znacznik? – mb21

Odpowiedz

13

stosując ciecz Filtr

Udało mi się to zrobić przy użyciu filtra cieczy. Jest kilka zastrzeżeń:

  • Twój wkład musi być czysty. Miałem kilka kręconymi cudzysłowami i niedrukowanymi znakami, które wyglądały jak spacja w kilku plikach (copypasta z Worda lub innych) i widziałem "Niepoprawną sekwencję bajtów w UTF-8" jako błąd Jekyll.

  • Może to spowodować pewne problemy. Używałem ikon <i class="icon-file"></i> z twitter bootstrap. Zastąpił on pusty tag przez <i class="icon-file"/>, a bootstrap tego nie polubił. Dodatkowo wkręca się w mojej treści oktoberty {% codeblock %}. Nie zastanawiałem się dlaczego.

  • ile będzie to wyczyścić wyjście zmiennej cieczy takich jak {{ content }} rzeczywistości nie rozwiązuje problemu w oryginalnym poście, który ma wcięcie html w kontekście otaczającej html. Zapewni to dobrze sformatowany html, ale jako fragment, który nie będzie wcięty względem znaczników nad fragmentem.Jeśli chcesz sformatować wszystko w kontekście, użyj zadania Rake zamiast filtra.

-

require 'rubygems' 
require 'json' 
require 'nokogiri' 
require 'nokogiri-pretty' 

module Jekyll 
    module PrettyPrintFilter 
    def pretty_print(input) 
     #seeing some ASCII-8 come in 
     input = input.encode("UTF-8") 

     #Parsing with nokogiri first cleans up some things the XSLT can't handle 
     content = Nokogiri::HTML::DocumentFragment.parse input 
     parsed_content = content.to_html 

     #Unfortunately nokogiri-pretty can't use DocumentFragments... 
     html = Nokogiri::HTML parsed_content 
     pretty = html.human 

     #...so now we need to remove the stuff it added to make valid HTML 
     output = PrettyPrintFilter.strip_extra_html(pretty) 
     output 
    end 

    def PrettyPrintFilter.strip_extra_html(html) 
     #type declaration 
     html = html.sub('<?xml version="1.0" encoding="ISO-8859-1"?>','') 

     #second <html> tag 
     first = true 
     html = html.gsub('<html>') do |match| 
     if first == true 
      first = false 
      next 
     else 
      '' 
     end 
     end 

     #first </html> tag 
     html = html.sub('</html>','') 

     #second <head> tag 
     first = true 
     html = html.gsub('<head>') do |match| 
     if first == true 
      first = false 
      next 
     else 
      '' 
     end 
     end 

     #first </head> tag 
     html = html.sub('</head>','') 

     #second <body> tag 
     first = true 
     html = html.gsub('<body>') do |match| 
     if first == true 
      first = false 
      next 
     else 
      '' 
     end 
     end 

     #first </body> tag 
     html = html.sub('</body>','') 

     html 
    end 
    end 
end 

Liquid::Template.register_filter(Jekyll::PrettyPrintFilter) 

Korzystanie zadania Rake

Używam zadanie w moim Rakefile do całkiem wydrukować wyjście po stronie Jekyll został wygenerowany.

require 'nokogiri' 
require 'nokogiri-pretty' 

desc "Pretty print HTML output from Jekyll" 
task :pretty_print do 
    #change public to _site or wherever your output goes 
    html_files = File.join("**", "public", "**", "*.html") 

    Dir.glob html_files do |html_file| 
    puts "Cleaning #{html_file}" 

    file = File.open(html_file) 
    contents = file.read 

    begin 
     #we're gonna parse it as XML so we can apply an XSLT 
     html = Nokogiri::XML(contents) 

     #the human() method is from nokogiri-pretty. Just an XSL transform on the XML. 
     pretty_html = html.human 
    rescue Exception => msg 
     puts "Failed to pretty print #{html_file}: #{msg}" 
    end 

    #Yep, we're overwriting the file. Potentially destructive. 
    file = File.new(html_file,"w") 
    file.write(pretty_html) 

    file.close 
    end 
end 
+0

istnieje sposób na wcięcie tylko zawartość elementu "body", ale pozostawiając dodatkowe znaki nowej linii dla czytelności? – fcalderan

+0

Można jawnie wykonać transformację XSL zgodnie z opisem tutaj: http://stackoverflow.com/questions/1898829/how-do-i-pretty-print-html-with-nokogiri, a następnie dostosować XSLT według potrzeb. – bwest

0

Możemy to osiągnąć, pisząc niestandardowy filtr cieczy, aby uporządkować html, a następnie wykonując {{content | tidy }}, aby uwzględnić kod HTML.

Szybkie wyszukiwanie suggests, że rubinowy, czysty klejnot może nie zostać utrzymany, ale nokogiri jest drogą do zrobienia. Będzie to oczywiście oznaczało zainstalowanie klejnotu nokogiri.

Zobacz advice on writing liquid filters i Jekyll example filters.

Przykładem może wyglądać mniej więcej tak: w _plugins, dodać skrypt o nazwie schludny-html.rb zawierającą:

require 'nokogiri' 
module TextFilter 
    def tidy(input) 
    desired = Nokogiri::HTML::DocumentFragment.parse(input).to_html 
    end 
end 
Liquid::Template.register_filter(TextFilter) 

(Nietestowane)

+0

Po prostu próbowałem tego podejścia, ale tekst jest nadal unindented – fcalderan