mirror of
https://github.com/kremalicious/blog.git
synced 2025-02-14 21:10:25 +01:00
commit
44b57208c1
23
Gemfile
23
Gemfile
@ -1,12 +1,19 @@
|
|||||||
# A sample Gemfile
|
# A sample Gemfile
|
||||||
source "https://rubygems.org"
|
source "https://rubygems.org"
|
||||||
|
|
||||||
# gem "rails"
|
group :development do
|
||||||
gem 'jekyll', '1.5.1'
|
|
||||||
gem 'mini_magick', '>=3.6.0'
|
gem 'jekyll'
|
||||||
gem 'fileutils', '>=0.7'
|
gem 'jekyll-sitemap'
|
||||||
|
gem 'jekyll-timeago'
|
||||||
|
gem 'rouge'
|
||||||
|
gem 'mini_magick'
|
||||||
|
gem 'fileutils'
|
||||||
|
# for faster LSI generation
|
||||||
|
#gem 'gsl'
|
||||||
|
# from http://tonyarnold.com/2014/03/27/speeding-up-jekylls-latent-semantic-mapping.html
|
||||||
|
gem 'narray', :git => "https://github.com/tonyarnold/narray"
|
||||||
|
gem 'gsl', :git => "https://github.com/tonyarnold/rb-gsl"
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
# for faster LSI generation
|
|
||||||
# from http://tonyarnold.com/2014/03/27/speeding-up-jekylls-latent-semantic-mapping.html
|
|
||||||
gem 'narray', :git => "https://github.com/tonyarnold/narray"
|
|
||||||
gem 'gsl', :git => "https://github.com/tonyarnold/rb-gsl"
|
|
@ -107,8 +107,8 @@ module.exports = function(grunt){
|
|||||||
],
|
],
|
||||||
'<%= config.site %>/<%= config.assets.js %>/kremalicious3.min.js': [
|
'<%= config.site %>/<%= config.assets.js %>/kremalicious3.min.js': [
|
||||||
'bower_components/jquery/dist/jquery.js',
|
'bower_components/jquery/dist/jquery.js',
|
||||||
'bower_components/infinitescroll/index.js',
|
'bower_components/jquery-infinite-scroll/jquery.infinitescroll.js',
|
||||||
'bower_components/masonry/index.js',
|
'bower_components/masonry/dist/masonry.pkgd.js',
|
||||||
'bower_components/imagesloaded/imagesloaded.js',
|
'bower_components/imagesloaded/imagesloaded.js',
|
||||||
'bower_components/simpleJekyllSearch/index.js',
|
'bower_components/simpleJekyllSearch/index.js',
|
||||||
'bower_components/jquery.adaptive-background/index.js',
|
'bower_components/jquery.adaptive-background/index.js',
|
||||||
|
46
LICENSE
Normal file
46
LICENSE
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
---------------
|
||||||
|
Posts
|
||||||
|
---------------
|
||||||
|
|
||||||
|
All post content under `_src/_posts` is licensed under a
|
||||||
|
Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
|
||||||
|
License.
|
||||||
|
http://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||||
|
|
||||||
|
---------------
|
||||||
|
Photos & images
|
||||||
|
---------------
|
||||||
|
|
||||||
|
All photos & image assets under `_src/_media`, `_src/assets/img`, and
|
||||||
|
`assets sheet.psd` are plain ol' copyright.
|
||||||
|
|
||||||
|
Copyright (c) 2008–2014 Matthias Kretschmann
|
||||||
|
|
||||||
|
Don't care if you fork & play with it, but you're not allowed to publish
|
||||||
|
anything from it as a whole without my written permission.
|
||||||
|
|
||||||
|
---------------
|
||||||
|
Everything else
|
||||||
|
---------------
|
||||||
|
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2008–2014 Matthias Kretschmann
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
43
README.md
43
README.md
@ -3,7 +3,8 @@ kremalicious3
|
|||||||
|
|
||||||
> [kremalicious.com](http://kremalicious.com) based on [Jekyll](http://jekyllrb.com). Neat.
|
> [kremalicious.com](http://kremalicious.com) based on [Jekyll](http://jekyllrb.com). Neat.
|
||||||
|
|
||||||
[ ](https://www.codeship.io/projects/18092)
|
[ ](https://www.codeship.io/projects/18092) [](https://gemnasium.com/kremalicious/kremalicious3)
|
||||||
|
|
||||||
|
|
||||||
Requirements
|
Requirements
|
||||||
------------------
|
------------------
|
||||||
@ -51,3 +52,43 @@ Runs almost the same tasks as `grunt server` but puts everything into the `_buil
|
|||||||
```bash
|
```bash
|
||||||
grunt build
|
grunt build
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Licenses
|
||||||
|
------------------
|
||||||
|
|
||||||
|
### Posts
|
||||||
|
|
||||||
|
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/80x15.png" /></a><br />All post content under `_src/_posts` is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.
|
||||||
|
|
||||||
|
### Photos & images
|
||||||
|
|
||||||
|
All photos & image assets under `_src/_media`, `_src/assets/img`, and `assets sheet.psd` are plain ol' copyright.
|
||||||
|
|
||||||
|
Copyright (c) 2008–2014 Matthias Kretschmann
|
||||||
|
|
||||||
|
Don't care if you fork & play with it, but you're not allowed to publish anything from it as a whole without my written permission.
|
||||||
|
|
||||||
|
### Everything else
|
||||||
|
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2008–2014 Matthias Kretschmann
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
13
_config.yml
13
_config.yml
@ -21,7 +21,6 @@ email: m@kretschmann.io
|
|||||||
# --------------------
|
# --------------------
|
||||||
|
|
||||||
permalink: /:title
|
permalink: /:title
|
||||||
relative_permalinks: true
|
|
||||||
paginate: 15
|
paginate: 15
|
||||||
paginate_path: "/page/:num"
|
paginate_path: "/page/:num"
|
||||||
category_dir: "/"
|
category_dir: "/"
|
||||||
@ -33,7 +32,7 @@ category_title_prefix: ""
|
|||||||
|
|
||||||
future: false
|
future: false
|
||||||
markdown: redcarpet
|
markdown: redcarpet
|
||||||
pygments: true
|
highlighter: rouge
|
||||||
|
|
||||||
redcarpet:
|
redcarpet:
|
||||||
extensions: ['autolink', 'smart', 'hard_wrap']
|
extensions: ['autolink', 'smart', 'hard_wrap']
|
||||||
@ -44,10 +43,18 @@ redcarpet:
|
|||||||
|
|
||||||
source: ./_src
|
source: ./_src
|
||||||
destination: ./_site
|
destination: ./_site
|
||||||
exclude: ['styl', 'app.js']
|
exclude: ['assets/styl', 'app.js']
|
||||||
keep_files: ['media', 'gen']
|
keep_files: ['media', 'gen']
|
||||||
|
|
||||||
|
|
||||||
|
# Plugins
|
||||||
|
# --------------------
|
||||||
|
|
||||||
|
gems:
|
||||||
|
- jekyll-sitemap
|
||||||
|
- jekyll-timeago
|
||||||
|
|
||||||
|
|
||||||
# jekyll-picture-tag
|
# jekyll-picture-tag
|
||||||
# --------------------
|
# --------------------
|
||||||
|
|
||||||
|
@ -18,8 +18,17 @@
|
|||||||
</aside>
|
</aside>
|
||||||
</div>
|
</div>
|
||||||
<section class="footer-copyright" class="row">
|
<section class="footer-copyright" class="row">
|
||||||
<p>© 2007 – {{ site.time | date: "%Y" }} <a href="http://matthiaskretschmann.com" rel="me">Matthias Kretschmann</a>.</p>
|
|
||||||
<p class="license">Code snippets: <a rel="item-license" href="http://www.opensource.org/licenses/mit-license.php">MIT License</a>. Goodies: <a rel="item-license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">CC BY NC SA</a>. Hosted by <a href="http://www.mediatemple.net#a_aid=4f37f8fe3e47e" title="Media Temple">(mt)</a></p>
|
<p>© 2007 – {{ site.time | date: "%Y" }} <a href="http://matthiaskretschmann.com" rel="me">Matthias Kretschmann</a></p>
|
||||||
|
|
||||||
|
<p><a class="icon icon-github" href="https://github.com/kremalicious/kremalicious3">View source</a> ¦ Hosted by <a href="http://www.mediatemple.net#a_aid=4f37f8fe3e47e" title="Media Temple">(mt)</a></p>
|
||||||
|
|
||||||
|
<p class="license">
|
||||||
|
Posts & goodies: <a rel="item-license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">CC BY NC SA</a> ¦
|
||||||
|
Photos & images: © Copyright ¦
|
||||||
|
Code: <a rel="item-license" href="http://www.opensource.org/licenses/mit-license.php">MIT License</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
@ -1,80 +0,0 @@
|
|||||||
#
|
|
||||||
# https://gist.github.com/runemadsen/6263974
|
|
||||||
#
|
|
||||||
# modified
|
|
||||||
#
|
|
||||||
|
|
||||||
module Jekyll
|
|
||||||
module Paginate
|
|
||||||
|
|
||||||
class Pagination < Generator
|
|
||||||
def generate(site)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class CategoryPages < Generator
|
|
||||||
|
|
||||||
safe true
|
|
||||||
|
|
||||||
def generate(site)
|
|
||||||
|
|
||||||
site.pages.dup.each do |page|
|
|
||||||
paginate(site, page) if CategoryPager.pagination_enabled?(site.config, page)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
def paginate(site, page)
|
|
||||||
|
|
||||||
# sort categories by descending date of publish
|
|
||||||
category_posts = site.categories[page.data['category']].sort_by { |p| -p.date.to_f }
|
|
||||||
|
|
||||||
# calculate total number of pages
|
|
||||||
pages = CategoryPager.calculate_pages(category_posts, site.config['paginate'].to_i)
|
|
||||||
|
|
||||||
# iterate over the total number of pages and create a physical page for each
|
|
||||||
(1..pages).each do |num_page|
|
|
||||||
|
|
||||||
# the CategoryPager handles the paging and category data
|
|
||||||
pager = CategoryPager.new(site, num_page, category_posts, page.data['category'], pages)
|
|
||||||
|
|
||||||
if num_page > 1
|
|
||||||
newpage = Page.new(site, site.source, page.dir, page.name)
|
|
||||||
newpage.pager = pager
|
|
||||||
newpage.dir = File.join(page.dir, "/page/#{num_page}")
|
|
||||||
site.pages << newpage
|
|
||||||
else
|
|
||||||
page.pager = pager
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
class CategoryPager < Pager
|
|
||||||
|
|
||||||
attr_reader :category
|
|
||||||
|
|
||||||
def self.pagination_enabled?(config, page)
|
|
||||||
page.name == 'index.html' && page.data.key?('category') && !config['paginate'].nil?
|
|
||||||
end
|
|
||||||
|
|
||||||
# same as the base class, but includes the category value
|
|
||||||
def initialize(site, page, all_posts, category, num_pages = nil)
|
|
||||||
@category = category
|
|
||||||
super site, page, all_posts, num_pages
|
|
||||||
end
|
|
||||||
|
|
||||||
# use the original to_liquid method, but add in category info
|
|
||||||
alias_method :original_to_liquid, :to_liquid
|
|
||||||
def to_liquid
|
|
||||||
x = original_to_liquid
|
|
||||||
x['category'] = @category
|
|
||||||
x
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,311 +0,0 @@
|
|||||||
# Sitemap.xml Generator is a Jekyll plugin that generates a sitemap.xml file by
|
|
||||||
# traversing all of the available posts and pages.
|
|
||||||
#
|
|
||||||
# How To Use:
|
|
||||||
# 1) Copy source file into your _plugins folder within your Jekyll project.
|
|
||||||
# 2) Change modify the url variable in _config.yml to reflect your domain name.
|
|
||||||
# 3) Run Jekyll: jekyll --server to re-generate your site.
|
|
||||||
#
|
|
||||||
# Variables:
|
|
||||||
# * Change SITEMAP_FILE_NAME if you want your sitemap to be called something
|
|
||||||
# other than sitemap.xml.
|
|
||||||
# * Change the PAGES_INCLUDE_POSTS list to include any pages that are looping
|
|
||||||
# through your posts (e.g. "index.html", "archive.html", etc.). This will
|
|
||||||
# ensure that right after you make a new post, the last modified date will
|
|
||||||
# be updated to reflect the new post.
|
|
||||||
# * A sitemap.xml should be included in your _site folder.
|
|
||||||
# * If there are any files you don't want included in the sitemap, add them
|
|
||||||
# to the EXCLUDED_FILES list. The name should match the name of the source
|
|
||||||
# file.
|
|
||||||
# * If you want to include the optional changefreq and priority attributes,
|
|
||||||
# simply include custom variables in the YAML Front Matter of that file.
|
|
||||||
# The names of these custom variables are defined below in the
|
|
||||||
# CHANGE_FREQUENCY_CUSTOM_VARIABLE_NAME and PRIORITY_CUSTOM_VARIABLE_NAME
|
|
||||||
# constants.
|
|
||||||
#
|
|
||||||
# Notes:
|
|
||||||
# * The last modified date is determined by the latest from the following:
|
|
||||||
# system modified date of the page or post, system modified date of
|
|
||||||
# included layout, system modified date of included layout within that
|
|
||||||
# layout, ...
|
|
||||||
#
|
|
||||||
# Author: Michael Levin
|
|
||||||
# Site: http://www.kinnetica.com
|
|
||||||
# Distributed Under A Creative Commons License
|
|
||||||
# - http://creativecommons.org/licenses/by/3.0/
|
|
||||||
#
|
|
||||||
# Modified for Octopress by John W. Long
|
|
||||||
#
|
|
||||||
require 'rexml/document'
|
|
||||||
require 'fileutils'
|
|
||||||
|
|
||||||
module Jekyll
|
|
||||||
|
|
||||||
# Change SITEMAP_FILE_NAME if you would like your sitemap file
|
|
||||||
# to be called something else
|
|
||||||
SITEMAP_FILE_NAME = "sitemap.xml"
|
|
||||||
|
|
||||||
# Any files to exclude from being included in the sitemap.xml
|
|
||||||
EXCLUDED_FILES = ["index.xml", "robots.txt", "search.json"]
|
|
||||||
|
|
||||||
# Any files that include posts, so that when a new post is added, the last
|
|
||||||
# modified date of these pages should take that into account
|
|
||||||
PAGES_INCLUDE_POSTS = ["index.html"]
|
|
||||||
|
|
||||||
# Custom variable names for changefreq and priority elements
|
|
||||||
# These names are used within the YAML Front Matter of pages or posts
|
|
||||||
# for which you want to include these properties
|
|
||||||
CHANGE_FREQUENCY_CUSTOM_VARIABLE_NAME = "change_frequency"
|
|
||||||
PRIORITY_CUSTOM_VARIABLE_NAME = "priority"
|
|
||||||
|
|
||||||
class Post
|
|
||||||
attr_accessor :name
|
|
||||||
|
|
||||||
def full_path_to_source
|
|
||||||
File.join(@base, @name)
|
|
||||||
end
|
|
||||||
|
|
||||||
def location_on_server
|
|
||||||
"#{site.config['url']}#{url}/"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Page
|
|
||||||
attr_accessor :name
|
|
||||||
|
|
||||||
def full_path_to_source
|
|
||||||
File.join(@base, @dir, @name)
|
|
||||||
end
|
|
||||||
|
|
||||||
def location_on_server
|
|
||||||
location = "#{site.config['url']}#{url}"
|
|
||||||
location.gsub(/index.html$/, "")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Layout
|
|
||||||
def full_path_to_source
|
|
||||||
File.join(@base, @name)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Recover from strange exception when starting server without --auto
|
|
||||||
class SitemapFile < StaticFile
|
|
||||||
def write(dest)
|
|
||||||
begin
|
|
||||||
super(dest)
|
|
||||||
rescue
|
|
||||||
end
|
|
||||||
|
|
||||||
true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class SitemapGenerator < Generator
|
|
||||||
|
|
||||||
# Valid values allowed by sitemap.xml spec for change frequencies
|
|
||||||
VALID_CHANGE_FREQUENCY_VALUES = ["always", "hourly", "daily", "weekly",
|
|
||||||
"monthly", "yearly", "never"]
|
|
||||||
|
|
||||||
# Goes through pages and posts and generates sitemap.xml file
|
|
||||||
#
|
|
||||||
# Returns nothing
|
|
||||||
def generate(site)
|
|
||||||
sitemap = REXML::Document.new << REXML::XMLDecl.new("1.0", "UTF-8")
|
|
||||||
|
|
||||||
urlset = REXML::Element.new "urlset"
|
|
||||||
urlset.add_attribute("xmlns",
|
|
||||||
"http://www.sitemaps.org/schemas/sitemap/0.9")
|
|
||||||
|
|
||||||
@last_modified_post_date = fill_posts(site, urlset)
|
|
||||||
fill_pages(site, urlset)
|
|
||||||
|
|
||||||
sitemap.add_element(urlset)
|
|
||||||
|
|
||||||
# File I/O: create sitemap.xml file and write out pretty-printed XML
|
|
||||||
unless File.exists?(site.dest)
|
|
||||||
FileUtils.mkdir_p(site.dest)
|
|
||||||
end
|
|
||||||
file = File.new(File.join(site.dest, SITEMAP_FILE_NAME), "w")
|
|
||||||
formatter = REXML::Formatters::Pretty.new(4)
|
|
||||||
formatter.compact = true
|
|
||||||
formatter.write(sitemap, file)
|
|
||||||
file.close
|
|
||||||
|
|
||||||
# Keep the sitemap.xml file from being cleaned by Jekyll
|
|
||||||
site.static_files << Jekyll::SitemapFile.new(site, site.dest, "/", SITEMAP_FILE_NAME)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Create url elements for all the posts and find the date of the latest one
|
|
||||||
#
|
|
||||||
# Returns last_modified_date of latest post
|
|
||||||
def fill_posts(site, urlset)
|
|
||||||
last_modified_date = nil
|
|
||||||
site.posts.each do |post|
|
|
||||||
if !excluded?(post.name)
|
|
||||||
url = fill_url(site, post)
|
|
||||||
urlset.add_element(url)
|
|
||||||
end
|
|
||||||
|
|
||||||
path = post.full_path_to_source
|
|
||||||
date = File.mtime(path)
|
|
||||||
last_modified_date = date if last_modified_date == nil or date > last_modified_date
|
|
||||||
end
|
|
||||||
|
|
||||||
last_modified_date
|
|
||||||
end
|
|
||||||
|
|
||||||
# Create url elements for all the normal pages and find the date of the
|
|
||||||
# index to use with the pagination pages
|
|
||||||
#
|
|
||||||
# Returns last_modified_date of index page
|
|
||||||
def fill_pages(site, urlset)
|
|
||||||
site.pages.each do |page|
|
|
||||||
if !excluded?(page.name)
|
|
||||||
path = page.full_path_to_source
|
|
||||||
if File.exists?(path)
|
|
||||||
url = fill_url(site, page)
|
|
||||||
urlset.add_element(url)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Fill data of each URL element: location, last modified,
|
|
||||||
# change frequency (optional), and priority.
|
|
||||||
#
|
|
||||||
# Returns url REXML::Element
|
|
||||||
def fill_url(site, page_or_post)
|
|
||||||
url = REXML::Element.new "url"
|
|
||||||
|
|
||||||
loc = fill_location(page_or_post)
|
|
||||||
url.add_element(loc)
|
|
||||||
|
|
||||||
lastmod = fill_last_modified(site, page_or_post)
|
|
||||||
url.add_element(lastmod) if lastmod
|
|
||||||
|
|
||||||
if (page_or_post.data[CHANGE_FREQUENCY_CUSTOM_VARIABLE_NAME])
|
|
||||||
change_frequency =
|
|
||||||
page_or_post.data[CHANGE_FREQUENCY_CUSTOM_VARIABLE_NAME].downcase
|
|
||||||
|
|
||||||
if (valid_change_frequency?(change_frequency))
|
|
||||||
changefreq = REXML::Element.new "changefreq"
|
|
||||||
changefreq.text = change_frequency
|
|
||||||
url.add_element(changefreq)
|
|
||||||
else
|
|
||||||
puts "ERROR: Invalid Change Frequency In #{page_or_post.name}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if (page_or_post.data[PRIORITY_CUSTOM_VARIABLE_NAME])
|
|
||||||
priority_value = page_or_post.data[PRIORITY_CUSTOM_VARIABLE_NAME]
|
|
||||||
if valid_priority?(priority_value)
|
|
||||||
priority = REXML::Element.new "priority"
|
|
||||||
priority.text = page_or_post.data[PRIORITY_CUSTOM_VARIABLE_NAME]
|
|
||||||
url.add_element(priority)
|
|
||||||
else
|
|
||||||
puts "ERROR: Invalid Priority In #{page_or_post.name}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
url
|
|
||||||
end
|
|
||||||
|
|
||||||
# Get URL location of page or post
|
|
||||||
#
|
|
||||||
# Returns the location of the page or post
|
|
||||||
def fill_location(page_or_post)
|
|
||||||
loc = REXML::Element.new "loc"
|
|
||||||
loc.text = page_or_post.location_on_server
|
|
||||||
|
|
||||||
loc
|
|
||||||
end
|
|
||||||
|
|
||||||
# Fill lastmod XML element with the last modified date for the page or post.
|
|
||||||
#
|
|
||||||
# Returns lastmod REXML::Element or nil
|
|
||||||
def fill_last_modified(site, page_or_post)
|
|
||||||
path = page_or_post.full_path_to_source
|
|
||||||
|
|
||||||
lastmod = REXML::Element.new "lastmod"
|
|
||||||
date = File.mtime(path)
|
|
||||||
latest_date = find_latest_date(date, site, page_or_post)
|
|
||||||
|
|
||||||
if @last_modified_post_date == nil
|
|
||||||
# This is a post
|
|
||||||
lastmod.text = latest_date.iso8601
|
|
||||||
else
|
|
||||||
# This is a page
|
|
||||||
if posts_included?(page_or_post.name)
|
|
||||||
# We want to take into account the last post date
|
|
||||||
final_date = greater_date(latest_date, @last_modified_post_date)
|
|
||||||
lastmod.text = final_date.iso8601
|
|
||||||
else
|
|
||||||
lastmod.text = latest_date.iso8601
|
|
||||||
end
|
|
||||||
end
|
|
||||||
lastmod
|
|
||||||
end
|
|
||||||
|
|
||||||
# Go through the page/post and any implemented layouts and get the latest
|
|
||||||
# modified date
|
|
||||||
#
|
|
||||||
# Returns formatted output of latest date of page/post and any used layouts
|
|
||||||
def find_latest_date(latest_date, site, page_or_post)
|
|
||||||
layouts = site.layouts
|
|
||||||
layout = layouts[page_or_post.data["layout"]]
|
|
||||||
while layout
|
|
||||||
path = layout.full_path_to_source
|
|
||||||
date = File.mtime(path)
|
|
||||||
|
|
||||||
latest_date = date if (date > latest_date)
|
|
||||||
|
|
||||||
layout = layouts[layout.data["layout"]]
|
|
||||||
end
|
|
||||||
|
|
||||||
latest_date
|
|
||||||
end
|
|
||||||
|
|
||||||
# Which of the two dates is later
|
|
||||||
#
|
|
||||||
# Returns latest of two dates
|
|
||||||
def greater_date(date1, date2)
|
|
||||||
if (date1 >= date2)
|
|
||||||
date1
|
|
||||||
else
|
|
||||||
date2
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Is the page or post listed as something we want to exclude?
|
|
||||||
#
|
|
||||||
# Returns boolean
|
|
||||||
def excluded?(name)
|
|
||||||
EXCLUDED_FILES.include? name
|
|
||||||
end
|
|
||||||
|
|
||||||
def posts_included?(name)
|
|
||||||
PAGES_INCLUDE_POSTS.include? name
|
|
||||||
end
|
|
||||||
|
|
||||||
# Is the change frequency value provided valid according to the spec
|
|
||||||
#
|
|
||||||
# Returns boolean
|
|
||||||
def valid_change_frequency?(change_frequency)
|
|
||||||
VALID_CHANGE_FREQUENCY_VALUES.include? change_frequency
|
|
||||||
end
|
|
||||||
|
|
||||||
# Is the priority value provided valid according to the spec
|
|
||||||
#
|
|
||||||
# Returns boolean
|
|
||||||
def valid_priority?(priority)
|
|
||||||
begin
|
|
||||||
priority_val = Float(priority)
|
|
||||||
return true if priority_val >= 0.0 and priority_val <= 1.0
|
|
||||||
rescue ArgumentError
|
|
||||||
end
|
|
||||||
|
|
||||||
false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,109 +0,0 @@
|
|||||||
#
|
|
||||||
# jekyll-timeago
|
|
||||||
#
|
|
||||||
# https://github.com/markets/jekyll-timeago
|
|
||||||
#
|
|
||||||
|
|
||||||
module Jekyll
|
|
||||||
module Timeago
|
|
||||||
|
|
||||||
DAYS_PER = {
|
|
||||||
:days => 1,
|
|
||||||
:weeks => 7,
|
|
||||||
:months => 31,
|
|
||||||
:years => 365,
|
|
||||||
}
|
|
||||||
|
|
||||||
# Max level of detail
|
|
||||||
# years > months > weeks > days
|
|
||||||
# 1 year and 7 months and 2 weeks and 6 days
|
|
||||||
MAX_DEPTH_LEVEL = 4
|
|
||||||
|
|
||||||
# Default level of detail
|
|
||||||
# 1 month and 5 days, 3 weeks and 2 days, 2 years and 6 months
|
|
||||||
DEFAULT_DEPTH_LEVEL = 2
|
|
||||||
|
|
||||||
def timeago(input, depth = DEFAULT_DEPTH_LEVEL)
|
|
||||||
unless depth_allowed?(depth)
|
|
||||||
raise "Invalid depth level: #{depth.inspect}"
|
|
||||||
end
|
|
||||||
|
|
||||||
unless input.is_a?(Date) || input.is_a?(Time)
|
|
||||||
raise "Invalid input type: #{input.inspect}"
|
|
||||||
end
|
|
||||||
|
|
||||||
days_passed = (Date.today - Date.parse(input.to_s)).to_i
|
|
||||||
time_ago_to_now(days_passed, depth)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
# Days passed to time ago sentence
|
|
||||||
def time_ago_to_now(days_passed, depth)
|
|
||||||
return "today" if days_passed == 0
|
|
||||||
return "yesterday" if days_passed == 1
|
|
||||||
return "tomorrow" if days_passed == -1
|
|
||||||
|
|
||||||
future = days_passed < 0
|
|
||||||
slots = build_time_ago_slots(days_passed.abs, depth)
|
|
||||||
sentence = to_sentence(slots)
|
|
||||||
|
|
||||||
if future
|
|
||||||
"in #{sentence}"
|
|
||||||
else
|
|
||||||
"#{sentence} ago"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Builds time ranges: ['1 month', '5 days']
|
|
||||||
# - days_passed: integer in absolute
|
|
||||||
# - depth: level of detail
|
|
||||||
# - current_slots: built time slots
|
|
||||||
def build_time_ago_slots(days_passed, depth, current_slots = [])
|
|
||||||
return current_slots if depth == 0 || days_passed == 0
|
|
||||||
|
|
||||||
time_range = days_to_time_range(days_passed)
|
|
||||||
days = DAYS_PER[time_range]
|
|
||||||
num_elems = days_passed / days
|
|
||||||
range_type = if num_elems == 1
|
|
||||||
time_range.to_s[0...-1] # singularize
|
|
||||||
else
|
|
||||||
time_range.to_s
|
|
||||||
end
|
|
||||||
|
|
||||||
current_slots << "#{num_elems} #{range_type}"
|
|
||||||
pending_days = days_passed - (num_elems*days)
|
|
||||||
build_time_ago_slots(pending_days, depth - 1, current_slots)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Number of days to minimum period time which can be grouped
|
|
||||||
def days_to_time_range(days_passed)
|
|
||||||
case days_passed.abs
|
|
||||||
when 0...7
|
|
||||||
:days
|
|
||||||
when 7...31
|
|
||||||
:weeks
|
|
||||||
when 31...365
|
|
||||||
:months
|
|
||||||
else
|
|
||||||
:years
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Validate if allowed level of detail
|
|
||||||
def depth_allowed?(depth)
|
|
||||||
(1..MAX_DEPTH_LEVEL).include?(depth)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Array to sentence: ['1 month', '1 week', '5 days'] => "1 month, 1 week and 5 days"
|
|
||||||
def to_sentence(slots)
|
|
||||||
if slots.length == 1
|
|
||||||
slots[0]
|
|
||||||
else
|
|
||||||
"#{slots[0...-1].join(', ')} and #{slots[-1]}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
Liquid::Template.register_filter(Jekyll::Timeago)
|
|
@ -35,7 +35,9 @@ They are completely styled with CSS3 so they're sharp on all screens no matter h
|
|||||||
|
|
||||||
Just drop in the kbdftw.css in your `head`:
|
Just drop in the kbdftw.css in your `head`:
|
||||||
|
|
||||||
{% highlight html %}<link rel="stylesheet" href="kbdfun.css">{% endhighlight %}
|
```html
|
||||||
|
<link rel="stylesheet" href="kbdfun.css">
|
||||||
|
```
|
||||||
|
|
||||||
If you want to use the Android key style, include roboto.css before:
|
If you want to use the Android key style, include roboto.css before:
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ var siteNavigation = {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// show search
|
// show search
|
||||||
$searcharea.removeClass('ready bounceOutUp').addClass('ready bounceInDown');
|
$searcharea.removeClass('ready bounceOutUp').addClass('ready slideDown');
|
||||||
$searchfield.focus();
|
$searchfield.focus();
|
||||||
if ( $searchfield.val().length ) {
|
if ( $searchfield.val().length ) {
|
||||||
$searchpop.removeClass('hide');
|
$searchpop.removeClass('hide');
|
||||||
@ -48,7 +48,7 @@ var siteNavigation = {
|
|||||||
|
|
||||||
// bind the hide controls
|
// bind the hide controls
|
||||||
$(document).bind('click.hidethepop', function() {
|
$(document).bind('click.hidethepop', function() {
|
||||||
$searcharea.removeClass('bounceInDown');
|
$searcharea.removeClass('slideDown');
|
||||||
$searchpop.addClass('hide');
|
$searchpop.addClass('hide');
|
||||||
|
|
||||||
// unbind the hide controls
|
// unbind the hide controls
|
||||||
@ -78,7 +78,7 @@ var siteNavigation = {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
// hide search area
|
// hide search area
|
||||||
$searcharea.removeClass('bounceInDown').addClass('bounceOutUp');
|
$searcharea.removeClass('slideDown').addClass('bounceOutUp');
|
||||||
$searchpop.addClass('hide');
|
$searchpop.addClass('hide');
|
||||||
|
|
||||||
// empty search field
|
// empty search field
|
||||||
|
@ -51,7 +51,7 @@ gpuacceleration()
|
|||||||
////////////////////////////////////
|
////////////////////////////////////
|
||||||
|
|
||||||
// Down
|
// Down
|
||||||
@keyframes bounceInDown
|
@keyframes slideDown
|
||||||
0%, 60%, 75%, 90%, 100%
|
0%, 60%, 75%, 90%, 100%
|
||||||
// http://cubic-bezier.com/#.06,.85,.54,1.39
|
// http://cubic-bezier.com/#.06,.85,.54,1.39
|
||||||
transition-timing-function: cubic-bezier(.06,.85,.54,1)
|
transition-timing-function: cubic-bezier(.06,.85,.54,1)
|
||||||
@ -59,20 +59,11 @@ gpuacceleration()
|
|||||||
0%
|
0%
|
||||||
transform: translate3d(0, -100px, 0)
|
transform: translate3d(0, -100px, 0)
|
||||||
|
|
||||||
60%
|
|
||||||
transform: translate3d(0, 20px, 0)
|
|
||||||
|
|
||||||
75%
|
|
||||||
transform: translate3d(0, -10px, 0)
|
|
||||||
|
|
||||||
90%
|
|
||||||
transform: translate3d(0, 5px, 0)
|
|
||||||
|
|
||||||
100%
|
100%
|
||||||
transform: none
|
transform: none
|
||||||
|
|
||||||
.bounceInDown
|
.slideDown
|
||||||
animation: bounceInDown .4s both
|
animation: slideDown .25s both
|
||||||
|
|
||||||
// Up
|
// Up
|
||||||
@keyframes bounceOutUp
|
@keyframes bounceOutUp
|
||||||
|
@ -160,8 +160,9 @@ button
|
|||||||
@extend .textcenter
|
@extend .textcenter
|
||||||
width: 16px
|
width: 16px
|
||||||
height: 16px
|
height: 16px
|
||||||
line-height: 1
|
line-height: 12px
|
||||||
font-size: $font-size-small
|
font-size: $font-size-small
|
||||||
|
padding: 0
|
||||||
border-radius: 16px
|
border-radius: 16px
|
||||||
display: block
|
display: block
|
||||||
background: $brand-grey-light
|
background: $brand-grey-light
|
||||||
|
@ -12,17 +12,17 @@
|
|||||||
.gravatar
|
.gravatar
|
||||||
margin-bottom: ($line-height-computed/2)
|
margin-bottom: ($line-height-computed/2)
|
||||||
|
|
||||||
.footer-description
|
|
||||||
@extend .h5
|
|
||||||
a
|
|
||||||
display: block
|
|
||||||
|
|
||||||
&,
|
&,
|
||||||
.footer-description
|
.footer-description
|
||||||
color: $text-color-light
|
color: $text-color-light
|
||||||
line-height: $line-height-computed
|
line-height: $line-height-computed
|
||||||
|
|
||||||
.footer-copyright
|
.footer-description
|
||||||
|
@extend .h5
|
||||||
|
a
|
||||||
|
display: block
|
||||||
|
|
||||||
|
.footer-copyright
|
||||||
@extend .divider-top
|
@extend .divider-top
|
||||||
padding-top: $line-height-computed
|
padding-top: $line-height-computed
|
||||||
padding-bottom: $line-height-computed
|
padding-bottom: $line-height-computed
|
||||||
@ -31,6 +31,11 @@
|
|||||||
margin-bottom: 0
|
margin-bottom: 0
|
||||||
font-size: $font-size-mini
|
font-size: $font-size-mini
|
||||||
|
|
||||||
|
.icon:before
|
||||||
|
font-size: inherit
|
||||||
|
margin-right: .2em
|
||||||
|
line-height: inherit
|
||||||
|
|
||||||
// Subscribe component
|
// Subscribe component
|
||||||
.subscribe
|
.subscribe
|
||||||
margin: $line-height-computed auto
|
margin: $line-height-computed auto
|
||||||
|
@ -202,7 +202,8 @@ strong,
|
|||||||
font-weight: 700
|
font-weight: 700
|
||||||
font-style: normal
|
font-style: normal
|
||||||
|
|
||||||
em
|
em,
|
||||||
|
.italic
|
||||||
font-style: italic
|
font-style: italic
|
||||||
|
|
||||||
cite
|
cite
|
||||||
@ -219,13 +220,23 @@ hr
|
|||||||
|
|
||||||
blockquote,
|
blockquote,
|
||||||
blockquote > p
|
blockquote > p
|
||||||
font-style: italic
|
@extend .italic
|
||||||
color: $text-color-light
|
color: $text-color-light
|
||||||
|
|
||||||
blockquote
|
blockquote
|
||||||
padding: 0 $line-height-computed
|
padding: 0 $line-height-computed
|
||||||
margin: 0 0 $line-height-computed
|
margin: 0 0 $line-height-computed
|
||||||
border-left: 2px solid $text-color-dimmed
|
position: relative
|
||||||
|
|
||||||
|
// quotation marks
|
||||||
|
&:before
|
||||||
|
content: "“"
|
||||||
|
font-size: 400%
|
||||||
|
font-family: "Hoefler Text", "Times New Roman", serif
|
||||||
|
color: rgba($text-color-dimmed, 40%)
|
||||||
|
position: absolute
|
||||||
|
left: -($line-height-computed/2)
|
||||||
|
top: -($line-height-computed/2)
|
||||||
|
|
||||||
p:last-child
|
p:last-child
|
||||||
margin-bottom: 0
|
margin-bottom: 0
|
||||||
|
@ -9,10 +9,8 @@ category: design
|
|||||||
|
|
||||||
<h1 class="page-title icon icon-{{ page.category }}">{{ page.category }}</h1>
|
<h1 class="page-title icon icon-{{ page.category }}">{{ page.category }}</h1>
|
||||||
|
|
||||||
{% for post in paginator.posts %}
|
{% for post in site.categories.design %}
|
||||||
|
|
||||||
{% include articles.html %}
|
{% include articles.html %}
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
---
|
---
|
||||||
layout: nil
|
|
||||||
---
|
---
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<feed xmlns="http://www.w3.org/2005/Atom">
|
<feed xmlns="http://www.w3.org/2005/Atom">
|
||||||
|
@ -9,10 +9,8 @@ category: goodies
|
|||||||
|
|
||||||
<h1 class="page-title icon icon-{{ page.category }}">{{ page.category }}</h1>
|
<h1 class="page-title icon icon-{{ page.category }}">{{ page.category }}</h1>
|
||||||
|
|
||||||
{% for post in paginator.posts %}
|
{% for post in site.categories.goodies %}
|
||||||
|
|
||||||
{% include articles.html %}
|
{% include articles.html %}
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
@ -8,10 +8,8 @@ category: personal
|
|||||||
|
|
||||||
<h1 class="page-title icon icon-{{ page.category }}">{{ page.category }}</h1>
|
<h1 class="page-title icon icon-{{ page.category }}">{{ page.category }}</h1>
|
||||||
|
|
||||||
{% for post in paginator.posts %}
|
{% for post in site.categories.personal %}
|
||||||
|
|
||||||
{% include articles.html %}
|
{% include articles.html %}
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
@ -8,10 +8,8 @@ category: photography
|
|||||||
|
|
||||||
<h1 class="page-title icon icon-{{ page.category }}">{{ page.category }}</h1>
|
<h1 class="page-title icon icon-{{ page.category }}">{{ page.category }}</h1>
|
||||||
|
|
||||||
{% for post in paginator.posts %}
|
{% for post in site.categories.photography %}
|
||||||
|
|
||||||
{% include articles.html %}
|
{% include articles.html %}
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
@ -12,10 +12,8 @@ category: photos
|
|||||||
<div class="masonry">
|
<div class="masonry">
|
||||||
<div class="grid-sizer"></div>
|
<div class="grid-sizer"></div>
|
||||||
|
|
||||||
{% for post in paginator.posts %}
|
{% for post in site.categories.photos %}
|
||||||
|
|
||||||
{% include articles.html %}
|
{% include articles.html %}
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -12,9 +12,9 @@
|
|||||||
"normalize-opentype.css": ">=0.1.2",
|
"normalize-opentype.css": ">=0.1.2",
|
||||||
"jquery": ">=2.0.3",
|
"jquery": ">=2.0.3",
|
||||||
"picturefill": ">=1.2.1",
|
"picturefill": ">=1.2.1",
|
||||||
"masonry": "http://masonry.desandro.com/masonry.pkgd.min.js",
|
"masonry": ">=3.1.5",
|
||||||
"imagesloaded": ">=3.1.0",
|
"imagesloaded": ">=3.1.0",
|
||||||
"infinitescroll": "https://raw.github.com/paulirish/infinite-scroll/master/jquery.infinitescroll.js",
|
"jquery-infinite-scroll": ">=2.0.2",
|
||||||
"simpleJekyllSearch": "https://raw.github.com/christian-fei/Simple-Jekyll-Search/master/jekyll-search.jquery.js",
|
"simpleJekyllSearch": "https://raw.github.com/christian-fei/Simple-Jekyll-Search/master/jekyll-search.jquery.js",
|
||||||
"jquery.adaptive-background": "https://raw.github.com/briangonzalez/jquery.adaptive-backgrounds.js/master/src/jquery.adaptive-backgrounds.js"
|
"jquery.adaptive-background": "https://raw.github.com/briangonzalez/jquery.adaptive-backgrounds.js/master/src/jquery.adaptive-backgrounds.js"
|
||||||
},
|
},
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"stylus": ">=0.45.0",
|
"stylus": ">=0.45.0",
|
||||||
"nib": ">=1.0.3",
|
"nib": ">=1.0.3",
|
||||||
"grunt": ">=0.4.1",
|
"grunt": ">=0.4.5",
|
||||||
"grunt-contrib-clean": ">=0.5.0",
|
"grunt-contrib-clean": ">=0.5.0",
|
||||||
"grunt-contrib-connect": ">=0.5.0",
|
"grunt-contrib-connect": ">=0.5.0",
|
||||||
"grunt-contrib-cssmin": ">=0.6.2",
|
"grunt-contrib-cssmin": ">=0.6.2",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user