create a middleware for serving fonts (solve cross domain issue) + add cache for consume liquid tag + fix image picker
This commit is contained in:
parent
86ac74e290
commit
54063d6b46
@ -4,6 +4,7 @@ module Admin
|
||||
include ActionView::Helpers::SanitizeHelper
|
||||
extend ActionView::Helpers::SanitizeHelper::ClassMethods
|
||||
include ActionView::Helpers::TextHelper
|
||||
include ActionView::Helpers::NumberHelper
|
||||
|
||||
sections 'settings', 'theme_assets'
|
||||
|
||||
@ -15,6 +16,7 @@ module Admin
|
||||
@js_and_css_assets = (@assets[:javascripts] || []) + (@assets[:stylesheets] || [])
|
||||
|
||||
if request.xhr?
|
||||
@images = @assets[:images]
|
||||
render :action => 'images', :layout => false and return
|
||||
else
|
||||
@snippets = current_site.snippets.order_by([[:name, :asc]]).all.to_a
|
||||
@ -33,9 +35,10 @@ module Admin
|
||||
success.json do
|
||||
render :json => {
|
||||
:status => 'success',
|
||||
:name => truncate(@theme_asset.slug, :length => 22),
|
||||
:slug => @theme_asset.slug,
|
||||
:url => @theme_asset.source.url
|
||||
:url => @theme_asset.source.url,
|
||||
:local_path => @theme_asset.local_path(true),
|
||||
:size => number_to_human_size(@theme_asset.size),
|
||||
:date => l(@theme_asset.updated_at, :format => :short)
|
||||
}
|
||||
end
|
||||
failure.json { render :json => { :status => 'error' } }
|
||||
|
@ -49,6 +49,14 @@ class ThemeAsset
|
||||
self.stylesheet? || self.javascript?
|
||||
end
|
||||
|
||||
def local_path(short = false)
|
||||
if short
|
||||
self.read_attribute(:local_path).gsub(/^#{self.content_type.pluralize}\//, '')
|
||||
else
|
||||
self.read_attribute(:local_path)
|
||||
end
|
||||
end
|
||||
|
||||
def plain_text_name
|
||||
if not @plain_text_name_changed
|
||||
@plain_text_name ||= self.safe_source_filename
|
||||
|
@ -1,10 +1,13 @@
|
||||
%li{ :class => "#{'hidden' if asset.hidden?}" }
|
||||
- edit = local_assigns.key?(:edit) ? edit : true
|
||||
|
||||
%li{ :class => "#{asset.new_record? ? 'new-asset' : 'asset'} #{'hidden' if asset.hidden?}" }
|
||||
%em
|
||||
%strong= link_to asset.local_path, edit_admin_theme_asset_path(asset)
|
||||
%strong= link_to asset.local_path(!edit), edit ? edit_admin_theme_asset_path(asset) : asset.source.url, :'data-local-path' => asset.local_path
|
||||
.more
|
||||
%span.size= number_to_human_size(asset.size)
|
||||
—
|
||||
%span!= t('.updated_at')
|
||||
= l asset.updated_at, :format => :short
|
||||
%span.date= l asset.updated_at, :format => :short
|
||||
|
||||
= link_to image_tag('admin/list/icons/trash.png'), admin_theme_asset_path(asset), :class => 'remove', :confirm => t('admin.messages.confirm'), :method => :delete
|
||||
- if edit
|
||||
= link_to image_tag('admin/list/icons/trash.png'), admin_theme_asset_path(asset), :class => 'remove', :confirm => t('admin.messages.confirm'), :method => :delete
|
||||
|
@ -4,12 +4,12 @@
|
||||
.actions
|
||||
= admin_button_tag t('admin.theme_assets.index.new'), admin_theme_assets_url(:json), :class => 'button small add', :id => 'upload-link'
|
||||
|
||||
- if @image_assets.empty?
|
||||
- if @images.empty?
|
||||
%p.no-items!= t('.no_items')
|
||||
|
||||
%ul.assets
|
||||
= render 'asset', :asset => current_site.theme_assets.build, :edit => false
|
||||
%ul.list.theme-assets
|
||||
= render 'asset', :asset => current_site.theme_assets.build(:updated_at => Time.now, :local_path => 'images/new.jpg', :content_type => 'image'), :edit => false
|
||||
|
||||
= render :partial => 'asset', :collection => @image_assets, :locals => { :per_row => 3, :edit => false }
|
||||
= render :partial => 'asset', :collection => @images, :locals => { :edit => false }
|
||||
|
||||
%li.clear
|
@ -46,5 +46,8 @@ module Locomotive
|
||||
|
||||
# Configure sensitive parameters which will be filtered from the log file.
|
||||
config.filter_parameters << :password
|
||||
|
||||
config.middleware.insert_after ::ActionDispatch::Static, '::Locomotive::Middlewares::Fonts', :path => %r{^/fonts}
|
||||
# config.middleware.insert_after 'Rack::Lock', 'Dragonfly::Middleware'
|
||||
end
|
||||
end
|
||||
|
@ -4,14 +4,14 @@ Locomotive::Application.configure do
|
||||
# In the development environment your application's code is reloaded on
|
||||
# every request. This slows down response time but is perfect for development
|
||||
# since you don't have to restart the webserver when you make code changes.
|
||||
config.cache_classes = false
|
||||
config.cache_classes = true # false
|
||||
|
||||
# Log error messages when you accidentally call methods on nil.
|
||||
config.whiny_nils = true
|
||||
|
||||
# Show full error reports and disable caching
|
||||
config.consider_all_requests_local = true
|
||||
config.action_controller.perform_caching = false
|
||||
config.action_controller.perform_caching = true #false
|
||||
|
||||
# Don't care if the mailer can't send
|
||||
config.action_mailer.raise_delivery_errors = false
|
||||
|
3
doc/TODO
3
doc/TODO
@ -38,7 +38,8 @@ x snippet dependencies => do not work correctly
|
||||
x mask internal asset_collections
|
||||
x refactor ui for the theme assets page
|
||||
x fix assets liquid tags / filters
|
||||
- proxy for fonts
|
||||
x upload and insert new images in a css or js from the ui is broken
|
||||
x proxy for fonts (http://markevans.github.com/dragonfly/file.Rails3.html)
|
||||
- fix tests
|
||||
- order yaml file (http://www.ruby-forum.com/topic/120295)
|
||||
- global regions: keyword in editable element (http://www.mongodb.org/display/DOCS/Updating)
|
||||
|
@ -1,4 +1,3 @@
|
||||
# require 'locomotive/patches'
|
||||
require 'locomotive/configuration'
|
||||
require 'locomotive/logger'
|
||||
require 'locomotive/liquid'
|
||||
@ -14,6 +13,7 @@ require 'locomotive/regexps'
|
||||
require 'locomotive/render'
|
||||
require 'locomotive/import'
|
||||
require 'locomotive/delayed_job'
|
||||
require 'locomotive/middlewares'
|
||||
|
||||
require 'mongo_session_store/mongoid'
|
||||
|
||||
|
@ -9,13 +9,17 @@ module Locomotive
|
||||
return '' if input.nil?
|
||||
|
||||
unless input =~ /^(\/|http:)/
|
||||
stylesheet = ThemeAsset.new(:site => @context.registers[:site], :folder => 'stylesheets')
|
||||
input = '/' + ThemeAssetUploader.new(stylesheet).store_path(input)
|
||||
segments = "stylesheets/#{input}".split('/')
|
||||
|
||||
filename, folder = segments.pop, segments.join('/')
|
||||
|
||||
stylesheet = ThemeAsset.new(:site => @context.registers[:site], :folder => folder)
|
||||
|
||||
input = '/' + ThemeAssetUploader.new(stylesheet).store_path(filename)
|
||||
end
|
||||
|
||||
# puts "stylesheet_tag context ? #{@context}"
|
||||
|
||||
input = "#{input}.css" unless input.ends_with?('.css')
|
||||
|
||||
%{<link href="#{input}" media="screen" rel="stylesheet" type="text/css" />}
|
||||
end
|
||||
|
||||
@ -25,20 +29,39 @@ module Locomotive
|
||||
return '' if input.nil?
|
||||
|
||||
unless input =~ /^(\/|http:)/
|
||||
javascript = ThemeAsset.new(:site => @context.registers[:site], :folder => 'javascripts')
|
||||
input = '/' + ThemeAssetUploader.new(javascript).store_path(input)
|
||||
segments = "javascripts/#{input}".split('/')
|
||||
|
||||
filename, folder = segments.pop, segments.join('/')
|
||||
|
||||
javascript = ThemeAsset.new(:site => @context.registers[:site], :folder => folder)
|
||||
|
||||
input = '/' + ThemeAssetUploader.new(javascript).store_path(filename)
|
||||
end
|
||||
|
||||
input = "#{input}.js" unless input.ends_with?('.js')
|
||||
|
||||
%{<script src="#{input}" type="text/javascript"></script>}
|
||||
end
|
||||
|
||||
def theme_image_url(input)
|
||||
return '' if input.nil?
|
||||
|
||||
input = "images/#{input}" unless input.starts_with?('/')
|
||||
|
||||
segments = input.split('/')
|
||||
|
||||
filename, folder = segments.pop, segments.join('/')
|
||||
|
||||
image = ThemeAsset.new(:site => @context.registers[:site], :folder => folder)
|
||||
|
||||
'/' + ThemeAssetUploader.new(image).store_path(filename)
|
||||
end
|
||||
|
||||
# Write an image tag
|
||||
# input: url of the image OR asset drop
|
||||
def image_tag(input, *args)
|
||||
image_options = inline_options(args_to_options(args))
|
||||
"<img src=\"#{File.join('/', get_path_from_asset(input))}\" #{image_options}/>"
|
||||
"<img src=\"#{File.join('/', get_url_from_asset(input))}\" #{image_options}/>"
|
||||
end
|
||||
|
||||
# Embed a flash movie into a page
|
||||
@ -46,7 +69,7 @@ module Locomotive
|
||||
# width: width (in pixel or in %) of the embedded movie
|
||||
# height: height (in pixel or in %) of the embedded movie
|
||||
def flash_tag(input, *args)
|
||||
path = get_path_from_asset(input)
|
||||
path = get_url_from_asset(input)
|
||||
embed_options = inline_options(args_to_options(args))
|
||||
%{
|
||||
<object #{embed_options}>
|
||||
@ -114,9 +137,9 @@ module Locomotive
|
||||
(options.stringify_keys.to_a.collect { |a, b| "#{a}=\"#{b}\"" }).join(' ') << ' '
|
||||
end
|
||||
|
||||
# Get the path to be used in html tags such as image_tag, flash_tag, ...etc
|
||||
# Get the url to be used in html tags such as image_tag, flash_tag, ...etc
|
||||
# input: url (String) OR asset drop
|
||||
def get_path_from_asset(input)
|
||||
def get_url_from_asset(input)
|
||||
input.respond_to?(:url) ? input.url : input
|
||||
end
|
||||
end
|
||||
|
@ -5,7 +5,7 @@ module Locomotive
|
||||
#
|
||||
# Usage:
|
||||
#
|
||||
# {% consume blog from 'http://nocoffee.tumblr.com/api/read.json?num=3' username: 'john', password: 'easy', format: 'json' %}
|
||||
# {% consume blog from 'http://nocoffee.tumblr.com/api/read.json?num=3' username: 'john', password: 'easy', format: 'json', expires_in: 3000 %}
|
||||
# {% for post in blog.posts %}
|
||||
# {{ post.title }}
|
||||
# {% endfor %}
|
||||
@ -23,6 +23,8 @@ module Locomotive
|
||||
markup.scan(::Liquid::TagAttributes) do |key, value|
|
||||
@options[key] = value if key != 'http'
|
||||
end
|
||||
@expires_in = (@options.delete('expires_in') || 0).to_i
|
||||
@cache_key = Digest::SHA1.hexdigest(@target)
|
||||
else
|
||||
raise ::Liquid::SyntaxError.new("Syntax Error in 'consume' - Valid syntax: consume <var> from \"<url>\" [username: value, password: value]")
|
||||
end
|
||||
@ -31,10 +33,18 @@ module Locomotive
|
||||
end
|
||||
|
||||
def render(context)
|
||||
context.stack do
|
||||
context.scopes.last[@target.to_s] = Locomotive::Httparty::Webservice.consume(@url, @options.symbolize_keys)
|
||||
render_all_and_cache_it(context)
|
||||
end
|
||||
|
||||
render_all(@nodelist, context)
|
||||
protected
|
||||
|
||||
def render_all_and_cache_it(context)
|
||||
Rails.cache.fetch(@cache_key, :expires_in => @expires_in) do
|
||||
context.stack do
|
||||
context.scopes.last[@target.to_s] = Locomotive::Httparty::Webservice.consume(@url, @options.symbolize_keys)
|
||||
|
||||
render_all(@nodelist, context)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
1
lib/locomotive/middlewares.rb
Normal file
1
lib/locomotive/middlewares.rb
Normal file
@ -0,0 +1 @@
|
||||
require 'locomotive/middlewares/fonts'
|
44
lib/locomotive/middlewares/fonts.rb
Normal file
44
lib/locomotive/middlewares/fonts.rb
Normal file
@ -0,0 +1,44 @@
|
||||
require 'rack/utils'
|
||||
|
||||
module Locomotive
|
||||
module Middlewares
|
||||
class Fonts
|
||||
include Rack::Utils
|
||||
|
||||
def initialize(app, opts = {})
|
||||
@app = app
|
||||
@path_regexp = opts[:path] || %r{^/fonts/}
|
||||
@file_server = ::Rack::File.new(opts[:root] || "#{Rails.root}/public")
|
||||
@expires_in = opts[:expires_in] || 24.hour
|
||||
end
|
||||
|
||||
def call(env)
|
||||
if env["PATH_INFO"] =~ @path_regexp
|
||||
site = fetch_site(env['SERVER_NAME'])
|
||||
|
||||
if site.nil?
|
||||
@app.call(env)
|
||||
else
|
||||
env["PATH_INFO"] = ::File.join('/', 'sites', site.id.to_s, 'theme', env["PATH_INFO"])
|
||||
|
||||
response = @file_server.call(env)
|
||||
|
||||
response[1]['Cache-Control'] = "public; max-age=#{@expires_in}" # varnish
|
||||
|
||||
response
|
||||
end
|
||||
else
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def fetch_site(domain_name)
|
||||
Rails.cache.fetch(domain_name, :expires_in => @expires_in) do
|
||||
Site.match_domain(domain_name).first
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -56,7 +56,7 @@ module Locomotive
|
||||
'asset_collections' => Locomotive::Liquid::Drops::AssetCollections.new,
|
||||
'stylesheets' => Locomotive::Liquid::Drops::ThemeAssets::Stylesheets.new,
|
||||
'javascripts' => Locomotive::Liquid::Drops::ThemeAssets::Javascripts.new,
|
||||
'images' => Locomotive::Liquid::Drops::ThemeAssets::Images.new,
|
||||
'theme_images' => Locomotive::Liquid::Drops::ThemeAssets::Images.new,
|
||||
'contents' => Locomotive::Liquid::Drops::Contents.new,
|
||||
'current_page' => self.params[:page]
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ $(document).ready(function() {
|
||||
if (typeof $.fn.imagepicker != 'undefined')
|
||||
$('a#image-picker-link').imagepicker({
|
||||
insertFn: function(link) {
|
||||
return "{{ theme_images." + link.attr('data-slug') + " }}";
|
||||
return "{{ '" + link.attr('data-local-path') + "' | theme_image_url }}";
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -47,13 +47,13 @@ $.fn.imagepicker = function(options) {
|
||||
.insertBefore($('.asset-picker ul li.clear'))
|
||||
.addClass('asset');
|
||||
|
||||
asset.find('h4 a').attr('href', json.url)
|
||||
.attr('data-slug', json.slug)
|
||||
.attr('data-shortcut-url', json.shortcut_url)
|
||||
.html(json.name).bind('click', function(e) {
|
||||
asset.find('strong a').attr('href', json.url)
|
||||
.attr('data-local-path', json.local_path)
|
||||
.html(json.local_path).bind('click', function(e) {
|
||||
copyLinkToEditor($(this), e);
|
||||
});
|
||||
asset.find('.image .inside img').attr('src', json.vignette_url);
|
||||
asset.find('.more .size').html(json.size);
|
||||
asset.find('.more .date').html(json.date);
|
||||
|
||||
if ($('.asset-picker ul li.asset').length % 3 == 0)
|
||||
asset.addClass('last');
|
||||
@ -74,7 +74,7 @@ $.fn.imagepicker = function(options) {
|
||||
'onComplete': function() {
|
||||
setupUploader();
|
||||
|
||||
$('ul.assets h4 a').bind('click', function(e) { copyLinkToEditor($(this), e); });
|
||||
$('ul.theme-assets strong a').bind('click', function(e) { copyLinkToEditor($(this), e); });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -37,7 +37,7 @@ $(document).ready(function() {
|
||||
|
||||
$('a#image-picker-link').imagepicker({
|
||||
insertFn: function(link) {
|
||||
return link.attr('data-url');
|
||||
return link.attr('href');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -49,7 +49,7 @@
|
||||
|
||||
/* ___ asset picker ___ */
|
||||
|
||||
div.asset-picker { width: 470px; position: relative; }
|
||||
div.asset-picker { width: 720px; position: relative; }
|
||||
div.asset-picker .actions { position: absolute; right: 4px; top: 0px; }
|
||||
|
||||
div.asset-picker p.no-items { background-image: url("/images/admin/list/none-small.png"); }
|
||||
@ -57,6 +57,9 @@ div.asset-picker p.no-items { background-image: url("/images/admin/list/none-sma
|
||||
div.asset-picker ul { overflow: auto; height: 471px; }
|
||||
div.asset-picker ul li.new-asset { display: none; }
|
||||
|
||||
div.asset-picker ul { margin: 0px; }
|
||||
div.asset-picker ul li .more { top: 8px; }
|
||||
|
||||
/* ___ custom fields ___ */
|
||||
|
||||
#edit-custom-field {
|
||||
|
Loading…
Reference in New Issue
Block a user