middleman-image-uploader-tag 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/Gemfile +11 -0
- data/README.md +99 -0
- data/Rakefile +10 -0
- data/features/support/env.rb +4 -0
- data/lib/middleman-image-uploader-tag.rb +9 -0
- data/lib/middleman/image-uploader-tag/cdns/base.rb +9 -0
- data/lib/middleman/image-uploader-tag/cdns/cloudinary.rb +37 -0
- data/lib/middleman/image-uploader-tag/exceptions.rb +24 -0
- data/lib/middleman/image-uploader-tag/extension.rb +84 -0
- data/lib/middleman/image-uploader-tag/version.rb +5 -0
- data/lib/middleman_extension.rb +1 -0
- data/middleman-image-uploader-tag.gemspec +31 -0
- data/test/fixtures/test/.gitignore +18 -0
- data/test/fixtures/test/Gemfile +14 -0
- data/test/fixtures/test/config.rb +72 -0
- data/test/fixtures/test/source/images/background.png +0 -0
- data/test/fixtures/test/source/images/middleman.png +0 -0
- data/test/fixtures/test/source/index.html.erb +10 -0
- data/test/fixtures/test/source/javascripts/all.js +1 -0
- data/test/fixtures/test/source/layouts/layout.erb +19 -0
- data/test/fixtures/test/source/stylesheets/all.css +55 -0
- data/test/fixtures/test/source/stylesheets/normalize.css +375 -0
- data/test/lib/middleman/image-uploader-tag/cdns/cloudinary_test.rb +132 -0
- data/test/lib/middleman/image-uploader-tag/extension_test.rb +174 -0
- data/test/test_helper.rb +10 -0
- metadata +142 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 362ef8e1b744f133c54355093a958ed4d1445ac1
|
4
|
+
data.tar.gz: a2a0114837e730164b9927b952907f6a88b8b734
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bd13ca115c108becb86f3e6c71c8b55cd56b7089bd5f1caa76904778ad5675ea73d4805692fbd0435e4eb3837af2d8b9c9b4328ecc698b994707cc0f6b928ad1
|
7
|
+
data.tar.gz: 34c26fa912fc9bc2265e079c862fb6d1d52ec056930d41cbdadbf81b66ec793550483389103b1b7b9ed6aa2a9dab8af48a45f00d6386e1545b2f55b408bcb756
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
# Middleman Image Uploader Tag
|
2
|
+
|
3
|
+
`middleman-image-uploader-tag` is an extension for the [Middleman] static site generator that adds special tag helpers with functionality of uploading images into a external services as CDN's and remote storages.
|
4
|
+
|
5
|
+
## The Reason
|
6
|
+
|
7
|
+
If you start a new blog generated by the Middleman and hosted at the GitHub static pages, soon you become realize that pushing big images into the repository has a few drawbacks:
|
8
|
+
|
9
|
+
- the speed of deploy through the git is very low
|
10
|
+
- it pollutes your repository with huge files (GitHub is definitely not Flckr)
|
11
|
+
- it caches for 10 minutes only because of GitHub CDNs Cache-Control headers. So your readers would not be happy to redownload huge backgrounds or photos each time they visit your site..
|
12
|
+
- ...
|
13
|
+
|
14
|
+
## Concept
|
15
|
+
|
16
|
+
During development phase nothing is changed. To prevent redundancy uploading into remote hosting (while you are looking for different pictures, changing their sizes and so on), local images used as ussually.
|
17
|
+
|
18
|
+
But at the build time all images would be uploaded into remote hosting, and their relative paths replaced for appropriate absolute urls.
|
19
|
+
That gives you a possibility to control caching time of images, as well as other options that your CDN may provides you, separately.
|
20
|
+
|
21
|
+
## Important Note
|
22
|
+
|
23
|
+
At the moment only the [Cloudinary] CDN is supported. But it is easy to add any new one.
|
24
|
+
|
25
|
+
## Installation
|
26
|
+
|
27
|
+
Nothing special:
|
28
|
+
|
29
|
+
`gem install middleman-image-uploader-tag`
|
30
|
+
|
31
|
+
Or just add the following line into your `Gemfile`:
|
32
|
+
|
33
|
+
`gem 'middleman-image-uploader-tag'`
|
34
|
+
|
35
|
+
and after run `bundle install`.
|
36
|
+
|
37
|
+
Also you can install the latest code directly from repository with:
|
38
|
+
|
39
|
+
`gem 'middleman-image-uploader-tag', git: 'https://github.com/aliaksandrb/middleman-image-uploader-tag.git'`
|
40
|
+
|
41
|
+
|
42
|
+
## Configuration
|
43
|
+
|
44
|
+
Activate extension in your `config.rb`, providing credentials for remote provider:
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
activate :image_uploader_tag do |e|
|
48
|
+
e.remote_images_dir = 'remote_images'
|
49
|
+
e.provider = :cloudinary
|
50
|
+
e.provider_config = {
|
51
|
+
cloud_name: ENV['CLOUDINARY_CLOUD_NAME'],
|
52
|
+
api_key: ENV['CLOUDINARY_API_KEY'],
|
53
|
+
api_secret: ENV['CLOUDINARY_API_SECRET'],
|
54
|
+
enhance_image_tag: false,
|
55
|
+
static_image_support: true,
|
56
|
+
secure: true
|
57
|
+
}
|
58
|
+
end
|
59
|
+
```
|
60
|
+
|
61
|
+
Note: the `remote_images_dir` sets the only folder images being uploaded.
|
62
|
+
|
63
|
+
It is optional and by default has the value `'remote_images'`. You can change it but be sure to place it NOT within the images directory of the Middleman, just somewhere in the application root folder.
|
64
|
+
|
65
|
+
## Usage
|
66
|
+
|
67
|
+
Now in your views you can use a few new helpers:
|
68
|
+
|
69
|
+
Example for `.slim` or `.haml` templates
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
= remote_image_tag 'test.png', alt: 'hello'
|
73
|
+
|
74
|
+
= remote_image_tag 'backgrounds/test.png', alt: 'hello'
|
75
|
+
```
|
76
|
+
|
77
|
+
If you want to use it in your `.md` templates for posts content, you should rename them, adding additional proccessing level.
|
78
|
+
|
79
|
+
For example you had an post `source/articles/2015-05-21-welcome.html.markdown` then you need to rename it to `source/articles/2015-05-21-welcome.html.markdown.erb` (note `.erb` at the end).
|
80
|
+
|
81
|
+
After you can use a bit different helper:
|
82
|
+
|
83
|
+
```ruby
|
84
|
+
![MYIMAGE](<%= remote_image_tag_link 'test.png' %>)
|
85
|
+
```
|
86
|
+
|
87
|
+
or as simple as
|
88
|
+
|
89
|
+
```ruby
|
90
|
+
<%= remote_image_tag 'test.png' %>
|
91
|
+
```
|
92
|
+
|
93
|
+
The difference between `remote_image_tag` and `remote_image_tag_link` is that the first wraps link into `<img>` tag, but the other just produces the raw link as `https://cdn.blablabla.com/test.png`.
|
94
|
+
|
95
|
+
[middleman]: http://middlemanapp.com/
|
96
|
+
[cloudinary]: https://cloudinary.com/
|
97
|
+
___
|
98
|
+
|
99
|
+
Any feedback or issue report appreciated!
|
data/Rakefile
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'middleman-core'
|
2
|
+
require 'middleman/image-uploader-tag/exceptions'
|
3
|
+
require 'middleman/image-uploader-tag/extension'
|
4
|
+
require 'middleman/image-uploader-tag/cdns/base.rb'
|
5
|
+
require 'middleman/image-uploader-tag/cdns/cloudinary.rb'
|
6
|
+
|
7
|
+
::Middleman::Extensions.register(
|
8
|
+
:image_uploader_tag, ::Middleman::ImageUploaderTag::Extension
|
9
|
+
)
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'cloudinary'
|
2
|
+
|
3
|
+
module Middleman
|
4
|
+
module ImageUploaderTag
|
5
|
+
|
6
|
+
class CloudinaryCDN < BaseCDN
|
7
|
+
OBLIGATORY_OPTIONS = [:cloud_name, :api_secret, :api_key]
|
8
|
+
|
9
|
+
def initialize(config)
|
10
|
+
raise AuthorizationRequired if OBLIGATORY_OPTIONS.any? { |k| config[k].nil? }
|
11
|
+
|
12
|
+
Cloudinary.config do |c|
|
13
|
+
config.each { |key, value| c.public_send(:"#{key}=", value) unless value.nil? }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def get_remote_link(image_path)
|
18
|
+
raise NotFound if !image_path || !File.exist?(image_path.to_s)
|
19
|
+
|
20
|
+
upload_to_cloud(image_path)[:secure_url]
|
21
|
+
end
|
22
|
+
|
23
|
+
def upload_to_cloud(file, options = {})
|
24
|
+
# rescue Cloudinary exceptions? (timeouts, limits and so on..)
|
25
|
+
raise NotFound if !file || !File.exist?(file.to_s)
|
26
|
+
|
27
|
+
options.merge!({ use_filename: true, unique_filename: false })
|
28
|
+
|
29
|
+
Cloudinary::Uploader.upload(file, options).inject({}) do |memo, (k,v)|
|
30
|
+
memo[k.to_sym] = v
|
31
|
+
memo
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Middleman
|
2
|
+
module ImageUploaderTag
|
3
|
+
|
4
|
+
class ImageUploaderTagException < StandardError
|
5
|
+
def initialize(msg = nil)
|
6
|
+
@message = msg
|
7
|
+
super
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class NotFound < ImageUploaderTagException
|
12
|
+
def to_s
|
13
|
+
"#{self.class}: #{@message || 'No such image file in the remote folder'}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class AuthorizationRequired < ImageUploaderTagException
|
18
|
+
def to_s
|
19
|
+
"#{self.class}: #{@message || 'One or more obligatory options are missed'}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'middleman-core'
|
2
|
+
require 'middleman-core/extensions'
|
3
|
+
|
4
|
+
module Middleman
|
5
|
+
module ImageUploaderTag
|
6
|
+
|
7
|
+
class Extension < ::Middleman::Extension
|
8
|
+
option :provider, nil, 'CDN provider name'
|
9
|
+
option :provider_config, nil, 'CDN provider config options'
|
10
|
+
option :remote_images_dir, nil, %q{
|
11
|
+
Folder where images are placed.
|
12
|
+
Must be outside the :images_dir of the Middleman'
|
13
|
+
}
|
14
|
+
|
15
|
+
def initialize(app, options_hash = {}, &block)
|
16
|
+
super
|
17
|
+
|
18
|
+
# Require libraries only when activated
|
19
|
+
# require 'necessary/library'
|
20
|
+
|
21
|
+
@@provider_options = options
|
22
|
+
@@app = app
|
23
|
+
|
24
|
+
self.class.create_images_dir!
|
25
|
+
end
|
26
|
+
|
27
|
+
helpers do
|
28
|
+
def remote_image_tag(image_name, params = {})
|
29
|
+
image_tag remote_image_tag_link(image_name), params
|
30
|
+
end
|
31
|
+
|
32
|
+
def remote_image_tag_link(image_name)
|
33
|
+
klass = ::Middleman::ImageUploaderTag::Extension
|
34
|
+
|
35
|
+
klass.get_remote_path image_name
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.image_location(image_path)
|
40
|
+
File.join(app.root, 'source', remote_images_dir, image_path)
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.provider
|
44
|
+
# need cache here i believe
|
45
|
+
# handle cases for snake_case_name
|
46
|
+
# handle unknown provider
|
47
|
+
Object.const_get(
|
48
|
+
"::Middleman::ImageUploaderTag::#{provider_options.provider.to_s.capitalize}CDN"
|
49
|
+
).new(provider_options.provider_config)
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.get_remote_path(image_name)
|
53
|
+
image_path = image_location(image_name)
|
54
|
+
raise NotFound unless File.exist?(image_path)
|
55
|
+
|
56
|
+
if app.config.environment == :build
|
57
|
+
provider.get_remote_link(image_path)
|
58
|
+
else
|
59
|
+
image_name
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.provider_options
|
64
|
+
@@provider_options
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.app
|
68
|
+
@@app
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.remote_images_dir
|
72
|
+
@@remote_images_dir ||= provider_options.remote_images_dir || 'remote_images'
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.create_images_dir!
|
76
|
+
img_dir = File.join(app.root, 'source', remote_images_dir)
|
77
|
+
|
78
|
+
Dir.mkdir(img_dir) unless Dir.exist?(img_dir)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
require_relative 'middleman-image-uploader-tag'
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
$:.push File.expand_path('../lib', __FILE__)
|
4
|
+
require 'middleman/image-uploader-tag/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = 'middleman-image-uploader-tag'
|
8
|
+
s.version = Middleman::ImageUploaderTag::VERSION
|
9
|
+
s.platform = Gem::Platform::RUBY
|
10
|
+
s.authors = ['Aliaksandr Buhayeu']
|
11
|
+
s.email = ['aliaksandr.buhayeu@gmail.com']
|
12
|
+
s.homepage = 'https://github.com/aliaksandrb/middleman-image-uploader-tag'
|
13
|
+
s.summary = %q{Image tag helper with automatic upload to external services}
|
14
|
+
s.description = %q{
|
15
|
+
The remote_image_tag helper provide you automatic image upload to external
|
16
|
+
hosting services with public back-link mapping
|
17
|
+
}
|
18
|
+
s.license = 'MIT'
|
19
|
+
|
20
|
+
s.files = `git ls-files`.split("\n")
|
21
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
22
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
23
|
+
s.require_paths = ['lib']
|
24
|
+
|
25
|
+
s.add_runtime_dependency 'middleman-core', ['>= 3.3.12']
|
26
|
+
s.add_runtime_dependency 'cloudinary', '~>1.1.0'
|
27
|
+
|
28
|
+
s.add_development_dependency 'minitest', '~> 5.6.1'
|
29
|
+
s.add_development_dependency 'fivemat', '~> 1.3.1'
|
30
|
+
s.add_development_dependency 'minitest-stub-const'
|
31
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
2
|
+
#
|
3
|
+
# If you find yourself ignoring temporary files generated by your text editor
|
4
|
+
# or operating system, you probably want to add a global ignore instead:
|
5
|
+
# git config --global core.excludesfile ~/.gitignore_global
|
6
|
+
|
7
|
+
# Ignore bundler config
|
8
|
+
/.bundle
|
9
|
+
|
10
|
+
# Ignore the build directory
|
11
|
+
/build
|
12
|
+
|
13
|
+
# Ignore cache
|
14
|
+
/.sass-cache
|
15
|
+
/.cache
|
16
|
+
|
17
|
+
# Ignore .DS_store file
|
18
|
+
.DS_Store
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# If you do not have OpenSSL installed, update
|
2
|
+
# the following line to use "http://" instead
|
3
|
+
source 'https://rubygems.org'
|
4
|
+
|
5
|
+
gem "middleman", "~>3.3.12"
|
6
|
+
|
7
|
+
# Live-reloading plugin
|
8
|
+
gem "middleman-livereload", "~> 3.1.0"
|
9
|
+
|
10
|
+
# For faster file watcher updates on Windows:
|
11
|
+
gem "wdm", "~> 0.1.0", :platforms => [:mswin, :mingw]
|
12
|
+
|
13
|
+
# Windows does not come with time zone data
|
14
|
+
gem "tzinfo-data", platforms: [:mswin, :mingw, :jruby]
|
@@ -0,0 +1,72 @@
|
|
1
|
+
###
|
2
|
+
# Compass
|
3
|
+
###
|
4
|
+
|
5
|
+
# Change Compass configuration
|
6
|
+
# compass_config do |config|
|
7
|
+
# config.output_style = :compact
|
8
|
+
# end
|
9
|
+
|
10
|
+
###
|
11
|
+
# Page options, layouts, aliases and proxies
|
12
|
+
###
|
13
|
+
|
14
|
+
# Per-page layout changes:
|
15
|
+
#
|
16
|
+
# With no layout
|
17
|
+
# page "/path/to/file.html", :layout => false
|
18
|
+
#
|
19
|
+
# With alternative layout
|
20
|
+
# page "/path/to/file.html", :layout => :otherlayout
|
21
|
+
#
|
22
|
+
# A path which all have the same layout
|
23
|
+
# with_layout :admin do
|
24
|
+
# page "/admin/*"
|
25
|
+
# end
|
26
|
+
|
27
|
+
# Proxy pages (https://middlemanapp.com/advanced/dynamic_pages/)
|
28
|
+
# proxy "/this-page-has-no-template.html", "/template-file.html", :locals => {
|
29
|
+
# :which_fake_page => "Rendering a fake page with a local variable" }
|
30
|
+
|
31
|
+
###
|
32
|
+
# Helpers
|
33
|
+
###
|
34
|
+
|
35
|
+
# Automatic image dimensions on image_tag helper
|
36
|
+
# activate :automatic_image_sizes
|
37
|
+
|
38
|
+
# Reload the browser automatically whenever files change
|
39
|
+
# configure :development do
|
40
|
+
# activate :livereload
|
41
|
+
# end
|
42
|
+
|
43
|
+
# Methods defined in the helpers block are available in templates
|
44
|
+
# helpers do
|
45
|
+
# def some_helper
|
46
|
+
# "Helping"
|
47
|
+
# end
|
48
|
+
# end
|
49
|
+
|
50
|
+
set :css_dir, 'stylesheets'
|
51
|
+
|
52
|
+
set :js_dir, 'javascripts'
|
53
|
+
|
54
|
+
set :images_dir, 'images'
|
55
|
+
|
56
|
+
# Build-specific configuration
|
57
|
+
configure :build do
|
58
|
+
# For example, change the Compass output style for deployment
|
59
|
+
# activate :minify_css
|
60
|
+
|
61
|
+
# Minify Javascript on build
|
62
|
+
# activate :minify_javascript
|
63
|
+
|
64
|
+
# Enable cache buster
|
65
|
+
# activate :asset_hash
|
66
|
+
|
67
|
+
# Use relative URLs
|
68
|
+
# activate :relative_assets
|
69
|
+
|
70
|
+
# Or use a different image path
|
71
|
+
# set :http_prefix, "/Content/images/"
|
72
|
+
end
|