octopod-exe 0.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +8 -0
- data/Rakefile +11 -0
- data/assets/_config.yml.sample +48 -0
- data/assets/_includes/disqus_count.html +13 -0
- data/assets/_includes/disqus_thread.html +13 -0
- data/assets/_includes/flattr_loader.html +14 -0
- data/assets/_includes/isso_thread.html +6 -0
- data/assets/_includes/post.html +20 -0
- data/assets/_includes/post_header.html +17 -0
- data/assets/_includes/post_line.html +3 -0
- data/assets/_includes/sidebar.html +109 -0
- data/assets/_includes/tweet_us.html +3 -0
- data/assets/_layouts/default.html +86 -0
- data/assets/_layouts/feed.xml +107 -0
- data/assets/_layouts/jsonfeed.json +48 -0
- data/assets/_layouts/page.html +15 -0
- data/assets/_layouts/player_index.html +36 -0
- data/assets/_layouts/post.html +10 -0
- data/assets/_layouts/with_twitter_card.html +98 -0
- data/assets/_posts/2016-03-22-episode0.md +24 -0
- data/assets/_sass/_overrides.scss +68 -0
- data/assets/apple-touch-icon-precomposed.png +0 -0
- data/assets/episodes.m4a.rss +5 -0
- data/assets/episodes.mp3.rss +5 -0
- data/assets/episodes.ogg.rss +5 -0
- data/assets/episodes/episode0.m4a +0 -0
- data/assets/episodes/episode0.mp3 +0 -0
- data/assets/episodes/episode0.ogg +0 -0
- data/assets/favicon.ico +0 -0
- data/assets/feed.m4a.json +5 -0
- data/assets/feed.mp3.json +5 -0
- data/assets/feed.ogg.json +5 -0
- data/assets/general_feed.xml +30 -0
- data/assets/img/favicon.ico +0 -0
- data/assets/img/logo-360x360.png +0 -0
- data/assets/img/logo-itunes.jpg +0 -0
- data/assets/img/logo.jpg +0 -0
- data/assets/img/logo/android-icon-144x144.png +0 -0
- data/assets/img/logo/android-icon-192x192.png +0 -0
- data/assets/img/logo/android-icon-36x36.png +0 -0
- data/assets/img/logo/android-icon-48x48.png +0 -0
- data/assets/img/logo/android-icon-72x72.png +0 -0
- data/assets/img/logo/android-icon-96x96.png +0 -0
- data/assets/img/logo/apple-icon-114x114.png +0 -0
- data/assets/img/logo/apple-icon-120x120.png +0 -0
- data/assets/img/logo/apple-icon-144x144.png +0 -0
- data/assets/img/logo/apple-icon-152x152.png +0 -0
- data/assets/img/logo/apple-icon-180x180.png +0 -0
- data/assets/img/logo/apple-icon-57x57.png +0 -0
- data/assets/img/logo/apple-icon-60x60.png +0 -0
- data/assets/img/logo/apple-icon-72x72.png +0 -0
- data/assets/img/logo/apple-icon-76x76.png +0 -0
- data/assets/img/logo/apple-icon-precomposed.png +0 -0
- data/assets/img/logo/apple-icon.png +0 -0
- data/assets/img/logo/browserconfig.xml +2 -0
- data/assets/img/logo/favicon-16x16.png +0 -0
- data/assets/img/logo/favicon-32x32.png +0 -0
- data/assets/img/logo/favicon-96x96.png +0 -0
- data/assets/img/logo/favicon.ico +0 -0
- data/assets/img/logo/manifest.json +41 -0
- data/assets/img/logo/ms-icon-144x144.png +0 -0
- data/assets/img/logo/ms-icon-150x150.png +0 -0
- data/assets/img/logo/ms-icon-310x310.png +0 -0
- data/assets/img/logo/ms-icon-70x70.png +0 -0
- data/assets/imprint.md +19 -0
- data/assets/index.md +14 -0
- data/bin/octopod +273 -0
- data/lib/jekyll-octopod.rb +11 -0
- data/lib/jekyll/date_de.rb +54 -0
- data/lib/jekyll/flattr_filters.rb +107 -0
- data/lib/jekyll/octopod_filters.rb +336 -0
- data/lib/jekyll/paged_feed_page.rb +22 -0
- data/lib/jekyll/paged_feed_page_generator.rb +20 -0
- data/lib/jekyll/podcast_player_page.rb +24 -0
- data/lib/jekyll/podcast_player_page_generator.rb +14 -0
- data/lib/jekyll/podigee_player_tag.rb +44 -0
- data/lib/jekyll/static_file.rb +20 -0
- data/lib/jekyll/update_config.rb +14 -0
- data/lib/octopod/version.rb +11 -0
- metadata +580 -0
@@ -0,0 +1,41 @@
|
|
1
|
+
{
|
2
|
+
"name": "App",
|
3
|
+
"icons": [
|
4
|
+
{
|
5
|
+
"src": "\/android-icon-36x36.png",
|
6
|
+
"sizes": "36x36",
|
7
|
+
"type": "image\/png",
|
8
|
+
"density": "0.75"
|
9
|
+
},
|
10
|
+
{
|
11
|
+
"src": "\/android-icon-48x48.png",
|
12
|
+
"sizes": "48x48",
|
13
|
+
"type": "image\/png",
|
14
|
+
"density": "1.0"
|
15
|
+
},
|
16
|
+
{
|
17
|
+
"src": "\/android-icon-72x72.png",
|
18
|
+
"sizes": "72x72",
|
19
|
+
"type": "image\/png",
|
20
|
+
"density": "1.5"
|
21
|
+
},
|
22
|
+
{
|
23
|
+
"src": "\/android-icon-96x96.png",
|
24
|
+
"sizes": "96x96",
|
25
|
+
"type": "image\/png",
|
26
|
+
"density": "2.0"
|
27
|
+
},
|
28
|
+
{
|
29
|
+
"src": "\/android-icon-144x144.png",
|
30
|
+
"sizes": "144x144",
|
31
|
+
"type": "image\/png",
|
32
|
+
"density": "3.0"
|
33
|
+
},
|
34
|
+
{
|
35
|
+
"src": "\/android-icon-192x192.png",
|
36
|
+
"sizes": "192x192",
|
37
|
+
"type": "image\/png",
|
38
|
+
"density": "4.0"
|
39
|
+
}
|
40
|
+
]
|
41
|
+
}
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/assets/imprint.md
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
---
|
2
|
+
title: Imprint
|
3
|
+
layout: default
|
4
|
+
navigation: 1
|
5
|
+
---
|
6
|
+
|
7
|
+
# Media Owner and Content
|
8
|
+
|
9
|
+
... put in information here ...
|
10
|
+
|
11
|
+
# Links
|
12
|
+
|
13
|
+
... put in information here ...
|
14
|
+
|
15
|
+
|
16
|
+
# License
|
17
|
+
|
18
|
+
... use cc by as below or put in information here ...
|
19
|
+
[](http://creativecommons.org/licenses/by/4.0/)
|
data/assets/index.md
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
---
|
2
|
+
title: Episodes
|
3
|
+
layout: default
|
4
|
+
navigation: 0
|
5
|
+
---
|
6
|
+
{% assign post = site.posts.first %}
|
7
|
+
{% include post.html %}
|
8
|
+
|
9
|
+
{% assign current_post = site.posts.first %}
|
10
|
+
{% for post in site.posts -%}
|
11
|
+
{% unless post.url == current_post.url -%}
|
12
|
+
{% include post_line.html %}
|
13
|
+
{% endunless %}
|
14
|
+
{% endfor %}
|
data/bin/octopod
ADDED
@@ -0,0 +1,273 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# require "byebug"
|
3
|
+
PWD = Dir.pwd
|
4
|
+
|
5
|
+
GEM_DIR = Gem::Specification.find_by_name("jekyll-octopod").gem_dir
|
6
|
+
# HAS20170501 disgusting hack for development
|
7
|
+
# GEM_DIR = "/home/user/jekyll/jekyll-octopod/"
|
8
|
+
|
9
|
+
|
10
|
+
require 'rubygems'
|
11
|
+
require 'optparse'
|
12
|
+
require 'yaml'
|
13
|
+
require 'fileutils'
|
14
|
+
|
15
|
+
|
16
|
+
octopod_help = <<HELP
|
17
|
+
Octopod - podcast publishing for geeks
|
18
|
+
|
19
|
+
Basic Command Line Usage:
|
20
|
+
Standard Jekyll commands:
|
21
|
+
octopod b[uild] # . -> ./_site
|
22
|
+
octopod build <path to write generated site> # . -> <path>
|
23
|
+
octopod build <path to source> <path to write generated site> # <path> -> <path>
|
24
|
+
octopod import <importer name> <options> # imports posts using named import script
|
25
|
+
octopod setup # Setup blog to become podcast-aware, copy assets and default config
|
26
|
+
octopod s[erver] # Starts the server
|
27
|
+
|
28
|
+
Additional Octopod commands:
|
29
|
+
octopod episode # adds a template for a new episode
|
30
|
+
octopod deploy # deploys your site
|
31
|
+
|
32
|
+
See 'octopod <command> --help' for more information on a specific command.
|
33
|
+
|
34
|
+
Configuration is read from '<source>/_config.yml' but can be overridden
|
35
|
+
using the following options:
|
36
|
+
|
37
|
+
HELP
|
38
|
+
|
39
|
+
episode_help = <<EPISODE_HELP
|
40
|
+
octopod episode - generates a template to post your next episode
|
41
|
+
|
42
|
+
octopod episode [options] [audio file[, audio file]]
|
43
|
+
|
44
|
+
Configuration is read from '<source>/_config.yml' but can be overridden
|
45
|
+
using the following options:
|
46
|
+
|
47
|
+
EPISODE_HELP
|
48
|
+
|
49
|
+
deploy_help = <<DEPLOY_HELP
|
50
|
+
octopod deploy - deploys website via rsync
|
51
|
+
|
52
|
+
octopod deploy [path to write generated site] [options]
|
53
|
+
|
54
|
+
Configuration is read from '<source>/_config.yml' but can be overridden
|
55
|
+
using the following options:
|
56
|
+
|
57
|
+
DEPLOY_HELP
|
58
|
+
|
59
|
+
DEFAULT_EXT = '.md'
|
60
|
+
|
61
|
+
class OptionParser
|
62
|
+
alias_method :_octopod_banner=, :banner=
|
63
|
+
def banner=(_)
|
64
|
+
return ''
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def ok_failed(condition)
|
69
|
+
if (condition)
|
70
|
+
puts "OK"
|
71
|
+
else
|
72
|
+
puts "FAILED"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def write_file?(filename)
|
77
|
+
if File.exists?(filename)
|
78
|
+
unless ["Y","N"].include?(@answer)
|
79
|
+
puts ""
|
80
|
+
@answer = ask("File '#{filename}' already exists. Overwrite? Capitalized answer for ALL files.", ['y', 'Y', 'n', 'N'])
|
81
|
+
end
|
82
|
+
["Y", "y"].include?(@answer)
|
83
|
+
else
|
84
|
+
true
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def copy_file_or_create_dir(file)
|
89
|
+
filename = file.split(GEM_DIR + "/assets")[1]
|
90
|
+
if File.directory?(file)
|
91
|
+
FileUtils.mkdir(PWD + filename, {verbose: true}) unless File.exists?(PWD + filename)
|
92
|
+
else
|
93
|
+
if write_file?(PWD + filename)
|
94
|
+
FileUtils.cp(file, PWD + filename, {verbose: true})
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def ask(message, valid_options = nil)
|
100
|
+
if valid_options
|
101
|
+
answer = get_stdin("#{message} #{valid_options.to_s.gsub(/"/, '').gsub(/, /,'/')} ") while !valid_options.include?(answer)
|
102
|
+
else
|
103
|
+
answer = get_stdin(message)
|
104
|
+
end
|
105
|
+
answer
|
106
|
+
end
|
107
|
+
|
108
|
+
def get_stdin(message)
|
109
|
+
print message
|
110
|
+
STDIN.gets.chomp
|
111
|
+
end
|
112
|
+
|
113
|
+
if ARGV.size > 0 && (ARGV[0] == 'episode' || ARGV[0] == 'deploy' || ARGV[0] == 'setup')
|
114
|
+
options = YAML.load_file(File.join(PWD, '_config.yml'))
|
115
|
+
options['posts_dir'] = File.join(PWD, '_posts')
|
116
|
+
|
117
|
+
case ARGV[0]
|
118
|
+
|
119
|
+
when 'episode'
|
120
|
+
post_header = {
|
121
|
+
'title' => 'A Title',
|
122
|
+
'subtitle' => "A Subtle Subtitle",
|
123
|
+
'datum' => 'May 22nd, 2016',
|
124
|
+
'layout' => 'post',
|
125
|
+
'author' => options['author'],
|
126
|
+
'explicit' => options['explicit'] || 'no',
|
127
|
+
'duration' => "0:01:00",
|
128
|
+
'audio' => {
|
129
|
+
'm4a' => 'name.m4a',
|
130
|
+
'mp3' => 'name.mp3',
|
131
|
+
'ogg' => 'name.ogg'},
|
132
|
+
'chapters' => [
|
133
|
+
'00:00:00.000 Intro.',
|
134
|
+
'00:00:30.000 Outro.'
|
135
|
+
]
|
136
|
+
}
|
137
|
+
|
138
|
+
opts = OptionParser.new do |opts|
|
139
|
+
opts._octopod_banner = episode_help
|
140
|
+
|
141
|
+
opts.on("-a", "--author [AUTHOR]", "Name of post author") do |episode_author|
|
142
|
+
post_header['author'] = options['author'] = episode_author
|
143
|
+
end
|
144
|
+
|
145
|
+
opts.on("-c", "--chapters [chapter1,chapter2,...]", Array, "The episodes chapters.") do |episode_chapters|
|
146
|
+
warn episode_chapters.inspect
|
147
|
+
post_header['chapters'] = options['chapters'] = episode_chapters
|
148
|
+
end
|
149
|
+
|
150
|
+
opts.on("-d", "--duration [DURATION]", "Duration of the episode") do |episode_duration|
|
151
|
+
post_header['duration'] = options['duration'] = episode_duration.to_i
|
152
|
+
end
|
153
|
+
|
154
|
+
opts.on("-e", "--explicit [yes/no]", "Explicit rating for this episode (default: 'no')") do |episode_explicit|
|
155
|
+
post_header['explicit'] = options['explicit'] = episode_explicit
|
156
|
+
end
|
157
|
+
|
158
|
+
opts.on("--episode-cover [PATH]", "Path to the image that represents the episode.") do |episode_cover|
|
159
|
+
post_header['episode_cover'] = options['episode_cover'] = episode_cover
|
160
|
+
end
|
161
|
+
|
162
|
+
opts.on("-l", "--layout [LAYOUT]", "Layout to use (default: 'post')") do |episode_layout|
|
163
|
+
post_header['layout'] = options['layout'] = episode_layout
|
164
|
+
end
|
165
|
+
|
166
|
+
opts.on("-p", "--posts-dir [PATH]", "Path to the post directory (default: '_posts')") do |episode_posts_dir|
|
167
|
+
options['posts_dir'] = episode_posts_dir
|
168
|
+
end
|
169
|
+
|
170
|
+
opts.on("-s", "--subtitle [TEXT]", "Subtitle of the episode") do |episode_subtitle|
|
171
|
+
post_header['subtitle'] = options['subtitle'] = episode_subtitle
|
172
|
+
end
|
173
|
+
|
174
|
+
opts.on("--summary [TEXT]", "Summary of the episode") do |episode_summary|
|
175
|
+
post_header['summary'] = options['summary'] = episode_summary
|
176
|
+
end
|
177
|
+
|
178
|
+
opts.on("--tags [tag1,tag2,...]", Array, "Tags for the episode") do |episode_tags|
|
179
|
+
post_header['tags'] = options['tags'] = episode_tags
|
180
|
+
end
|
181
|
+
|
182
|
+
opts.on("-t", "--title [TEXT]", "Title of the episode") do |episode_title|
|
183
|
+
post_header['title'] = options['title'] = episode_title
|
184
|
+
end
|
185
|
+
end
|
186
|
+
opts.parse!
|
187
|
+
|
188
|
+
unless FileTest.directory?(options['posts_dir'])
|
189
|
+
abort("rake aborted: '#{options['posts_dir']}' directory not found.")
|
190
|
+
end
|
191
|
+
|
192
|
+
post_header['title'] = post_header['title'] || 'untitled'
|
193
|
+
slug = post_header['title'].downcase.strip.gsub(' ', '-').gsub(/[^\w-]/, '_')
|
194
|
+
date = Time.now.strftime('%Y-%m-%d')
|
195
|
+
|
196
|
+
filename = File.join(options['posts_dir'], "#{date}-#{slug}#{DEFAULT_EXT}")
|
197
|
+
|
198
|
+
abort() unless write_file?(filename)
|
199
|
+
|
200
|
+
open(filename, 'w') do |post|
|
201
|
+
post.puts post_header.to_yaml
|
202
|
+
post.puts '---'
|
203
|
+
post.puts "## {{ page.subtitle }}\n\n"
|
204
|
+
post.puts "{{ page | web_player_moderator:site }}\n\n"
|
205
|
+
post.puts "## Shownotes and Links\n\n* Note"
|
206
|
+
end
|
207
|
+
|
208
|
+
puts "Created new episode: #{filename}" if File.exists?(filename)
|
209
|
+
|
210
|
+
when 'deploy'
|
211
|
+
opts = OptionParser.new do |opts|
|
212
|
+
opts._octopod_banner = deploy_help
|
213
|
+
|
214
|
+
opts.on("--document-root [PATH]", "Path to the documwrite_fileent root on the remote machine") do |deploy_document_root|
|
215
|
+
options['document_root'] = deploy_document_root
|
216
|
+
end
|
217
|
+
|
218
|
+
opts.on("--rsync-delete", "Delete extraneous files from destination dir") do |deploy_rsync_delete|
|
219
|
+
options['rsync_delete'] = deploy_rsync_delete
|
220
|
+
end
|
221
|
+
|
222
|
+
opts.on("--ssh-host [USER@]<HOST>", "[User and] host of the destination machine") do |deploy_ssh_host|
|
223
|
+
options['ssh_host'] = deploy_ssh_host =~ /\A\w*@.*/ ? deploy_ssh_host : "#{ENV['USER']}@#{deploy_ssh_host}"
|
224
|
+
end
|
225
|
+
|
226
|
+
opts.on("--ssh-port [PORT]", "SSH port on the remote machine") do |deploy_ssh_port|
|
227
|
+
options['ssh_port'] = deploy_ssh_port.to_i
|
228
|
+
end
|
229
|
+
end
|
230
|
+
opts.parse!
|
231
|
+
|
232
|
+
options['public_dir'] = ARGV[1] ? ARGV[1] : File.join(PWD, '_site')
|
233
|
+
exclude = ""
|
234
|
+
if File.exists?('./rsync-exclude')
|
235
|
+
exclude = "--exclude-from '#{File.expand_path('./rsync-exclude')}'"
|
236
|
+
end
|
237
|
+
puts "## Deploying website via Rsync"
|
238
|
+
|
239
|
+
rsync_command = "rsync --progress -avze 'ssh -p #{options['ssh_port']}' #{exclude} \
|
240
|
+
#{"--delete" unless options['rsync_delete'] == false} \
|
241
|
+
#{options['public_dir']}/ #{options['ssh_host']}:#{options['document_root']}"
|
242
|
+
|
243
|
+
ok_failed system(rsync_command)
|
244
|
+
|
245
|
+
when 'setup'
|
246
|
+
unless File.exists?(PWD + '/_config.dist_backup.yml')
|
247
|
+
puts "", "===== Creating a backup of the configuration file ... ====="
|
248
|
+
FileUtils.cp(PWD + '/_config.yml', PWD + '/_config.dist_backup.yml', {verbose: true})
|
249
|
+
puts "===== ... done ===== ", ""
|
250
|
+
end
|
251
|
+
|
252
|
+
|
253
|
+
puts "", "If you are creating a brand new podcasting site, you can safely overwrite and answer with 'Y'."
|
254
|
+
puts "If this is an old site, it's better to answer with 'N'." , ""
|
255
|
+
|
256
|
+
puts "", "===== Copying assets ... ====="
|
257
|
+
Dir.glob(GEM_DIR + "/assets/**/*").each do |file|
|
258
|
+
copy_file_or_create_dir(file)
|
259
|
+
end
|
260
|
+
|
261
|
+
Dir.glob(GEM_DIR + "/assets/**/.*").each do |file|
|
262
|
+
copy_file_or_create_dir(file)
|
263
|
+
end
|
264
|
+
|
265
|
+
if write_file?(PWD + "/_config.yaml")
|
266
|
+
FileUtils.cp(GEM_DIR + "/assets/_config.yml.sample", PWD + "/_config.yml", {verbose: true})
|
267
|
+
end
|
268
|
+
puts "===== ... done ===== ", ""
|
269
|
+
end
|
270
|
+
else
|
271
|
+
puts octopod_help if ARGV.size > 0 && ARGV[0] == '--help'
|
272
|
+
load Gem.bin_path('jekyll', 'jekyll')
|
273
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require "jekyll/flattr_filters"
|
2
|
+
require "jekyll/octopod_filters"
|
3
|
+
require "jekyll/paged_feed_page"
|
4
|
+
require "jekyll/paged_feed_page_generator"
|
5
|
+
require "jekyll/podcast_player_page"
|
6
|
+
require "jekyll/podcast_player_page_generator"
|
7
|
+
require "jekyll/update_config"
|
8
|
+
require "jekyll/static_file"
|
9
|
+
require "jekyll/podigee_player_tag"
|
10
|
+
require "jekyll/date_de"
|
11
|
+
require "octopod/version"
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'date'
|
3
|
+
|
4
|
+
# gem install facets
|
5
|
+
require 'facets/integer/ordinal'
|
6
|
+
|
7
|
+
module Jekyll
|
8
|
+
module DateDe
|
9
|
+
#Deutsche Lokalisation:
|
10
|
+
MONTHNAMES_DE = [nil,
|
11
|
+
"Januar", "Februar", "März", "April", "Mai", "Juni",
|
12
|
+
"Juli", "August", "September", "Oktober", "November", "Dezember" ]
|
13
|
+
ABBR_MONTHNAMES_DE = [nil,
|
14
|
+
"Jan", "Feb", "Mär", "Apr", "Mai", "Jun",
|
15
|
+
"Jul", "Aug", "Sep", "Okt", "Nov", "Dez" ]
|
16
|
+
DAYNAMES_DE = [
|
17
|
+
"Sonntag", "Montag", "Dienstag", "Mittwoch",
|
18
|
+
"Donnerstag", "Freitag", "Samstag" ]
|
19
|
+
ABBR_DAYNAMES_DE = [
|
20
|
+
"So", "Mo", "Di", "Mi",
|
21
|
+
"Do", "Fr", "Sa" ]
|
22
|
+
|
23
|
+
# Returns a datetime if the input is a string
|
24
|
+
def datetime(date)
|
25
|
+
if date.class == String
|
26
|
+
date = Time.parse(date)
|
27
|
+
end
|
28
|
+
date
|
29
|
+
end
|
30
|
+
|
31
|
+
# Formats date by given date format
|
32
|
+
def format_date(date, format)
|
33
|
+
date = datetime(date)
|
34
|
+
if format.nil? || format.empty? || format == "ordinal"
|
35
|
+
date_formatted = ordinalize(date)
|
36
|
+
else
|
37
|
+
format.gsub!(/%a/, ABBR_DAYNAMES_DE[date.wday])
|
38
|
+
format.gsub!(/%A/, DAYNAMES_DE[date.wday])
|
39
|
+
format.gsub!(/%b/, ABBR_MONTHNAMES_DE[date.mon])
|
40
|
+
format.gsub!(/%B/, MONTHNAMES_DE[date.mon])
|
41
|
+
date_formatted = date.strftime(format)
|
42
|
+
end
|
43
|
+
date_formatted
|
44
|
+
end
|
45
|
+
|
46
|
+
# Usage: {{ post.date | full_date_de }}
|
47
|
+
# Result: 13. Dezember 2017
|
48
|
+
def full_date_de(date)
|
49
|
+
format_date(date, "%d. %B %Y")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
Liquid::Template.register_filter(Jekyll::DateDe)
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
module Jekyll
|
4
|
+
module FlattrFilters
|
5
|
+
# Generates the query string part for the flattr load.js from the
|
6
|
+
# configurations in _config.yml
|
7
|
+
#
|
8
|
+
# {{ site | flattr_loader_options }}
|
9
|
+
def flattr_loader_options(site)
|
10
|
+
return if site['flattr_uid'].nil?
|
11
|
+
keys = %w[mode https popout uid button language category]
|
12
|
+
options = flattr_options(site, nil, keys).delete_if { |_, v| v.to_s.empty? }
|
13
|
+
|
14
|
+
options.map { |k, v| "#{k}=#{ERB::Util.url_encode(v)}" }.join('&')
|
15
|
+
end
|
16
|
+
|
17
|
+
# Returns a flattr button
|
18
|
+
#
|
19
|
+
# {{ site | flattr_button:page }}
|
20
|
+
def flattr_button(site, page = nil)
|
21
|
+
return if site['flattr_uid'].nil?
|
22
|
+
|
23
|
+
keys = %w[url title description uid popout button category language tags]
|
24
|
+
options = flattr_options(site, page, keys)
|
25
|
+
|
26
|
+
button = '<a class="FlattrButton" style="display:none;" '
|
27
|
+
button << %Q{title="#{options.delete('title')}" href="#{options.delete('url')}" }
|
28
|
+
button << options.map { |k, v|
|
29
|
+
%Q{data-flattr-#{k}="#{v}"} unless k == 'description'
|
30
|
+
}.join(' ')
|
31
|
+
button << ">\n\n#{options['description'].gsub(/<\/?[^>]*>/, "")}\n</a>"
|
32
|
+
end
|
33
|
+
|
34
|
+
# Returns a RSS payment link.
|
35
|
+
#
|
36
|
+
# {{ site | flattr_rss:post }}
|
37
|
+
def flattr_rss(site, page = nil)
|
38
|
+
return if site['flattr_uid'].nil?
|
39
|
+
link = '<atom:link rel="payment" href="https://flattr.com/submit/auto?'
|
40
|
+
link << %Q{#{flattr_feed_options(site, page)}" type="text/html" />}
|
41
|
+
end
|
42
|
+
|
43
|
+
# Returns a ATOM payment link.
|
44
|
+
#
|
45
|
+
# {{ site | flattr_atom:post }}
|
46
|
+
def flattr_atom(site, page = nil)
|
47
|
+
return if site['flattr_uid'].nil?
|
48
|
+
link = '<link rel="payment" href="https://flattr.com/submit/auto?'
|
49
|
+
link << %Q{#{flattr_feed_options(site, page)}" type="text/html" />}
|
50
|
+
end
|
51
|
+
|
52
|
+
# Removes all leading "flattr_" from the keys of the given hash.
|
53
|
+
#
|
54
|
+
# flattrize({ 'octopod' => 'awesome', 'flattr_uid' => 'pattex' })
|
55
|
+
# => { "octopod" => "awesome", "uid" => "pattex" }
|
56
|
+
def flattrize(hsh)
|
57
|
+
config = {}
|
58
|
+
hsh.to_hash.each { |k, v|
|
59
|
+
if new_key = k.to_s.match(/\Aflattr_(.*)\z/)
|
60
|
+
config[new_key[1]] = v
|
61
|
+
else
|
62
|
+
config[k] = v
|
63
|
+
end
|
64
|
+
}
|
65
|
+
|
66
|
+
config
|
67
|
+
end
|
68
|
+
|
69
|
+
def flattr_options(site, page, keys)
|
70
|
+
page = {} if page.nil?
|
71
|
+
site = flattrize(site)
|
72
|
+
page = flattrize(page)
|
73
|
+
options = {}
|
74
|
+
|
75
|
+
keys.each { |k|
|
76
|
+
case k
|
77
|
+
when 'https'
|
78
|
+
options[k] = 1
|
79
|
+
when 'url'
|
80
|
+
options[k] = "#{site['url']}#{page['url']}"
|
81
|
+
when 'description'
|
82
|
+
options[k] = page['content'] || site['description'] || site['title']
|
83
|
+
when 'category'
|
84
|
+
options[k] = page['category'] || site['category'] || 'audio'
|
85
|
+
when 'language'
|
86
|
+
options[k] = page['language'] || site['language'] || 'en_GB'
|
87
|
+
when 'tags'
|
88
|
+
options[k] = page['tags'].join(', ') if page['tags']
|
89
|
+
else
|
90
|
+
options[k] = page[k] || site[k]
|
91
|
+
end
|
92
|
+
}
|
93
|
+
|
94
|
+
options
|
95
|
+
end
|
96
|
+
|
97
|
+
def flattr_feed_options(site, page)
|
98
|
+
keys = %w[url uid]
|
99
|
+
options = flattr_options(site, page, keys).map { |k, v|
|
100
|
+
"#{k == 'uid' ? 'user_id' : k}=#{ERB::Util.url_encode(v)}"
|
101
|
+
}.join('&')
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
Liquid::Template.register_filter(Jekyll::FlattrFilters)
|