theme assets page in progress
This commit is contained in:
parent
af955ef927
commit
368f643cf0
@ -1,5 +1,8 @@
|
||||
class Locomotive.Models.ThemeAsset extends Backbone.Model
|
||||
|
||||
paramRoot: 'theme_asset'
|
||||
|
||||
urlRoot: "#{Locomotive.mount_on}/theme_assets"
|
||||
|
||||
class Locomotive.Models.ThemeAssetsCollection extends Backbone.Collection
|
||||
|
||||
|
@ -74,12 +74,6 @@ class Locomotive.Views.Pages.FormView extends Locomotive.Views.Shared.FormView
|
||||
after_inputs_fold: ->
|
||||
@editor.refresh()
|
||||
|
||||
show_error: (attribute, message, html) ->
|
||||
switch attribute
|
||||
when 'raw_template'
|
||||
@$("#page_raw_template_input .CodeMirror").after(html)
|
||||
else super
|
||||
|
||||
render_editable_elements: ->
|
||||
@$('.formtastic fieldset.inputs:first').before(@editable_elements_view.render().el)
|
||||
@editable_elements_view.after_render()
|
||||
|
@ -1,14 +1,17 @@
|
||||
Locomotive.Views.Snippets ||= {}
|
||||
Locomotive.Views.Shared ||= {}
|
||||
|
||||
class Locomotive.Views.Snippets.ItemView extends Backbone.View
|
||||
class Locomotive.Views.Shared.ListItemView extends Backbone.View
|
||||
|
||||
tagName: 'li'
|
||||
|
||||
events:
|
||||
'click a.remove': 'remove_snippet'
|
||||
|
||||
template: ->
|
||||
# please overide template
|
||||
|
||||
render: ->
|
||||
$(@el).html(ich.snippet_item(@model.toJSON()))
|
||||
$(@el).html(@template()(@model.toJSON()))
|
||||
|
||||
return @
|
||||
|
@ -0,0 +1,52 @@
|
||||
Locomotive.Views.Shared ||= {}
|
||||
|
||||
class Locomotive.Views.Shared.ListView extends Backbone.View
|
||||
|
||||
tagName: 'div'
|
||||
|
||||
_item_views = []
|
||||
|
||||
initialize: ->
|
||||
_.bindAll(@, 'insert_item', 'remove_item')
|
||||
@collection.bind('add', @insert_item)
|
||||
@collection.bind('remove', @remove_item)
|
||||
|
||||
template: ->
|
||||
# please overide template
|
||||
|
||||
item_view_class: ->
|
||||
# please overide item_view_class
|
||||
|
||||
render: ->
|
||||
$(@el).html(@template()())
|
||||
|
||||
@render_items()
|
||||
|
||||
return @
|
||||
|
||||
render_items: ->
|
||||
if @collection.length == 0
|
||||
@$('.no-items').show()
|
||||
else
|
||||
@collection.each (item) =>
|
||||
@insert_item(item)
|
||||
|
||||
insert_item: (item) ->
|
||||
klass = @item_view_class()
|
||||
view = new klass model: item, parent_view: @
|
||||
|
||||
(@_item_views ||= []).push(view)
|
||||
|
||||
@$('ul').append(view.render().el)
|
||||
|
||||
remove_item: (item) ->
|
||||
@$('.no-items').show() if @collection.length == 0
|
||||
view = _.find @_item_views, (tmp) -> tmp.model == item
|
||||
view.remove() if view?
|
||||
|
||||
remove: ->
|
||||
_.each @_item_views, (view) => view.remove()
|
||||
super
|
||||
|
||||
|
||||
|
@ -0,0 +1,8 @@
|
||||
#= require ../shared/list_item_view
|
||||
|
||||
Locomotive.Views.Snippets ||= {}
|
||||
|
||||
class Locomotive.Views.Snippets.ListItemView extends Locomotive.Views.Shared.ListItemView
|
||||
|
||||
template: ->
|
||||
ich.snippet_item
|
@ -1,47 +1,17 @@
|
||||
#= require ../shared/list_view
|
||||
|
||||
Locomotive.Views.Snippets ||= {}
|
||||
|
||||
class Locomotive.Views.Snippets.ListView extends Backbone.View
|
||||
|
||||
tagName: 'div'
|
||||
class Locomotive.Views.Snippets.ListView extends Locomotive.Views.Shared.ListView
|
||||
|
||||
className: 'box'
|
||||
|
||||
_item_views = []
|
||||
|
||||
initialize: ->
|
||||
_.bindAll(@, 'remove_item')
|
||||
@collection = new Locomotive.Models.SnippetsCollection(@options.collection)
|
||||
@collection.bind('remove', @remove_item)
|
||||
|
||||
render: ->
|
||||
$(@el).html(ich.snippets_list())
|
||||
|
||||
@render_items()
|
||||
|
||||
return @
|
||||
|
||||
render_items: ->
|
||||
if @collection.length == 0
|
||||
@$('.no-items').show()
|
||||
else
|
||||
@collection.each (snippet) =>
|
||||
@insert_item(snippet)
|
||||
|
||||
insert_item: (snippet) ->
|
||||
view = new Locomotive.Views.Snippets.ItemView model: snippet, parent_view: @
|
||||
|
||||
(@_item_views ||= []).push(view)
|
||||
|
||||
@$('ul').append(view.render().el)
|
||||
|
||||
remove_item: (snippet) ->
|
||||
@$('.no-items').show() if @collection.length == 0
|
||||
view = _.find @_item_views, (tmp) -> tmp.model == snippet
|
||||
view.remove() if view?
|
||||
|
||||
remove: ->
|
||||
_.each @_item_views, (view) => view.remove()
|
||||
super
|
||||
|
||||
template: ->
|
||||
ich.snippets_list
|
||||
|
||||
|
||||
item_view_class: ->
|
||||
Locomotive.Views.Snippets.ListItemView
|
@ -0,0 +1,104 @@
|
||||
#= require ../shared/form_view
|
||||
|
||||
Locomotive.Views.ThemeAssets ||= {}
|
||||
|
||||
class Locomotive.Views.ThemeAssets.FormView extends Locomotive.Views.Shared.FormView
|
||||
|
||||
el: '#content'
|
||||
|
||||
events:
|
||||
'click a#image-picker-link': 'open_image_picker'
|
||||
'submit': 'save'
|
||||
|
||||
initialize: ->
|
||||
_.bindAll(@, 'insert_image')
|
||||
|
||||
@model = new Locomotive.Models.ThemeAsset(@options.theme_asset)
|
||||
|
||||
window.foo = @model
|
||||
|
||||
@image_picker_view = new Locomotive.Views.ThemeAssets.ImagePickerView on_select: @insert_image
|
||||
|
||||
Backbone.ModelBinding.bind @
|
||||
|
||||
render: ->
|
||||
super()
|
||||
|
||||
@enable_toggle_between_file_and_text()
|
||||
|
||||
@enable_source_editing()
|
||||
|
||||
@bind_source_mode()
|
||||
|
||||
@enable_source_file()
|
||||
|
||||
return @
|
||||
|
||||
enable_toggle_between_file_and_text: ->
|
||||
@$('div.hidden').hide()
|
||||
|
||||
@model.set(performing_plain_text: @$('#theme_asset_performing_plain_text').val())
|
||||
|
||||
@$('.selector > a.alt').click (event) =>
|
||||
event.stopPropagation() & event.preventDefault()
|
||||
|
||||
if @$('#file-selector').is(':hidden')
|
||||
@$('#text-selector').slideUp 'normal', =>
|
||||
@$('#file-selector').slideDown()
|
||||
@model.set(performing_plain_text: false)
|
||||
@$('input#theme_asset_performing_plain_text').val(false)
|
||||
else
|
||||
@$('#file-selector').slideUp 'normal', =>
|
||||
@$('#text-selector').slideDown()
|
||||
@model.set(performing_plain_text: true)
|
||||
@$('#theme_asset_performing_plain_text').val(true)
|
||||
|
||||
enable_source_file: ->
|
||||
# only in HTML 5
|
||||
@$('#theme_asset_source').bind 'change', (event) =>
|
||||
input = $(event.target)[0]
|
||||
if input.files?
|
||||
@model.set(source: input.files[0])
|
||||
|
||||
show_error: (attribute, message, html) ->
|
||||
switch attribute
|
||||
when 'source'
|
||||
@$(if @model.get('performing_plain_text')
|
||||
'#theme_asset_plain_text_input .CodeMirror'
|
||||
else
|
||||
'#theme_asset_source').after(html)
|
||||
else super
|
||||
|
||||
open_image_picker: (event) ->
|
||||
event.stopPropagation() & event.preventDefault()
|
||||
@image_picker_view.editor = @editor
|
||||
@image_picker_view.render()
|
||||
|
||||
insert_image: (path) ->
|
||||
text = "{{ '#{path}' | theme_image_url }}"
|
||||
@editor.replaceSelection(text)
|
||||
@image_picker_view.close()
|
||||
|
||||
source_mode: ->
|
||||
if @model.get('plain_text_type') == 'javascript' then 'javascript' else 'css'
|
||||
|
||||
enable_source_editing: ->
|
||||
input = @$('#theme_asset_plain_text')
|
||||
|
||||
return if input.size() == 0
|
||||
|
||||
@editor = CodeMirror.fromTextArea input.get()[0],
|
||||
mode: @source_mode()
|
||||
autoMatchParens: false
|
||||
lineNumbers: false
|
||||
passDelay: 50
|
||||
tabMode: 'shift'
|
||||
theme: 'default'
|
||||
onChange: (editor) => @model.set(plain_text: editor.getValue())
|
||||
|
||||
bind_source_mode: ->
|
||||
@$('#theme_asset_plain_text_type').bind 'change', (event) =>
|
||||
@editor.setOption 'mode', @source_mode()
|
||||
|
||||
after_inputs_fold: ->
|
||||
@editor.refresh() if @editor?
|
@ -0,0 +1,9 @@
|
||||
Locomotive.Views.ThemeAssets ||= {}
|
||||
|
||||
class Locomotive.Views.ThemeAssets.EditView extends Locomotive.Views.ThemeAssets.FormView
|
||||
|
||||
save: (event) ->
|
||||
@save_in_ajax event, on_success: (response, xhr) =>
|
||||
help = @$('.inner > p.help')
|
||||
help.find('b').html(response.dimensions)
|
||||
help.find('a').html(response.url).attr('href', response.url)
|
@ -7,6 +7,10 @@ class Locomotive.Views.ThemeAssets.ImagePickerView extends Locomotive.Views.Shar
|
||||
events:
|
||||
'click ul.list a': 'select_asset'
|
||||
|
||||
initialize: ->
|
||||
@collection ||= new Locomotive.Models.ThemeAssetsCollection()
|
||||
super
|
||||
|
||||
template: ->
|
||||
ich.theme_image_picker
|
||||
|
||||
|
@ -4,45 +4,82 @@ class Locomotive.Views.ThemeAssets.IndexView extends Backbone.View
|
||||
|
||||
el: '#content'
|
||||
|
||||
# events:
|
||||
# 'click .box a.remove': 'remove_asset'
|
||||
_lists_views: []
|
||||
|
||||
# initialize: ->
|
||||
initialize: ->
|
||||
_.bindAll(@, 'add_asset')
|
||||
|
||||
render: ->
|
||||
@build_uploader()
|
||||
|
||||
@render_snippets()
|
||||
|
||||
@render_images()
|
||||
|
||||
@render_js_and_css()
|
||||
|
||||
@render_fonts()
|
||||
|
||||
@render_media()
|
||||
|
||||
return @
|
||||
|
||||
render_snippets: ->
|
||||
@snippets_view = new Locomotive.Views.Snippets.ListView collection: @options.snippets
|
||||
build_uploader: ->
|
||||
el = @$('.quick-upload input[type=file]')
|
||||
link = @$('.quick-upload a.new')
|
||||
window.Locomotive.Uploadify.build el,
|
||||
url: link.attr('href')
|
||||
data_name: el.attr('name')
|
||||
file_ext: '*.jpg;*.png;*.jpeg;*.gif;*.flv;*.swf;*.ttf;*.js;*.css;*.mp3'
|
||||
height: link.outerHeight()
|
||||
width: link.outerWidth()
|
||||
success: (model) => @add_asset(model)
|
||||
error: (msg) =>
|
||||
console.log(msg)
|
||||
$.growl('alert', msg)
|
||||
|
||||
@$('#snippets-anchor').replaceWith(@snippets_view.render().el)
|
||||
add_asset: (model) ->
|
||||
console.log(model)
|
||||
list_view = @pick_list_view(model.content_type)
|
||||
console.log(list_view)
|
||||
list_view.collection.add(model)
|
||||
|
||||
render_snippets: ->
|
||||
@render_list 'snippets', @options.snippets, Locomotive.Views.Snippets.ListView
|
||||
|
||||
render_images: ->
|
||||
@render_list 'images', @options.images
|
||||
|
||||
render_js_and_css: ->
|
||||
@render_list 'js-and-css', @options.js_and_css_assets, Locomotive.Views.ThemeAssets.ListView, ich.js_and_css_list
|
||||
|
||||
render_fonts: ->
|
||||
@render_list 'fonts', @options.fonts, Locomotive.Views.ThemeAssets.ListView, ich.fonts_list
|
||||
|
||||
render_media: ->
|
||||
@render_list 'media', @options.media, Locomotive.Views.ThemeAssets.ListView, ich.media_list
|
||||
|
||||
render_list: (type, collection, view_klass, template) ->
|
||||
return if @$("##{type}-anchor").size() == 0
|
||||
|
||||
view_klass ||= Locomotive.Views.ThemeAssets.ListView
|
||||
view = new view_klass(collection: collection, type: type)
|
||||
if template?
|
||||
view.template = -> template
|
||||
|
||||
@$("##{type}-anchor").replaceWith(view.render().el)
|
||||
|
||||
(@_lists_views ||= []).push(view)
|
||||
|
||||
pick_list_view: (content_type) ->
|
||||
type = switch content_type
|
||||
when 'image' then 'images'
|
||||
when 'javascript', 'stylesheet' then 'js-and-css'
|
||||
when 'media' then 'media'
|
||||
when 'font' then 'fonts'
|
||||
|
||||
_.find @_lists_views, (view) => view.options.type == type
|
||||
|
||||
remove: ->
|
||||
@snippets_view.remove()
|
||||
_.each @_lists_views, (view) => view.remove()
|
||||
super
|
||||
|
||||
# remove_asset: (event) ->
|
||||
# event.stopPropagation() & event.preventDefault()
|
||||
#
|
||||
# link = $(event.target)
|
||||
#
|
||||
# if confirm(link.attr('data-confirm'))
|
||||
# $.rails.ajax
|
||||
# url: link.attr('href')
|
||||
# type: 'post'
|
||||
# dataType: 'json'
|
||||
# data:
|
||||
# _method: 'delete'
|
||||
# success: (data, status, xhr) => @on_successful_delete(link, xhr)
|
||||
# error: @on_failed_delete
|
||||
#
|
||||
#
|
||||
# on_successful_delete: (link, xhr) ->
|
||||
# link.parents('')
|
||||
# $.growl('success', xhr.getResponseHeader('X-Message'))
|
||||
#
|
||||
# on_failed_delete: (data, status, xhr) ->
|
||||
# $.growl('error', xhr.getResponseHeader('X-Message'))
|
||||
|
||||
|
@ -0,0 +1,8 @@
|
||||
#= require ../shared/list_item_view
|
||||
|
||||
Locomotive.Views.ThemeAssets ||= {}
|
||||
|
||||
class Locomotive.Views.ThemeAssets.ListItemView extends Locomotive.Views.Shared.ListItemView
|
||||
|
||||
template: ->
|
||||
ich.editable_theme_asset_item
|
@ -0,0 +1,17 @@
|
||||
#= require ../shared/list_view
|
||||
|
||||
Locomotive.Views.ThemeAssets ||= {}
|
||||
|
||||
class Locomotive.Views.ThemeAssets.ListView extends Locomotive.Views.Shared.ListView
|
||||
|
||||
className: 'box'
|
||||
|
||||
initialize: ->
|
||||
@collection = new Locomotive.Models.ThemeAssetsCollection(@options.collection)
|
||||
super
|
||||
|
||||
template: ->
|
||||
ich.images_list
|
||||
|
||||
item_view_class: ->
|
||||
Locomotive.Views.ThemeAssets.ListItemView
|
@ -0,0 +1,8 @@
|
||||
Locomotive.Views.ThemeAssets ||= {}
|
||||
|
||||
class Locomotive.Views.ThemeAssets.NewView extends Locomotive.Views.ThemeAssets.FormView
|
||||
|
||||
save: (event) ->
|
||||
@save_in_ajax event,
|
||||
on_success: (response, xhr) ->
|
||||
window.location.href = xhr.getResponseHeader('location')
|
@ -67,6 +67,7 @@ p.no-items {
|
||||
text-align: center;
|
||||
color: #9d8963;
|
||||
font-size: 16px !important;
|
||||
@include single-text-shadow(rgba(255, 255, 255, 1), 1px, 1px, 1px);
|
||||
|
||||
a {
|
||||
@include hover-link;
|
||||
@ -74,86 +75,86 @@ p.no-items {
|
||||
}
|
||||
}
|
||||
|
||||
// ul.list {
|
||||
// background: #fff;
|
||||
// list-style: none;
|
||||
// margin: 0px 0 20px 0;
|
||||
//
|
||||
// li.item {
|
||||
// position: relative;
|
||||
// height: 31px;
|
||||
// line-height: 31px;
|
||||
//
|
||||
// background: #ebedf4;
|
||||
// @include border-radius(16px);
|
||||
// @include box-shadow(rgba(0, 0, 0, 0.2) 0px 1px 0px 0px);
|
||||
//
|
||||
// margin-bottom: 10px;
|
||||
// clear: both;
|
||||
//
|
||||
// a {
|
||||
// margin-left: 18px;
|
||||
// @include hover-link;
|
||||
//
|
||||
// font-weight: bold;
|
||||
// font-size: 14px;
|
||||
// color: #1F82BC;
|
||||
// outline: none;
|
||||
// }
|
||||
//
|
||||
// em {
|
||||
// display: block;
|
||||
// float: left;
|
||||
// height: 31px;
|
||||
// width: 18px;
|
||||
// }
|
||||
//
|
||||
// strong {
|
||||
// display: block;
|
||||
// height: 31px;
|
||||
// margin-left: 18px;
|
||||
//
|
||||
// a {
|
||||
// position: relative;
|
||||
// top: 2px;
|
||||
// left: 15px;
|
||||
//
|
||||
// text-decoration: none;
|
||||
// color: #1f82bc;
|
||||
// font-size: 13px;
|
||||
// @include single-text-shadow(#fff, 1px, 1px, 1px);
|
||||
//
|
||||
// &:hover {
|
||||
// text-decoration: underline;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// &.sortable li strong a { left: 10px; }
|
||||
//
|
||||
// div.more {
|
||||
// position: absolute;
|
||||
// top: 0px;
|
||||
// right: 15px;
|
||||
//
|
||||
// font-size: 11px;
|
||||
// color: #8b8d9a;
|
||||
//
|
||||
// a {
|
||||
// position: relative;
|
||||
// top: 4px;
|
||||
// margin-left: 10px;
|
||||
// }
|
||||
//
|
||||
// span.handle {
|
||||
// position: relative;
|
||||
// top: 5px;
|
||||
// margin: 0 0 0 15px;
|
||||
// cursor: move;
|
||||
// }
|
||||
// } // li div.more
|
||||
// } // ul.list li
|
||||
// }
|
||||
ul.list {
|
||||
background: #fff;
|
||||
list-style: none;
|
||||
margin: 0px 0 20px 0;
|
||||
|
||||
li.item {
|
||||
position: relative;
|
||||
height: 31px;
|
||||
line-height: 31px;
|
||||
|
||||
background: #ebedf4;
|
||||
@include border-radius(16px);
|
||||
@include box-shadow(rgba(0, 0, 0, 0.2) 0px 1px 0px 0px);
|
||||
|
||||
margin-bottom: 10px;
|
||||
clear: both;
|
||||
|
||||
a {
|
||||
margin-left: 18px;
|
||||
@include hover-link;
|
||||
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
color: #1F82BC;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
// em {
|
||||
// display: block;
|
||||
// float: left;
|
||||
// height: 31px;
|
||||
// width: 18px;
|
||||
// }
|
||||
|
||||
// strong {
|
||||
// display: block;
|
||||
// height: 31px;
|
||||
// margin-left: 18px;
|
||||
//
|
||||
// a {
|
||||
// position: relative;
|
||||
// top: 2px;
|
||||
// left: 15px;
|
||||
//
|
||||
// text-decoration: none;
|
||||
// color: #1f82bc;
|
||||
// font-size: 13px;
|
||||
// @include single-text-shadow(#fff, 1px, 1px, 1px);
|
||||
//
|
||||
// &:hover {
|
||||
// text-decoration: underline;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// &.sortable li strong a { left: 10px; }
|
||||
|
||||
div.more {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
right: 15px;
|
||||
|
||||
font-size: 11px;
|
||||
color: #8b8d9a;
|
||||
|
||||
a {
|
||||
position: relative;
|
||||
top: 4px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
// span.handle {
|
||||
// position: relative;
|
||||
// top: 5px;
|
||||
// margin: 0 0 0 15px;
|
||||
// cursor: move;
|
||||
// }
|
||||
} // li div.more
|
||||
} // ul.list li
|
||||
}
|
||||
|
||||
// ul.theme-assets {
|
||||
// margin-left: 40px;
|
||||
|
@ -11,6 +11,8 @@
|
||||
.nav {
|
||||
@include box-header;
|
||||
|
||||
padding-left: 0px;
|
||||
|
||||
a {
|
||||
float: left;
|
||||
display: block;
|
||||
|
@ -431,5 +431,31 @@ form.formtastic {
|
||||
|
||||
} //ol
|
||||
} // fieldset
|
||||
|
||||
// theme assets
|
||||
.selector {
|
||||
position: relative;
|
||||
|
||||
a.alt {
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
line-height: 32px;
|
||||
|
||||
top: 0px;
|
||||
right: 20px;
|
||||
padding-left: 20px;
|
||||
|
||||
background: transparent image-url("locomotive/icons/asset_switch.png") no-repeat left center;
|
||||
|
||||
color: #787a89;
|
||||
font-size: 11px;
|
||||
@include single-text-shadow(rgba(255, 255, 255, 0.6), 1px, 1px, 1px);
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ module Locomotive
|
||||
|
||||
def destroy
|
||||
@snippet = current_site.snippets.find(params[:id])
|
||||
# @snippet.destroy
|
||||
@snippet.destroy
|
||||
respond_with @snippet, :location => theme_assets_url
|
||||
end
|
||||
|
||||
|
@ -20,31 +20,31 @@ module Locomotive
|
||||
end
|
||||
|
||||
def new
|
||||
@asset = current_site.theme_assets.build(params[:id])
|
||||
respond_with @asset
|
||||
@theme_asset = current_site.theme_assets.build(params[:id])
|
||||
respond_with @theme_asset
|
||||
end
|
||||
|
||||
def create
|
||||
@asset = current_site.theme_assets.create(params[:theme_asset])
|
||||
respond_with @asset, :location => edit_theme_asset_url(@asset._id)
|
||||
@theme_asset = current_site.theme_assets.create(params[:theme_asset])
|
||||
respond_with @theme_asset, :location => edit_theme_asset_url(@theme_asset._id)
|
||||
end
|
||||
|
||||
def edit
|
||||
@asset = current_site.theme_assets.find(params[:id])
|
||||
resource.performing_plain_text = true if resource.stylesheet_or_javascript?
|
||||
respond_with @asset
|
||||
@theme_asset = current_site.theme_assets.find(params[:id])
|
||||
@theme_asset.performing_plain_text = true if @theme_asset.stylesheet_or_javascript?
|
||||
respond_with @theme_asset
|
||||
end
|
||||
|
||||
def update
|
||||
@asset = current_site.theme_assets.find(params[:id])
|
||||
@asset.update_attributes(params[:theme_asset])
|
||||
respond_with @asset, :location => edit_theme_asset_url(@asset._id)
|
||||
@theme_asset = current_site.theme_assets.find(params[:id])
|
||||
@theme_asset.update_attributes(params[:theme_asset])
|
||||
respond_with @theme_asset, :location => edit_theme_asset_url(@theme_asset._id)
|
||||
end
|
||||
|
||||
def destroy
|
||||
@asset = current_site.theme_assets.find(params[:id])
|
||||
@asset.destroy
|
||||
respond_with @asset
|
||||
@theme_asset = current_site.theme_assets.find(params[:id])
|
||||
@theme_asset.destroy
|
||||
respond_with @theme_asset
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -9,10 +9,10 @@ module Locomotive
|
||||
## fields ##
|
||||
field :local_path
|
||||
field :content_type
|
||||
field :width, :type => Integer
|
||||
field :height, :type => Integer
|
||||
field :size, :type => Integer
|
||||
field :folder, :default => nil
|
||||
field :width, :type => Integer
|
||||
field :height, :type => Integer
|
||||
field :size, :type => Integer
|
||||
field :folder, :default => nil
|
||||
mount_uploader :source, ThemeAssetUploader, :mount_on => :source_filename
|
||||
|
||||
## associations ##
|
||||
@ -23,12 +23,14 @@ module Locomotive
|
||||
index [[:site_id, Mongo::ASCENDING], [:local_path, Mongo::ASCENDING]]
|
||||
|
||||
## callbacks ##
|
||||
before_validation :check_for_folder_changes
|
||||
before_validation :store_plain_text
|
||||
before_validation :sanitize_folder
|
||||
before_validation :build_local_path
|
||||
|
||||
## validations ##
|
||||
validates_presence_of :site, :source
|
||||
validates_presence_of :site
|
||||
validates_presence_of :source, :on => :create
|
||||
validates_presence_of :plain_text_name, :if => Proc.new { |a| a.performing_plain_text? }
|
||||
validates_uniqueness_of :local_path, :scope => :site_id
|
||||
validates_integrity_of :source
|
||||
@ -37,7 +39,8 @@ module Locomotive
|
||||
## named scopes ##
|
||||
|
||||
## accessors ##
|
||||
attr_accessor :plain_text_name, :plain_text, :plain_text_type, :performing_plain_text
|
||||
attr_accessor :plain_text_name, :plain_text, :plain_text_type, :performing_plain_text
|
||||
attr_accessible :folder, :source, :plain_text_type, :performing_plain_text, :plain_text_name, :plain_text
|
||||
|
||||
## methods ##
|
||||
|
||||
@ -82,6 +85,8 @@ module Locomotive
|
||||
end
|
||||
|
||||
def store_plain_text
|
||||
return if self.persisted? && !self.stylesheet_or_javascript?
|
||||
|
||||
self.content_type ||= @plain_text_type if self.performing_plain_text?
|
||||
|
||||
data = self.performing_plain_text? ? self.plain_text : self.source.read
|
||||
@ -90,7 +95,7 @@ module Locomotive
|
||||
|
||||
sanitized_source = self.escape_shortcut_urls(data)
|
||||
|
||||
self.source = CarrierWave::SanitizedFile.new({
|
||||
self.source = ::CarrierWave::SanitizedFile.new({
|
||||
:tempfile => StringIO.new(sanitized_source),
|
||||
:filename => "#{self.plain_text_name}.#{self.stylesheet? ? 'css' : 'js'}"
|
||||
})
|
||||
@ -122,7 +127,7 @@ module Locomotive
|
||||
self.folder = ActiveSupport::Inflector.transliterate(self.folder).gsub(/(\s)+/, '_').gsub(/^\//, '').gsub(/\/$/, '')
|
||||
|
||||
# folder should begin by a root folder
|
||||
if (self.folder =~ /^(stylesheets|javascripts|images|medias|fonts)/).nil?
|
||||
if (self.folder =~ /^(stylesheets|javascripts|images|media|fonts)/).nil?
|
||||
self.folder = File.join(self.content_type.to_s.pluralize, self.folder)
|
||||
end
|
||||
end
|
||||
@ -138,7 +143,7 @@ module Locomotive
|
||||
def escape_shortcut_urls(text)
|
||||
return if text.blank?
|
||||
|
||||
text.gsub(/[("'](\/(stylesheets|javascripts|images|medias)\/(([^;.]+)\/)*([a-z_\-0-9]+)\.[a-z]{2,3})[)"']/) do |path|
|
||||
text.gsub(/[("'](\/(stylesheets|javascripts|images|media)\/(([^;.]+)\/)*([a-z_\-0-9]+)\.[a-z]{2,3})[)"']/) do |path|
|
||||
|
||||
sanitized_path = path.gsub(/[("')]/, '').gsub(/^\//, '')
|
||||
|
||||
@ -150,8 +155,21 @@ module Locomotive
|
||||
end
|
||||
end
|
||||
|
||||
def check_for_folder_changes
|
||||
# https://github.com/jnicklas/carrierwave/issues/330
|
||||
# https://github.com/jnicklas/carrierwave-mongoid/issues/23
|
||||
if self.persisted? && self.folder_changed? && !self.source_filename_changed?
|
||||
# a simple way to rename a file
|
||||
old_asset = self.class.find(self._id)
|
||||
file = old_asset.source.file
|
||||
file.content_type = File.mime_type?(file.path) if file.content_type.nil?
|
||||
self.source = file
|
||||
self.changed_attributes['source_filename'] = nil # delete the old file
|
||||
end
|
||||
end
|
||||
|
||||
def content_type_can_not_changed
|
||||
self.errors.add(:source, :extname_changed) if !self.new_record? && self.content_type_changed?
|
||||
self.errors.add(:source, :extname_changed) if self.persisted? && self.content_type_changed?
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -1,6 +1,8 @@
|
||||
module Locomotive
|
||||
class ThemeAssetPresenter < BasePresenter
|
||||
|
||||
delegate :content_type, :to => :source
|
||||
|
||||
def local_path
|
||||
self.source.local_path(true)
|
||||
end
|
||||
@ -13,12 +15,16 @@ module Locomotive
|
||||
number_to_human_size(self.source.size)
|
||||
end
|
||||
|
||||
def dimensions
|
||||
self.source.image? ? "#{self.source.width}px x #{self.source.height}px" : nil
|
||||
end
|
||||
|
||||
def updated_at
|
||||
I18n.l(self.source.updated_at, :format => :short)
|
||||
end
|
||||
|
||||
def included_methods
|
||||
super + %w(local_path url size updated_at)
|
||||
super + %w(content_type local_path url size dimensions updated_at)
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -18,8 +18,8 @@ module Locomotive
|
||||
end
|
||||
|
||||
def self.build(site, path)
|
||||
asset = ThemeAsset.new(:site => site, :folder => File.dirname(path))
|
||||
uploader = ThemeAssetUploader.new(asset)
|
||||
asset = ThemeAsset.new(:site => site, :folder => File.dirname(path))
|
||||
uploader = ThemeAssetUploader.new(asset)
|
||||
uploader.retrieve_from_store!(File.basename(path))
|
||||
uploader
|
||||
end
|
||||
|
@ -1,6 +1,6 @@
|
||||
%script{ :type => 'text/html', :id => 'snippet_item' }
|
||||
|
||||
%strong= link_to "{{name}}", edit_snippet_path('{{id}}')
|
||||
%strong= link_to "{{name}}", edit_snippet_path('snippet_id').gsub(/\/snippet_id\//, '/{{id}}/')
|
||||
.more
|
||||
%span!= t('.updated_at')
|
||||
{{updated_at}}
|
||||
|
@ -1,12 +1,9 @@
|
||||
- edit = local_assigns.key?(:edit) ? edit : true
|
||||
%script{ :type => 'text/html', :id => 'editable_theme_asset_item' }
|
||||
|
||||
%li{ :class => (asset.new_record? ? 'new-asset' : 'asset') }
|
||||
%strong= link_to asset.local_path(!edit), edit ? edit_theme_asset_path(asset) : asset.source.url, :'data-local-path' => asset.local_path
|
||||
%strong= link_to "{{local_path}}", edit_theme_asset_path('asset_id').gsub(/\/asset_id\//, '/{{id}}/')
|
||||
.more
|
||||
%span.size= number_to_human_size(asset.size)
|
||||
—
|
||||
%span.size {{size}}
|
||||
%span!= t('.updated_at')
|
||||
%span.date= l asset.updated_at, :format => :short
|
||||
%span.date {{updated_at}}
|
||||
|
||||
- if edit && can?(:destroy, asset)
|
||||
= link_to 'x', theme_asset_path(asset), :class => 'remove', :confirm => t('locomotive.messages.confirm'), :method => :delete
|
||||
= link_to 'x', '#', :class => 'remove', :confirm => t('locomotive.messages.confirm')
|
@ -1,6 +1,9 @@
|
||||
- content_for :head do
|
||||
/ = include_javascripts :image_picker, :theme_assets
|
||||
/ = include_stylesheets :fancybox
|
||||
= render '/locomotive/theme_assets/picker'
|
||||
|
||||
- content_for :backbone_view_data do
|
||||
:plain
|
||||
{ theme_asset: #{@theme_asset.persisted? ? @theme_asset.to_json : 'null'} }
|
||||
|
||||
= f.hidden_field :performing_plain_text
|
||||
|
||||
@ -9,8 +12,7 @@
|
||||
= f.input :source
|
||||
|
||||
- if allow_plain_text_editing?(@theme_asset)
|
||||
%span.alt
|
||||
!= t('locomotive.theme_assets.form.choose_plain_text')
|
||||
= link_to t('locomotive.theme_assets.form.choose_plain_text'), '#', :class => 'alt'
|
||||
|
||||
- if allow_plain_text_editing?(@theme_asset)
|
||||
#text-selector{ :class => "selector #{'hidden' unless display_plain_text?(@theme_asset)}", :style => "#{'display: none' unless display_plain_text?(@theme_asset)}" }
|
||||
@ -19,12 +21,11 @@
|
||||
- if @theme_asset.new_record?
|
||||
= f.input :plain_text_name
|
||||
|
||||
= f.input :plain_text_type, :as => 'select', :collection => %w(stylesheet javascript)
|
||||
= f.input :plain_text_type, :as => 'select', :collection => %w(stylesheet javascript), :include_blank => false
|
||||
|
||||
= f.input :plain_text, :as => :'Locomotive::Code', :type => plain_text_type(@theme_asset)
|
||||
|
||||
%span.alt
|
||||
!= t('locomotive.theme_assets.form.choose_file')
|
||||
= link_to t('locomotive.theme_assets.form.choose_file'), '#', :class => 'alt'
|
||||
|
||||
= f.inputs :name => :options, :class => "inputs foldable #{'folded' if inputs_folded?(@asset)}" do
|
||||
= f.inputs :name => :options, :class => "inputs foldable #{'folded' if inputs_folded?(@theme_asset)}" do
|
||||
= f.input :folder
|
@ -12,7 +12,6 @@
|
||||
= file_field_tag 'theme_asset[source]'
|
||||
= link_to t('locomotive.theme_assets.image_picker.upload'), theme_assets_url(:json), :class => 'new', :id => 'upload-link'
|
||||
|
||||
|
||||
%script{ :type => 'text/html', :id => 'theme_asset' }
|
||||
|
||||
%li.item
|
||||
@ -22,5 +21,3 @@
|
||||
—
|
||||
%span!= t('.updated_at')
|
||||
%span.date {{updated_at}}
|
||||
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
- content_for :buttons do
|
||||
= local_action_button t('locomotive.theme_assets.index.new'), new_theme_asset_url, :class => 'new'
|
||||
|
||||
%p
|
||||
%p.help
|
||||
- if %w(image javascript stylesheet).include?(@theme_asset.content_type.to_s)
|
||||
!= t(".help_#{@theme_asset.content_type}", :path => @theme_asset.local_path(true), :width => @theme_asset.width, :height => @theme_asset.height)
|
||||
|
||||
|
@ -1,13 +1,37 @@
|
||||
- title t('.title')
|
||||
|
||||
- content_for :head do
|
||||
= render 'asset'
|
||||
|
||||
= render 'list', :name => 'images', :title => t('.images'), :empty_message => t('.no_items', :url => new_theme_asset_url)
|
||||
= render 'list', :name => 'media', :title => t('.media'), :empty_message => t('.no_items', :url => new_theme_asset_url)
|
||||
|
||||
- if can?(:manage, Locomotive::Snippet)
|
||||
= render '/locomotive/snippets/snippet'
|
||||
= render 'list', :name => 'snippets', :title => t('.snippets'), :empty_message => t('locomotive.snippets.index.no_items', :url => new_snippet_url)
|
||||
|
||||
- if can?(:manage, Locomotive::ThemeAsset)
|
||||
= render 'list', :name => 'js_and_css', :title => t('.css_and_js'), :empty_message => t('.no_items', :url => new_theme_asset_url)
|
||||
= render 'list', :name => 'fonts', :title => t('.fonts'), :empty_message => t('.no_items', :url => new_theme_asset_url)
|
||||
|
||||
- content_for :backbone_view_data do
|
||||
:plain
|
||||
{ snippets: #{@snippets.to_json} }
|
||||
{
|
||||
snippets: #{can?(:manage, Locomotive::Snippet) ? @snippets.to_json : 'null'},
|
||||
images: #{@assets[:images].to_json},
|
||||
media: #{@assets[:media].to_json},
|
||||
js_and_css_assets: #{can?(:manage, Locomotive::ThemeAsset) ? @js_and_css_assets.to_json : 'null'},
|
||||
fonts: #{can?(:manage, Locomotive::ThemeAsset) ? @assets[:fonts].to_json : 'null'}
|
||||
}
|
||||
|
||||
- content_for :submenu do
|
||||
= render_cell 'locomotive/settings_menu', :show
|
||||
|
||||
- content_for :buttons do
|
||||
- if can?(:manage, Locomotive::ThemeAsset)
|
||||
.button-wrapper.quick-upload
|
||||
= file_field_tag 'theme_asset[source]'
|
||||
= local_action_button :quick_upload, theme_assets_url(:json), :class => 'new'
|
||||
= local_action_button t('locomotive.snippets.index.new'), new_snippet_url, :class => 'new' if can?(:manage, Locomotive::Snippet)
|
||||
= local_action_button :new, new_theme_asset_url, :class => 'new' if can?(:manage, Locomotive::ThemeAsset)
|
||||
|
||||
@ -16,49 +40,12 @@
|
||||
- if can?(:manage, Locomotive::Snippet)
|
||||
#snippets-anchor
|
||||
|
||||
- content_for :head do
|
||||
= render '/locomotive/snippets/snippet'
|
||||
= render 'list', :name => 'snippets', :title => t('.snippets'), :empty_message => t('locomotive.snippets.index.no_items', :url => new_snippet_url)
|
||||
- if can?(:manage, Locomotive::ThemeAsset)
|
||||
#js-and-css-anchor
|
||||
|
||||
/ .box
|
||||
/ %h3!= t('.snippets')
|
||||
/ .inner
|
||||
/ - if @snippets.empty?
|
||||
/ %p.no-items!= t('locomotive.snippets.index.no_items', :url => new_snippet_url)
|
||||
/ - else
|
||||
/ %ul.snippets
|
||||
/ = render @snippets
|
||||
#images-anchor
|
||||
|
||||
- if can?(:manage, Locomotive::ThemeAsset)
|
||||
.box
|
||||
%h3!= t('.css_and_js')
|
||||
.inner
|
||||
- if @js_and_css_assets.empty?
|
||||
%p.no-items!= t('.no_items', :url => new_theme_asset_url)
|
||||
- else
|
||||
%ul.js-css
|
||||
= render :partial => 'asset', :collection => @js_and_css_assets
|
||||
#fonts-anchor
|
||||
|
||||
.box
|
||||
%h3!= t('.images')
|
||||
.inner
|
||||
- if @assets[:images].nil?
|
||||
%p.no-items!= t('.no_items', :url => new_theme_asset_url)
|
||||
- else
|
||||
%ul.images
|
||||
= render :partial => 'asset', :collection => @assets[:images]
|
||||
|
||||
- if can?(:manage, Locomotive::ThemeAsset)
|
||||
- if @assets[:fonts]
|
||||
.box
|
||||
%h3!= t('.fonts')
|
||||
.inner
|
||||
%ul.fonts
|
||||
= render :partial => 'asset', :collection => @assets[:fonts]
|
||||
|
||||
- if @assets[:medias]
|
||||
.box
|
||||
%h3!= t('.medias')
|
||||
.inner
|
||||
%ul.media
|
||||
= render :partial => 'asset', :collection => @assets[:medias]
|
||||
#media-anchor
|
@ -177,7 +177,7 @@ de:
|
||||
css_and_js: Style und Javascript
|
||||
fonts: Fonts
|
||||
images: Bilder
|
||||
medias: Medien
|
||||
media: Medien
|
||||
no_items: "Momentan gibt es keine Dateien. Klicke einfach <a href='%{url}'>hier</a>, um die erste Datei zu erstellen."
|
||||
asset:
|
||||
updated_at: Aktualisiert am
|
||||
|
@ -193,7 +193,7 @@ en:
|
||||
css_and_js: Style and javascript
|
||||
fonts: Fonts
|
||||
images: Images
|
||||
medias: Medias
|
||||
media: Media
|
||||
no_items: "There are no files for now."
|
||||
asset:
|
||||
updated_at: Updated at
|
||||
|
@ -187,7 +187,7 @@ es:
|
||||
css_and_js: Estilo y Javascript
|
||||
fonts: Fuentes
|
||||
images: Imágenes
|
||||
medias: Media
|
||||
media: Media
|
||||
no_items: "Por ahora no hay ficheros."
|
||||
asset:
|
||||
updated_at: Última actualización
|
||||
|
@ -191,7 +191,7 @@ fr:
|
||||
snippets: Snippets
|
||||
css_and_js: Style et javascript
|
||||
images: Images
|
||||
medias: Médias
|
||||
media: Média
|
||||
fonts: Polices
|
||||
no_items: "Il n'existe pas de fichiers."
|
||||
asset:
|
||||
|
@ -186,7 +186,7 @@ it:
|
||||
css_and_js: Style e javascript
|
||||
fonts: Fonts
|
||||
images: Immagini
|
||||
medias: Media
|
||||
media: Media
|
||||
no_items: "Per ora non ci sono file. Clicca <a href=\"%{url}\">qui</a> per creare il primo."
|
||||
asset:
|
||||
updated_at: Modificato il
|
||||
|
@ -173,7 +173,7 @@ nl:
|
||||
css_and_js: Stijlen en javascripts
|
||||
fonts: Lettertypes
|
||||
images: Afbeeldingen
|
||||
medias: Media
|
||||
media: Media
|
||||
no_items: "Er zijn momenteel geen bestanden. Klik <a href=\"%{url}\">hier</a> om de eerste aan te maken."
|
||||
asset:
|
||||
updated_at: Gewijzigd op
|
||||
|
@ -188,7 +188,7 @@
|
||||
css_and_js: Stilark og javascript
|
||||
fonts: Fonter
|
||||
images: Bilder
|
||||
medias: Media
|
||||
media: Media
|
||||
no_items: "Det er ingen filer her ennå."
|
||||
asset:
|
||||
updated_at: Sist oppdatert
|
||||
|
@ -172,7 +172,7 @@ pt-BR:
|
||||
css_and_js: CSS e Javascript
|
||||
fonts: Fontes
|
||||
images: Imagens
|
||||
medias: Mídia
|
||||
media: Mídia
|
||||
no_items: "Ainda não existem arquivos. Clique <a href=\"%{url}\">aqui</a> para criar o primeiro."
|
||||
asset:
|
||||
updated_at: Atualizado em
|
||||
|
@ -187,7 +187,7 @@ ru:
|
||||
css_and_js: Стили и javascript
|
||||
fonts: Шрифты
|
||||
images: Изображения
|
||||
medias: Медиа
|
||||
media: Медиа
|
||||
no_items: "Пока нет ни одного файла."
|
||||
asset:
|
||||
updated_at: Обновлено
|
||||
|
5
doc/TODO
5
doc/TODO
@ -25,12 +25,13 @@ x edit my site
|
||||
x create a new site
|
||||
x create a new accounts
|
||||
- theme assets
|
||||
xpolish the page
|
||||
x polish the page
|
||||
x snippets
|
||||
- delete in ajax
|
||||
x delete in ajax
|
||||
- upload many files at once
|
||||
- site picker
|
||||
- import/export
|
||||
- QU
|
||||
- content types
|
||||
|
||||
- install a site by default at the first installation (without asking)
|
||||
|
@ -18,7 +18,7 @@ module Locomotive
|
||||
def content_types
|
||||
{
|
||||
:image => ['image/jpeg', 'image/pjpeg', 'image/gif', 'image/png', 'image/x-png', 'image/jpg', 'image/x-icon'],
|
||||
:media => [/^video/, 'application/x-shockwave-flash', 'application/x-swf', /^audio/, 'application/ogg', 'application/x-mp3'],
|
||||
:media => [/^video/, 'application/x-shockwave-flash', 'application/x-flash-video', 'application/x-swf', /^audio/, 'application/ogg', 'application/x-mp3'],
|
||||
:pdf => ['application/pdf', 'application/x-pdf'],
|
||||
:stylesheet => ['text/css'],
|
||||
:javascript => ['text/javascript', 'text/js', 'application/x-javascript', 'application/javascript', 'text/x-component'],
|
||||
|
Loading…
Reference in New Issue
Block a user