Git Product home page Git Product logo

jekyll-nada's Introduction

Jekyll Nada

I have come here to chew bubblegum and kick ass ... and I'm all out of bubblegum.

About

A glorified Jekyll include tag.

I wrote this plugin to help me manage embedding of different types of media (<img>, <iframe>, HTML5 <audio> and <video>, Flash, etc.) in post pages.

The functionality of this plugin is very similar to the default Jekyll {% include %} tag, except that I've added the ability to combine tag, front-matter and site.config variables (where the former will trump the latter if there are duplicate variables).

Before this plugin, I had written these ... Long story short, I hated that all of the HTML was mixed in with the logic.

This plugin allows me to utilize liquid tags to do all the HTML bits and the plugin handles the variable normalization and other non-HTML logic bits.

Check out the usage section below for more information.

Installation

Add this line to your application's Gemfile:

gem 'jekyll-nada', :git => 'git://github.com/mhulse/jekyll-nada.git'

... and then execute:

$ bundle install

Create a new file in you _plugins/ folder named nada.rb with these contents:

# https://github.com/mhulse/jekyll-nada
require 'jekyll-nada'

OR, even better, add the following to your site's _config.yml:

gems:
  - jekyll-nada

Usage

Starting with _config.yml, you can add global defaults like so:

nada:
  wrap: "scroll"

Next, here's an example post:

---
layout: "post"
title: "My fake post"
date: "2004-05-03 21:10:04"
fig1:
  image: "foo.png"
  caption: "The quick brown fox hxy jumps over the lazy dog."
fig2:
  image: "foo2.gif"
  caption: "The quick brown fox hxy jumps over the lazy dog."
fig3:
  iframe: "http://maps.google.com/maps/ms?ie=UTF8&amp;hl=en&amp;msa=0&amp;msid=105976104673732766876.0004733e85b59d0ddcba6&amp;t=k&amp;ll=46.06983,15.325928&amp;spn=20.139199,49.63623&amp;output=embed"
  caption: "The **quick** brown _fox_ hxy jumps over the lazy dog."
fig4:
  video:
	- "foo1.webm"
	- "foo2.ogv"
	- "foo3.mp4"
  poster: "foo.png"
  caption: "The quick brown fox hxy jumps over the lazy dog."
fig5:
  audio:
	- foo1.ogg"
	- "foo2.mp3"
  caption: "The quick brown fox hxy jumps over the lazy dog."
---

{% nada fig1 %}

{% nada fig2 %}

{% nada fig3 width="100%" height="500" %}

{% nada fig4 class="x6" wrap="mm" %}

{% nada fig5 class="x6" wrap="" %}

As stated earlier, the tag variables override the front-matter variables, which override the _config.yml variables.

By defaut, Nada will load a template called nada.html from your _includes folder. The logic in this template is up to you, and should be based on your needs/front-matter.

Here's an example template:

<figure{% if nada.id %} id="{{ nada.id }}"{% endif %}{% if nada.class %} class="{{ nada.class }}"{% endif %}>
	
	{% if nada.wrap %}<div class="{{ nada.wrap }}">{% endif %}
		{% if nada.image %}
			{% if nada.lat and nada.lon %}
				<a href="https://www.google.com/maps/place/{{ nada.lat | cgi_escape }}+{{ nada.lon | cgi_escape }}" target="_blank" rel="nofollow">
			{% endif %}
			<img
				src="{{ site.uploads }}{{ nada.image }}"
				{% if nada.width %}width="{{ nada.width }}"{% endif %}
				{% if nada.height %}height="{{ nada.height }}"{% endif %}
				{% if nada.alt %}alt="{{ nada.alt }}"{% endif %}
			>
			{% if nada.lat and nada.lon %}
				</a>
			{% endif %}
		{% elsif nada.iframe %}
			<iframe
				src="{{ nada.iframe }}"
				{% if nada.width %}width="{{ nada.width }}"{% endif %}
				{% if nada.height %}height="{{ nada.height }}"{% endif %}
				marginheight="0"
				marginwidth="0"
				frameborder="0"
				scrolling="no"
				webkitallowfullscreen
				mozallowfullscreen
				allowfullscreen
			></iframe>
		{% elsif nada.video %}
			<video
				preload="none"
				{% if nada.poster %}poster="{{ site.uploads }}{{ nada.poster }}"{% endif %}
				width="{% if nada.width %}{{ nada.width }}{% else %}480{% endif %}"
				height="{% if nada.height %}{{ nada.height }}{% else %}270{% endif %}"
				controls
			>
				{% for file in nada.video %}
					{% assign ext = file | split: "." %}
					<source
						src="{{ site.uploads }}{{ file }}"
						type="{% case ext[1] %}{% when "mp4" %}video/mp4{% when "ogv" %}video/ogg{% when "webm" %}video/webm{% endcase %}"
					>
				{% endfor %}
			</video>
		{% elsif nada.audio %}
			<audio
				preload="none"
				controls
			>
				{% for file in nada.audio %}
					{% assign ext = file | split: "." %}
					<source
						src="{{ site.uploads }}{{ file }}"
						type="{% case ext[1] %}{% when "ogg" %}audio/ogg{% when "mp3" %}audio/mpeg{% endcase %}"
					>
				{% endfor %}
			</audio>
		{% elsif nada.flash %}
			<object type="application/x-shockwave-flash" data="{{ site.uploads }}{{ nada.flash }}" width="{{ nada.width }}" height="{{ nada.height }}">
				<param name="movie" value="{{ site.uploads }}{{ nada.flash }}">
				<param name="allowscriptaccess" value="always">
				<param name="menu" value="false">
				<param name="quality" value="high">
				<param name="flashvars" value="{{ nada.flashvars }}">
				{% if nada.base %}<param name="base" value="{% if nada.base contains "http" %}{{ nada.base }}{% else %}{{ site.uploads }}{{ nada.base }}{% endif %}">{% endif %}
				<p><a href="http://www.adobe.com/go/getflash"><img src="http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/legal/logo/160x41_get_flashplayer.gif" alt="Get Adobe Flash player"/></a></p>
			</object>
		{% endif %}
	{% if nada.wrap %}</div>{% endif %}
	
	{% if nada.caption %}<figcaption>{{ nada.caption | markdownify | trim }}</figcaption>{% endif %}
	
</figure>

While that may look like a lot of markup, the advantage here is that the same markup isn't crammed into the logic of a plugin file. Using a template puts full control into the hands of the end user.

Again, the default Jekyll include tag could do something very similar; the advantage to my plugin is the multi-level variable "normalization", which should make the Liquid logic easier to manage.

Lastly, if you don't want Liquid to parse the included template, append :raw to nada tag call, like so:

{% nada:raw template="test.html" foo="baz" %}

Contributing

Please read the CONTRIBUTING.md.

TL;DR:

  1. Fork it: http://github.com/<my-github-username>/nada/fork
  2. Create your feature branch: git checkout -b my-new-feature
  3. Commit your changes: git commit -am 'Add some feature.'
  4. Push to the branch: git push origin my-new-feature
  5. Create new pull request.

Feedback

Bugs? Constructive feedback? Questions?

Changelog

Release history

  • 2014-02-22   v0.0.1   Hello world!

LEGAL

Copyright © 2014 Micky Hulse

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with the License. You may obtain a copy of the License in the LICENSE file, or at:

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

:octocat:

jekyll-nada's People

Contributors

mhulse avatar

Stargazers

 avatar

Watchers

 avatar

jekyll-nada's Issues

Before Nada: older versions

Posting my older, related, plugins here, for archive's sake:

figure.rb:

# Inspired by:
# * https://github.com/opattison/jekyll-figure-image-tag
# * https://github.com/stewart/blog/blob/master/plugins/image_tag.rb
#
# Define in _config.yml:
#
# uploads: http://uploads.example.com/
#
# Example post front matter:
#
# ---
# image1:
#   src: 'foo.png'
#   caption: 'Lorem ipsum dolor sit.'
#   id: 'foo'
#   class: 'bar other'
#   wrap: 'baz'
#   alt: 'Billy'
# ---
#
# Example call:
#
# {% figure image1 %}
#
# Output:
#
# <figure id="foo" class="bar other"><div class="baz"><img src="http://uploads.mky.io/foo.png" alt="Billy"></div><figcaption>Lorem ipsum dolor sit.</figcaption></figure>
#
# @todo use templates from filesystem for the various types of output.

module Jekyll

  class FigureTag < Liquid::Tag

    def initialize(tag_name, text, tokens)

      super

      @text = text

    end

    def render(context)

      site = context.registers[:site]
      converter = site.getConverterImpl(::Jekyll::Converters::Markdown)

      _type = {
        'mp4' => 'video/mp4',
        'ogv' => 'video/ogg',
        'webm' => 'video/webm',
        'ogg' => 'audio/ogg',
        'mp3' => 'audio/mpeg',
      }

      if parts = @text.match(/([^\s]+)/) # Continue only if the assignmet of `parts` returns a match.

        _uploads = context.registers[:site].config['uploads']
        _figure = context.registers[:page][parts[1].strip]

        _alt = _figure['alt']
        _caption = _figure['caption']
        _class = _figure['class']
        _files = _figure['files']
        _height = _figure['height']
        _id = _figure['id']
        _kind = _figure['kind']
        _src = _figure['src']
        _width = _figure['width']
        _wrap = _figure['wrap']
        _poster = _figure['poster']

        _output = "<figure"
        _output += " id=\"#{_id}\"" if _id
        _output += " class=\"#{_class}\"" if _class
        _output += ">"
        _output += "<div class=\"#{_wrap}\">" if _wrap
        if _kind.to_s.downcase == "iframe"
          _output += "<iframe "
          _output += "width=\"#{_width}\" " if _width
          _output += "height=\"#{_height}\" " if _height
          _output += "src=\"#{_src}\" "
          _output += "marginheight=\"0\" marginwidth=\"0\" frameborder=\"0\" scrolling=\"no\" webkitallowfullscreen mozallowfullscreen allowfullscreen"
          _output += "></iframe>"
        elsif _kind.to_s.downcase == "audio"
          _output += "<audio preload=\"none\" controls>"
          _files.each do |_value|
            _ext = _value.match(/([^\.]+)$/)[1]
            _output += "<source src=\"#{_uploads}#{_value}\""
            _output += " type=\"#{_type[_ext]}\"" if _ext
            _output += ">"
          end
          _output += "</audio>"
        elsif _kind.to_s.downcase == "video"
          _output += "<video preload=\"none\""
          _output += " poster=\"#{_uploads}#{_poster}\"" if _poster
          _output += (_width) ? " width=\#{_width}\"" : " width=\"480\""
          _output += (_height) ? " height=\#{_height}\"" : " height=\"270\""
          _output += " controls>"
          _files.each do |_value|
            _ext = _value.match(/([^\.]+)$/)[1]
            _output += "<source src=\"#{_uploads}#{_value}\""
            _output += " type=\"#{_type[_ext]}\"" if _ext
            _output += ">"
          end
          _output += "</video>"
        else
          _output += "<img src=\"#{_uploads}#{_src}\" alt=\"#{_alt}\" width=\"#{_width}\" height=\"#{_height}\">"
        end
        _output += "</div>" if _wrap
        _output += "<figcaption>#{converter.convert(_caption)}</figcaption>" if _caption
        _output += "</figure>"

      else

        ""

      end

    end

  end

end

Liquid::Template.register_tag('figure', Jekyll::FigureTag)

fig.rb:

module Jekyll

  class Fig < Liquid::Tag

    def initialize(tag_name, markup, tokens)
      @markup = markup
      super
    end

    def render(context)

      render_markup = Liquid::Template.parse(@markup).render(context).gsub(/\\\{\\\{|\\\{\\%/, '\{\{' => '{{', '\{\%' => '{%')

      site = context.registers[:site]

      # Throw error if uploads not set.

      page = context.registers[:page]

      markup = /^(?:(?<key>[^\s]+)\s+)?\s*(?<attr>[\s\S]+)?$/.match(render_markup)

      settings = page[markup[:key]]

      instance = Marshal.load(Marshal.dump(settings))

      #puts instance

      attr = if markup[:attr]
        Hash[*markup[:attr].scan(/(?<attr>[^\s="]+)(?:="(?<value>[^"]+)")?\s?/).flatten]
      else
        {}
      end

      if instance['attr']
        attr = instance.delete('attr').merge(attr)
      end

      attr_string = attr.inject('') { |string, attrs|
        if attrs[1]
          string << "#{attrs[0]}=\"#{attrs[1]}\" "
        else
          string << "#{attrs[0]} "
        end
      }

      generate_figure(instance, attr_string, site)

    end

    def generate_figure(instance, attr_string, site)

      converter = site.getConverterImpl(::Jekyll::Converters::Markdown)
      uploads_fqdn = site.config['uploads']

      _output = "<figure"
      _output += " id=\"#{instance[:id]}\"" if instance[:id]
      _output += " class=\"#{instance[:class]}\"" if instance[:class]
      _output += ">"
      _output += "<div class=\"#{instance[:wrap]}\">" if instance[:wrap]

      # if _kind.to_s.downcase == "iframe"

      # elsif _kind.to_s.downcase == "audio"

      # elsif _kind.to_s.downcase == "video"

      # else

      # end

      _output += "</div>" if instance[:wrap]
      _output += "<figcaption>#{converter.convert(instance[:caption])}</figcaption>" if instance[:caption]
      _output += "</figure>"

    end

    def generate_image()

    end

    def generate_video()

    end

    def generate_audio()

    end

    def generate_iframe()

    end

    def generate_caption()

    end

  end

end

Liquid::Template.register_tag('fig', Jekyll::Fig)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.