如何使用生成器刮取页面内容?

时间:2016-04-24 09:36:23

标签: jekyll

我有一个博客,每个帖子都有一堆图片和视频。我希望能够使用一些关键字标记每个关键字,然后根据标记填充一组页面。例如,转到for n in uNames: df[n+'.S_HOLIDAY']=np.NaN 会列出标有/photos/car/的所有图片。

我现在使用一个简单的插件包含图片和视频,基本上只有渲染功能。我想我可以在那里添加标签。

但是我怎样才能让杰基尔'刮掉'我的页面并用图像填充页面?

1 个答案:

答案 0 :(得分:1)

简短回答是: 这很棘手

但为什么?

imgWithTags-tag这样的自定义{% img cookie-monster.png tag2,tag3 %}液体标签可以做两件事:

  • 渲染html标记
  • 商店标签 - > site.taggedImage变量中的图像关联

由于此标记可用于任何帖子,页面或集合文档,因此site.taggedImage变量仅在渲染过程后才会完成。

渲染过程完成后,我们可以抓住:site, :post_render钩子来处理我们的数据并创建标签页。

但是在这里,我们再也不能依赖{tag for p in tagPages%} ...... {%endfor%}来自动生成指向我们网页的链接:渲染完成。

技巧可以是手动维护链接数据文件,以便能够生成带有这样的循环的链接{% for p in site.data.tagPages %}...{% endfor %}

让我们试一试

注意:这仅适用于Jekyll 3.1.x版(不是3.0.x)

_plugins / imgWithTags-tag.rb

module Jekyll
  class ImgWithTags < Liquid::Tag

    # Custom liquid tag for images with tags
    # syntax : {% img path/to/img.jpg coma, separated, tags %}
    # tags are optionnal
    #
    # This plugin does two things :
    #   it renders html tag <a href='url'><img src='url' /></a>
    #   it stores tags -> images associations in site.config['images-tags']

    Syntax = /^(?<image_src>[^\s]+\.[a-zA-Z0-9]{3,4})\s*(?<tags>[\s\S]+)?$/

    def initialize(tag_name, markup, tokens)
      super
      if markup =~ Syntax then
        @url = $1
        @tags = $2.split(",").collect!{|tag| tag.strip } if !$2.nil?
      else
        raise "Image Tag can't read this tag. Try {% img path/to/img.jpg [coma, separated, tags] %}."
      end
    end

    def render(context)
      storeImgTags(context) if defined?(@tags) # store datas if we have tags
      site = context.registers[:site]
      imgTag = "<a href='#{ site.baseurl }/assets/#{@url}'><img src='#{ site.baseurl }/assets/#{@url}' /></a>"
    end

    def storeImgTags(context)
      # store tagged images datas in site config under the key site.config['images-tags']
      imagesTags = context.registers[:site].config['images-tags'] || {}

      @tags.each{|tag|
        slug = Utils.slugify(tag) # My tag -> my-tag
        # create a tag.slug entry if it doesn't exist
        imagesTags[slug] = imagesTags[slug] || {'name' => tag, 'images' => [] }
        # add image url in the tag.images array if the url doesn't already exist
        # this avoid duplicates
        imagesTags[slug]['images'] |= [@url.to_s]
      }
      context.registers[:site].config['images-tags'] = imagesTags
    end

  end
end

Liquid::Template.register_tag('img', Jekyll::ImgWithTags)

此时:呈现所有标记的图像链接,并存储所有标记 - >图像关联。

_plugins /钩位点后渲染imagesTagsPagesGenerator.rb

Jekyll::Hooks.register :site, :post_render do |site, payload|
  puts "++++++ site post_render hook : generating Images Tags pages"
  imagesTags = site.config['images-tags'] # datas stored by img tag
  linksDatas = site.data['imagesTagsLinks'] # tags pages link in data file
  pagesFolder = 'tag'

  imagesTags.each do |slug, datas|

    tagName = datas['name']
    tagImages = datas['images']
    pageDir =  File.join(pagesFolder, slug)

    tagPage = Jekyll::ImageTagPage.new(site, site.source, pageDir, tagName, tagImages)

    # as page rendering has already fired we do it again for our new pages
    tagPage.output = Jekyll::Renderer.new(site, tagPage, payload).run
    tagPage.trigger_hooks(:post_render)
    site.pages << tagPage

    # verbose check to see if we reference every tag url in out data file
    if !linksDatas.key?(tagName) # check if tag is in imagesTagsLinks data file
      puts "Warning ---------> #{tagName} not in data file"
      puts "Add : #{tagName}: #{tagPage.url}"
      puts "in data/imagesTagsLinks.yml"
      puts
    else
      if tagPage.url != linksDatas[tagName] then # check if url is correct in imagesTagsLinks data file
        puts "Warning ---------> incorrect url for '#{tagName}'"
        puts "Replace : #{tagName}: #{linksDatas[tagName]}"
        puts "by      : #{tagName}: #{tagPage.url}"
        puts "in data/imagesTagsLinks.yml"
        puts
      end
    end

  end
  puts "++++++ END site post_render hook"
end

module Jekyll
  class ImageTagPage < Page
    def initialize(site, base, dir, tag, images)
      @site = site
      @base = base
      @dir = dir
      @name = 'index.html'

      self.process(@name)
      self.read_yaml(File.join(base, '_layouts'), 'tag_index.html')
      self.data['tag'] = tag
      self.data['images'] = images
      self.data['title'] = "Images for tag : #{tag}"
    end
  end
end

标签布局页面

_layouts / tag_index.html

---
layout: default
---
<h2>{{ page.title }}</h2>
{% for i in page.images %}
  <img src="{{ site.baseurl }}/assets/{{ i }}" alt="Image tagged {{ page.tag }}">
{% endfor %}

在这里,一切都准备好生成标签页。

我们现在可以执行jekyll build并查看详细输出,只需告诉我们在_data/imagesTagsLinks.yml中添加的内容

_data / imagesTagsLinks.yml

tag1: /tag/tag1/
tag2: /tag/tag2/
...

我们现在可以通过简单的

链接到我们的标签页面
{% for t in site.data.imagesTagsLinks %}
  <li><a href="{{ site.baseurl }}{{ t[1] }}">{{ t[0] }}</a></li>
{% endfor %}

我告诉过你:这很棘手。但它完成了这项工作。

注意:可以改进img代码,为什么不改进figure代码?