theme assets
2
.gitignore
vendored
@ -4,3 +4,5 @@ log/*.log
|
||||
tmp/**/*
|
||||
.DS_Store
|
||||
rerun.txt
|
||||
uploads
|
||||
spec/tmp
|
||||
|
4
Gemfile
@ -11,9 +11,11 @@ gem "mongoid", ">= 2.0.0.beta4"
|
||||
gem "mongoid_acts_as_tree", :git => 'git://github.com/evansagge/mongoid_acts_as_tree.git'
|
||||
gem "warden"
|
||||
gem "devise", ">= 1.1.rc0"
|
||||
gem "haml", '>= 3.0.0.beta.2', :git => 'git://github.com/nex3/haml.git'
|
||||
gem "haml", '>= 3.0.1' #, :git => 'git://github.com/nex3/haml.git'
|
||||
gem "formtastic", :git => 'git://github.com/justinfrench/formtastic.git', :branch => 'rails3'
|
||||
gem "mongoid_acts_as_tree", :git => 'git://github.com/evansagge/mongoid_acts_as_tree.git'
|
||||
gem "carrierwave", :git => "http://github.com/jnicklas/carrierwave.git"
|
||||
gem "rmagick"
|
||||
|
||||
|
||||
# Development environment
|
||||
|
54
app/controllers/admin/theme_assets_controller.rb
Normal file
@ -0,0 +1,54 @@
|
||||
module Admin
|
||||
class ThemeAssetsController < BaseController
|
||||
|
||||
sections 'settings', 'theme_assets'
|
||||
|
||||
def index
|
||||
assets = current_site.theme_assets.all
|
||||
@non_image_assets = assets.find_all { |a| a.stylesheet? || a.javascript? }
|
||||
@image_assets = assets.find_all { |a| a.image? }
|
||||
end
|
||||
|
||||
def new
|
||||
@asset = current_site.theme_assets.build
|
||||
end
|
||||
|
||||
def edit
|
||||
@asset = current_site.theme_assets.find(params[:id])
|
||||
end
|
||||
|
||||
def create
|
||||
@asset = current_site.theme_assets.build(params[:theme_asset])
|
||||
|
||||
if @asset.save
|
||||
flash_success!
|
||||
redirect_to edit_admin_theme_asset_url(@asset)
|
||||
else
|
||||
flash_error!
|
||||
render :action => 'new'
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
@asset = current_site.theme_assets.find(params[:id])
|
||||
|
||||
if @asset.update_attributes(params[:theme_asset])
|
||||
flash_success!
|
||||
redirect_to edit_admin_theme_asset_url(@asset)
|
||||
else
|
||||
flash_error!
|
||||
render :action => 'edit'
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@asset = current_site.theme_assets.find(params[:id])
|
||||
@asset.destroy
|
||||
|
||||
flash_success!
|
||||
redirect_to admin_theme_assets_url
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
@ -4,6 +4,9 @@ class PagesController < ActionController::Base
|
||||
|
||||
before_filter :require_site
|
||||
|
||||
def show; end
|
||||
def show
|
||||
logger.debug "fullpath = #{request.fullpath}"
|
||||
# @page = current_site.pages.find
|
||||
end
|
||||
|
||||
end
|
40
app/helpers/admin/assets_helper.rb
Normal file
@ -0,0 +1,40 @@
|
||||
module Admin::AssetsHelper
|
||||
|
||||
def vignette_tag(asset)
|
||||
if asset.image?
|
||||
if asset.width < 80 && asset.height < 80
|
||||
image_tag(asset.source.url)
|
||||
else
|
||||
image_tag(asset.source.url(:medium))
|
||||
end
|
||||
# elsif asset.pdf?
|
||||
# image_tag(asset.source.url(:medium))
|
||||
else
|
||||
mime_type_to_image(asset, :medium)
|
||||
end
|
||||
end
|
||||
|
||||
def mime_type_to_image(asset, size = :thumb)
|
||||
mime_type = File.mime_type?(asset.source_filename)
|
||||
filename = "unknown"
|
||||
|
||||
if !(mime_type =~ /pdf/).nil?
|
||||
filename = "PDF"
|
||||
elsif !(mime_type =~ /css/).nil?
|
||||
filename = "CSS"
|
||||
elsif !(mime_type =~ /javascript/).nil?
|
||||
filename = "JAVA"
|
||||
end
|
||||
|
||||
image_tag(File.join("admin", "icons", "filetype", size.to_s, filename + ".png"))
|
||||
end
|
||||
|
||||
def image_dimensions_and_size(asset)
|
||||
content_tag(:small, "#{asset.width}px x #{@asset.height}px | #{number_to_human_size(asset.size)}")
|
||||
end
|
||||
|
||||
def allow_plain_text_editing?(asset)
|
||||
asset.new_record? || asset.stylesheet? || asset.javascript?
|
||||
end
|
||||
|
||||
end
|
@ -21,7 +21,7 @@ class Page
|
||||
before_validate :normalize_slug
|
||||
before_save { |p| p.parent_id = nil if p.parent_id.blank? }
|
||||
before_save :change_parent
|
||||
before_create { |p| p.parts << PagePart.build_body_part }
|
||||
before_create { |p| p.parts << PagePart.build_body_part if p.parts.empty? }
|
||||
before_create { |p| p.fix_position(false) }
|
||||
before_create :add_to_list_bottom
|
||||
before_destroy :do_not_remove_index_and_404_pages
|
||||
|
@ -11,6 +11,7 @@ class Site
|
||||
has_many_related :pages
|
||||
has_many_related :layouts
|
||||
has_many_related :snippets
|
||||
has_many_related :theme_assets
|
||||
embeds_many :memberships
|
||||
|
||||
## validations ##
|
||||
@ -81,7 +82,7 @@ class Site
|
||||
end
|
||||
|
||||
def destroy_in_cascade!
|
||||
%w{pages layouts snippets}.each do |association|
|
||||
%w{pages layouts snippets theme_assets}.each do |association|
|
||||
self.send(association).destroy_all
|
||||
end
|
||||
end
|
||||
|
94
app/models/theme_asset.rb
Normal file
@ -0,0 +1,94 @@
|
||||
class ThemeAsset
|
||||
include Mongoid::Document
|
||||
include Mongoid::Timestamps
|
||||
|
||||
## fields ##
|
||||
field :slug, :type => String
|
||||
field :content_type, :type => String
|
||||
field :width, :type => Integer
|
||||
field :height, :type => Integer
|
||||
field :size, :type => Integer
|
||||
mount_uploader :source, ThemeAssetUploader
|
||||
|
||||
## associations ##
|
||||
belongs_to_related :site
|
||||
|
||||
## callbacks ##
|
||||
before_validate :sanitize_slug
|
||||
before_validate :store_plain_text
|
||||
before_save :set_slug
|
||||
|
||||
## validations ##
|
||||
validate :extname_can_not_be_changed
|
||||
validates_presence_of :site
|
||||
validates_presence_of :slug, :if => Proc.new { |a| a.new_record? && a.performing_plain_text? }
|
||||
validates_integrity_of :source
|
||||
|
||||
## accessors ##
|
||||
attr_accessor :performing_plain_text
|
||||
|
||||
## methods ##
|
||||
|
||||
%w{image stylesheet javascript}.each do |type|
|
||||
define_method("#{type}?") do
|
||||
self.content_type == type
|
||||
end
|
||||
end
|
||||
|
||||
def plain_text
|
||||
@plain_text ||= (if self.stylesheet? || self.javascript?
|
||||
File.read(self.source.path)
|
||||
else
|
||||
nil
|
||||
end)
|
||||
end
|
||||
|
||||
def plain_text=(source)
|
||||
self.performing_plain_text = true if self.performing_plain_text.nil?
|
||||
@plain_text = source
|
||||
end
|
||||
|
||||
def performing_plain_text?
|
||||
!(self.performing_plain_text.blank? || self.performing_plain_text == 'false' || self.performing_plain_text == false)
|
||||
end
|
||||
|
||||
def store_plain_text
|
||||
return if self.plain_text.blank?
|
||||
|
||||
self.source = CarrierWave::SanitizedFile.new({
|
||||
:tempfile => StringIO.new(self.plain_text),
|
||||
:filename => self.filename
|
||||
})
|
||||
end
|
||||
|
||||
def filename
|
||||
if not self.image?
|
||||
"#{self.slug}.#{self.stylesheet? ? 'css' : 'js'}"
|
||||
else
|
||||
"#{self.slug}#{File.extname(self.source.file.original_filename)}"
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def sanitize_slug
|
||||
self.slug.slugify!(:underscore => true) if self.slug.present?
|
||||
end
|
||||
|
||||
def set_slug
|
||||
if self.slug.blank?
|
||||
self.slug = File.basename(self.source_filename, File.extname(self.source_filename))
|
||||
self.sanitize_slug
|
||||
end
|
||||
end
|
||||
|
||||
def extname_can_not_be_changed
|
||||
return if self.new_record?
|
||||
|
||||
Rails.logger.debug "previous = #{self.source.file.original_filename.inspect} / #{self.source_filename.inspect}"
|
||||
|
||||
if File.extname(self.source.file.original_filename) != File.extname(self.source_filename)
|
||||
self.errors.add(:source, :extname_changed)
|
||||
end
|
||||
end
|
||||
end
|
87
app/uploaders/theme_asset_uploader.rb
Normal file
@ -0,0 +1,87 @@
|
||||
# encoding: utf-8
|
||||
|
||||
class ThemeAssetUploader < CarrierWave::Uploader::Base
|
||||
|
||||
include CarrierWave::RMagick
|
||||
|
||||
# Choose what kind of storage to use for this uploader
|
||||
# storage :file
|
||||
# storage :s3
|
||||
|
||||
# Override the directory where uploaded files will be stored
|
||||
# This is a sensible default for uploaders that are meant to be mounted:
|
||||
def store_dir
|
||||
"sites/#{model.site_id}/themes/#{model.id}"
|
||||
end
|
||||
|
||||
version :thumb do
|
||||
process :resize_to_fill => [50, 50]
|
||||
process :convert => 'png'
|
||||
end
|
||||
|
||||
version :medium do
|
||||
process :resize_to_fill => [80, 80]
|
||||
process :convert => 'png'
|
||||
end
|
||||
|
||||
version :preview do
|
||||
process :resize_to_fit => [880, 1100]
|
||||
process :convert => 'png'
|
||||
end
|
||||
|
||||
process :set_content_type
|
||||
process :set_size
|
||||
process :set_width_and_height
|
||||
|
||||
def set_content_type
|
||||
value = :other
|
||||
|
||||
self.class.content_types.each_pair do |type, rules|
|
||||
rules.each do |rule|
|
||||
case rule
|
||||
when String then value = type if file.content_type == rule
|
||||
when Regexp then value = type if (file.content_type =~ rule) == 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
model.content_type = value
|
||||
end
|
||||
|
||||
def set_size
|
||||
model.size = file.size
|
||||
end
|
||||
|
||||
def set_width_and_height
|
||||
if model.image?
|
||||
model.width, model.height = `identify -format "%wx%h" #{file.path}`.split(/x/).collect(&:to_i)
|
||||
end
|
||||
end
|
||||
|
||||
def self.content_types
|
||||
{
|
||||
:image => ['image/jpeg', 'image/pjpeg', 'image/gif', 'image/png', 'image/x-png', 'image/jpg'],
|
||||
:stylesheet => ['text/css'],
|
||||
:javascript => ['text/javascript', 'text/js', 'application/x-javascript']
|
||||
}
|
||||
end
|
||||
|
||||
def extension_white_list
|
||||
%w(jpg jpeg gif png css js)
|
||||
end
|
||||
|
||||
def filename
|
||||
Rails.logger.debug "slug ===> #{model.slug} / #{model.content_type} / #{original_filename}"
|
||||
|
||||
if model.slug.present?
|
||||
model.filename
|
||||
else
|
||||
extension = File.extname(original_filename)
|
||||
basename = File.basename(original_filename, extension).slugify(:underscore => true)
|
||||
"#{basename}#{extension}"
|
||||
end
|
||||
#
|
||||
# original_filename
|
||||
end
|
||||
|
||||
end
|
@ -34,7 +34,7 @@
|
||||
= f.custom_input :language, { :css => 'full', :with_label => false } do
|
||||
- Locomotive.config.locales.each do |locale|
|
||||
%span
|
||||
= image_tag "admin/flags/#{locale}.png"
|
||||
= image_tag "admin/icons/flags/#{locale}.png"
|
||||
= f.radio_button :locale, locale
|
||||
|
||||
= t(".#{locale}")
|
||||
|
@ -2,4 +2,5 @@
|
||||
= admin_submenu_item 'site', edit_admin_current_site_url
|
||||
= admin_submenu_item 'layouts', admin_layouts_url
|
||||
= admin_submenu_item 'snippets', admin_snippets_url
|
||||
= admin_submenu_item 'theme_assets', admin_theme_assets_url
|
||||
= admin_submenu_item 'account', edit_admin_my_account_url
|
7
app/views/admin/theme_assets/_asset.html.haml
Normal file
@ -0,0 +1,7 @@
|
||||
%li{ :class => "asset #{'last' if (asset_counter + 1) % 6 == 0}"}
|
||||
%h4= link_to truncate(asset.slug, :length => 22), edit_admin_theme_asset_path(asset)
|
||||
.image
|
||||
.inside
|
||||
= vignette_tag(asset)
|
||||
.actions
|
||||
= link_to image_tag('admin/list/icons/cross.png'), admin_theme_asset_path(asset), :class => 'remove', :confirm => t('admin.messages.confirm'), :method => :delete
|
36
app/views/admin/theme_assets/_form.html.haml
Normal file
@ -0,0 +1,36 @@
|
||||
- content_for :head do
|
||||
= javascript_include_tag 'admin/plugins/codemirror/codemirror', 'admin/theme_assets.js'
|
||||
|
||||
= f.hidden_field :performing_plain_text
|
||||
|
||||
#file-selector{ :class => "selector #{'hidden' if @asset.performing_plain_text?}" }
|
||||
= f.inputs :name => :information do
|
||||
= f.input :source
|
||||
|
||||
- if @asset.new_record? || !@asset.image?
|
||||
%span.alt
|
||||
= t('admin.theme_assets.form.choose_plain_text')
|
||||
|
||||
- if allow_plain_text_editing?(@asset)
|
||||
#text-selector{ :class => "selector #{'hidden' if !@asset.performing_plain_text?}", :style => "#{'display: none' if !@asset.performing_plain_text?}" }
|
||||
= f.inputs :name => :code, :class => 'inputs code' do
|
||||
|
||||
- if @asset.new_record?
|
||||
= f.input :slug
|
||||
|
||||
= f.custom_input :content_type do
|
||||
= f.select :content_type, ["stylesheet", "javascript"]
|
||||
|
||||
= f.custom_input :plain_text, :css => 'full', :with_label => false do
|
||||
%code{ :class => (@asset.new_record? || (@asset.size && @asset.size > 40000) ? 'nude' : @asset.content_type) }
|
||||
= f.text_area :plain_text
|
||||
|
||||
%span.alt
|
||||
= t('admin.theme_assets.form.choose_file')
|
||||
|
||||
- if @asset.image?
|
||||
= f.foldable_inputs :name => "#{t('formtastic.titles.preview')} #{image_dimensions_and_size(@asset)}", :class => 'preview' do
|
||||
%li
|
||||
.image
|
||||
.inside
|
||||
= image_tag(@asset.source.url(:preview))
|
15
app/views/admin/theme_assets/edit.html.haml
Normal file
@ -0,0 +1,15 @@
|
||||
- title t('.title', :file => @asset.source_filename)
|
||||
|
||||
- content_for :submenu do
|
||||
= render 'admin/shared/menu/settings'
|
||||
|
||||
- content_for :buttons do
|
||||
= admin_button_tag t('admin.theme_assets.index.new'), new_admin_theme_asset_url, :class => 'add'
|
||||
|
||||
%p= t('.help')
|
||||
|
||||
= semantic_form_for @asset, :url => admin_theme_asset_url(@asset), :html => { :multipart => true } do |form|
|
||||
|
||||
= render 'form', :f => form
|
||||
|
||||
= render 'admin/shared/form_actions', :back_url => admin_theme_assets_url, :button_label => :update
|
27
app/views/admin/theme_assets/index.html.haml
Normal file
@ -0,0 +1,27 @@
|
||||
- title t('.title')
|
||||
|
||||
- content_for :submenu do
|
||||
= render 'admin/shared/menu/settings'
|
||||
|
||||
- content_for :buttons do
|
||||
= admin_button_tag :new, new_admin_theme_asset_url, :class => 'add'
|
||||
|
||||
%p= t('.help')
|
||||
|
||||
%h3= t('.css_and_js')
|
||||
- if @non_image_assets.empty?
|
||||
%p.no-items= t('.no_items', :url => new_admin_theme_asset_url)
|
||||
- else
|
||||
%ul.assets
|
||||
= render :partial => 'asset', :collection => @non_image_assets
|
||||
%li.clear
|
||||
|
||||
%br
|
||||
|
||||
%h3= t('.images')
|
||||
- if @image_assets.empty?
|
||||
%p.no-items= t('.no_items', :url => new_admin_theme_asset_url)
|
||||
- else
|
||||
%ul.assets
|
||||
= render :partial => 'asset', :collection => @image_assets
|
||||
%li.clear
|
12
app/views/admin/theme_assets/new.html.haml
Normal file
@ -0,0 +1,12 @@
|
||||
- title t('.title')
|
||||
|
||||
- content_for :submenu do
|
||||
= render 'admin/shared/menu/settings'
|
||||
|
||||
%p= t('.help')
|
||||
|
||||
= semantic_form_for @asset, :url => admin_theme_assets_url, :html => { :multipart => true } do |form|
|
||||
|
||||
= render 'form', :f => form
|
||||
|
||||
= render 'admin/shared/form_actions', :back_url => admin_theme_assets_url, :button_label => :create
|
@ -27,3 +27,9 @@ Locomotive::Application.configure do
|
||||
:domain => "example.com"
|
||||
}
|
||||
end
|
||||
|
||||
CarrierWave.configure do |config|
|
||||
config.storage = :file
|
||||
config.root = File.join(Rails.root, 'public')
|
||||
end
|
||||
|
||||
|
@ -27,3 +27,7 @@ Locomotive::Application.configure do
|
||||
# like if you have constraints or database-specific column types
|
||||
# config.active_record.schema_format = :sql
|
||||
end
|
||||
|
||||
CarrierWave.configure do |config|
|
||||
config.storage = :file
|
||||
end
|
48
config/initializers/carrierwave.rb
Normal file
@ -0,0 +1,48 @@
|
||||
require 'carrierwave/orm/mongoid'
|
||||
|
||||
module CarrierWave
|
||||
|
||||
class SanitizedFile
|
||||
|
||||
def original_filename=(filename)
|
||||
@original_filename = filename
|
||||
end
|
||||
|
||||
def content_type=(content_type)
|
||||
@content_type = content_type
|
||||
end
|
||||
|
||||
# http://github.com/jnicklas/carrierwave/issuesearch?state=closed&q=content+type#issue/48
|
||||
def copy_to_with_content_type(new_path, permissions=nil)
|
||||
new_file = self.copy_to_without_content_type(new_path, permissions)
|
||||
new_file.content_type = self.content_type
|
||||
new_file
|
||||
end
|
||||
|
||||
alias_method_chain :copy_to, :content_type
|
||||
|
||||
# FIXME (Did) CarrierWave speaks mime type now
|
||||
def content_type
|
||||
return @content_type if @content_type
|
||||
if @file.respond_to?(:content_type) and @file.content_type
|
||||
@file.content_type.chomp
|
||||
else
|
||||
File.mime_type?(@file) if @file.is_a?(String)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
module CarrierWave
|
||||
module Mongoid
|
||||
def validates_integrity_of(*attrs)
|
||||
options = attrs.last.is_a?(Hash) ? attrs.last : {}
|
||||
options[:message] ||= I18n.t('carrierwave.errors.integrity', :default => 'is not an allowed type of file.')
|
||||
validates_each(*attrs) do |record, attr, value|
|
||||
record.errors.add attr, options[:message] if record.send("#{attr}_integrity_error")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -23,6 +23,7 @@ en:
|
||||
snippets: Snippets
|
||||
account: My account
|
||||
site: Site
|
||||
theme_assets: Theme files
|
||||
footer:
|
||||
developed_by: Developed by
|
||||
powered_by: and Powered by
|
||||
@ -97,6 +98,20 @@ en:
|
||||
en: English
|
||||
fr: French
|
||||
|
||||
theme_assets:
|
||||
index:
|
||||
title: Listing theme files
|
||||
new: new file
|
||||
css_and_js: Style and javascript
|
||||
images: Images
|
||||
no_items: "There are no files for now. Just click <a href=\"{{url}}\">here</a> to create the first one."
|
||||
new:
|
||||
title: New file
|
||||
edit:
|
||||
title: "Editing {{file}}"
|
||||
form:
|
||||
choose_file: Choose file
|
||||
choose_plain_text: Choose plain text
|
||||
|
||||
formtastic:
|
||||
titles:
|
||||
@ -109,6 +124,14 @@ en:
|
||||
access_points: Access points
|
||||
memberships: Accounts
|
||||
membership_email: Account email
|
||||
file: File
|
||||
preview: Preview
|
||||
labels:
|
||||
theme_asset:
|
||||
new:
|
||||
source: File
|
||||
edit:
|
||||
source: Replace file
|
||||
hints:
|
||||
page:
|
||||
keywords: "Meta keywords used within the head tag of the page. They are separeted by an empty space. Required for SEO."
|
||||
@ -117,4 +140,8 @@ en:
|
||||
slug: "You need to know it in order to insert the snippet inside a page or a layout"
|
||||
site:
|
||||
domain_name: "ex: locomotiveapp.org"
|
||||
theme_asset:
|
||||
slug: "You do not need to add the extension file (.css or .js)"
|
||||
edit:
|
||||
source: "You can replace it by a file of the same extension"
|
||||
|
||||
|
4
config/locales/carrierwave_en.yml
Normal file
@ -0,0 +1,4 @@
|
||||
en:
|
||||
carrierwave:
|
||||
errors:
|
||||
integrity: 'is not an allowed type of file.'
|
4
config/locales/carrierwave_fr.yml
Normal file
@ -0,0 +1,4 @@
|
||||
fr:
|
||||
carrierwave:
|
||||
errors:
|
||||
integrity: "n'est pas un type de fichier autorisé"
|
@ -6,6 +6,7 @@ en:
|
||||
missing_content_for_layout: "should contain 'content_for_layout' liquid tag"
|
||||
needs_admin_account: "One admin account is required at least"
|
||||
protected_page: "You can not remove index or 404 pages"
|
||||
extname_changed: "New file does not have the original extension"
|
||||
|
||||
attributes:
|
||||
defaults:
|
||||
|
@ -35,9 +35,12 @@ Locomotive::Application.routes.draw do |map|
|
||||
|
||||
resource :my_account
|
||||
|
||||
resources :memberships
|
||||
resources :memberships
|
||||
|
||||
resources :theme_assets
|
||||
end
|
||||
|
||||
# magic url
|
||||
match '/' => 'pages#show'
|
||||
match '*path' => 'pages#show'
|
||||
end
|
||||
|
9
doc/TODO
@ -34,6 +34,15 @@ x create 404 + index pages once a site is created
|
||||
x can not delete index + 404 pages
|
||||
x validates_uniqueness_of :slug, :scope => :id
|
||||
x domain scoping when authenticating
|
||||
- theme assets
|
||||
x create / update
|
||||
x slug
|
||||
x filename from slug
|
||||
x can not replace a javascript by a stylesheet
|
||||
- disable version if not image
|
||||
- asset collections
|
||||
- assets
|
||||
- custom resizing
|
||||
|
||||
|
||||
BACKLOG:
|
||||
|
@ -5,7 +5,7 @@ class String
|
||||
# end
|
||||
|
||||
def slugify(options = {})
|
||||
options = { :sep => '_', :without_extension => false, :downcase => false }.merge(options)
|
||||
options = { :sep => '_', :without_extension => false, :downcase => false, :underscore => false }.merge(options)
|
||||
# replace accented chars with ther ascii equivalents
|
||||
s = ActiveSupport::Inflector.transliterate(self).to_s
|
||||
# No more than one slash in a row
|
||||
@ -20,6 +20,8 @@ class String
|
||||
s.downcase! if options[:downcase]
|
||||
# Turn unwanted chars into the seperator
|
||||
s.gsub!(/[^a-zA-Z0-9\-_\+\/]+/i, options[:sep])
|
||||
# Underscore
|
||||
s.gsub!(/[\-]/i, '') if options[:underscore]
|
||||
s
|
||||
end
|
||||
|
||||
|
BIN
public/images/admin/icons/filetype/medium/AC3.png
Executable file
After Width: | Height: | Size: 6.7 KiB |
BIN
public/images/admin/icons/filetype/medium/ACE.png
Executable file
After Width: | Height: | Size: 8.1 KiB |
BIN
public/images/admin/icons/filetype/medium/ADE.png
Executable file
After Width: | Height: | Size: 8.0 KiB |
BIN
public/images/admin/icons/filetype/medium/ADP.png
Executable file
After Width: | Height: | Size: 8.9 KiB |
BIN
public/images/admin/icons/filetype/medium/AI.png
Executable file
After Width: | Height: | Size: 7.8 KiB |
BIN
public/images/admin/icons/filetype/medium/AIFF.png
Executable file
After Width: | Height: | Size: 9.6 KiB |
BIN
public/images/admin/icons/filetype/medium/AU.png
Executable file
After Width: | Height: | Size: 9.6 KiB |
BIN
public/images/admin/icons/filetype/medium/AVI.png
Executable file
After Width: | Height: | Size: 8.9 KiB |
BIN
public/images/admin/icons/filetype/medium/BAT.png
Executable file
After Width: | Height: | Size: 8.4 KiB |
BIN
public/images/admin/icons/filetype/medium/BIN.png
Executable file
After Width: | Height: | Size: 10 KiB |
BIN
public/images/admin/icons/filetype/medium/BMP.png
Executable file
After Width: | Height: | Size: 11 KiB |
BIN
public/images/admin/icons/filetype/medium/BUP.png
Executable file
After Width: | Height: | Size: 8.0 KiB |
BIN
public/images/admin/icons/filetype/medium/CAB.png
Executable file
After Width: | Height: | Size: 7.7 KiB |
BIN
public/images/admin/icons/filetype/medium/CAT.png
Executable file
After Width: | Height: | Size: 9.3 KiB |
BIN
public/images/admin/icons/filetype/medium/CHM.png
Executable file
After Width: | Height: | Size: 8.9 KiB |
BIN
public/images/admin/icons/filetype/medium/CSS.png
Executable file
After Width: | Height: | Size: 7.7 KiB |
BIN
public/images/admin/icons/filetype/medium/CUE.png
Executable file
After Width: | Height: | Size: 7.2 KiB |
BIN
public/images/admin/icons/filetype/medium/DAT.png
Executable file
After Width: | Height: | Size: 8.4 KiB |
BIN
public/images/admin/icons/filetype/medium/DCR.png
Executable file
After Width: | Height: | Size: 6.6 KiB |
BIN
public/images/admin/icons/filetype/medium/DER.png
Executable file
After Width: | Height: | Size: 7.1 KiB |
BIN
public/images/admin/icons/filetype/medium/DIC.png
Executable file
After Width: | Height: | Size: 13 KiB |
BIN
public/images/admin/icons/filetype/medium/DIVX.png
Executable file
After Width: | Height: | Size: 11 KiB |
BIN
public/images/admin/icons/filetype/medium/DIZ.png
Executable file
After Width: | Height: | Size: 8.2 KiB |
BIN
public/images/admin/icons/filetype/medium/DLL.png
Executable file
After Width: | Height: | Size: 7.4 KiB |
BIN
public/images/admin/icons/filetype/medium/DOC.png
Executable file
After Width: | Height: | Size: 8.3 KiB |
BIN
public/images/admin/icons/filetype/medium/DOCX.png
Executable file
After Width: | Height: | Size: 11 KiB |
BIN
public/images/admin/icons/filetype/medium/DOS.png
Executable file
After Width: | Height: | Size: 8.7 KiB |
BIN
public/images/admin/icons/filetype/medium/DVD.png
Executable file
After Width: | Height: | Size: 9.3 KiB |
BIN
public/images/admin/icons/filetype/medium/DWG.png
Executable file
After Width: | Height: | Size: 9.8 KiB |
BIN
public/images/admin/icons/filetype/medium/DWT.png
Executable file
After Width: | Height: | Size: 9.9 KiB |
BIN
public/images/admin/icons/filetype/medium/EMF.png
Executable file
After Width: | Height: | Size: 9.4 KiB |
BIN
public/images/admin/icons/filetype/medium/EXC.png
Executable file
After Width: | Height: | Size: 7.9 KiB |
BIN
public/images/admin/icons/filetype/medium/FON.png
Executable file
After Width: | Height: | Size: 7.5 KiB |
BIN
public/images/admin/icons/filetype/medium/GIF.png
Executable file
After Width: | Height: | Size: 8.5 KiB |
BIN
public/images/admin/icons/filetype/medium/HLP.png
Executable file
After Width: | Height: | Size: 8.1 KiB |
BIN
public/images/admin/icons/filetype/medium/HTML.png
Executable file
After Width: | Height: | Size: 10 KiB |
BIN
public/images/admin/icons/filetype/medium/IFO.png
Executable file
After Width: | Height: | Size: 8.3 KiB |
BIN
public/images/admin/icons/filetype/medium/INF.png
Executable file
After Width: | Height: | Size: 8.3 KiB |
BIN
public/images/admin/icons/filetype/medium/INI.png
Executable file
After Width: | Height: | Size: 8.1 KiB |
BIN
public/images/admin/icons/filetype/medium/INS.png
Executable file
After Width: | Height: | Size: 10 KiB |
BIN
public/images/admin/icons/filetype/medium/IP.png
Executable file
After Width: | Height: | Size: 9.3 KiB |
BIN
public/images/admin/icons/filetype/medium/ISO.png
Executable file
After Width: | Height: | Size: 8.8 KiB |
BIN
public/images/admin/icons/filetype/medium/ISP.png
Executable file
After Width: | Height: | Size: 10 KiB |
BIN
public/images/admin/icons/filetype/medium/JAVA.png
Executable file
After Width: | Height: | Size: 8.2 KiB |
BIN
public/images/admin/icons/filetype/medium/JFIF.png
Executable file
After Width: | Height: | Size: 9.3 KiB |
BIN
public/images/admin/icons/filetype/medium/JPEG.png
Executable file
After Width: | Height: | Size: 9.8 KiB |
BIN
public/images/admin/icons/filetype/medium/JPG.png
Executable file
After Width: | Height: | Size: 11 KiB |
BIN
public/images/admin/icons/filetype/medium/LOG.png
Executable file
After Width: | Height: | Size: 7.9 KiB |
BIN
public/images/admin/icons/filetype/medium/M4A.png
Executable file
After Width: | Height: | Size: 8.8 KiB |
BIN
public/images/admin/icons/filetype/medium/MID.png
Executable file
After Width: | Height: | Size: 8.4 KiB |
BIN
public/images/admin/icons/filetype/medium/MMF.png
Executable file
After Width: | Height: | Size: 7.1 KiB |
BIN
public/images/admin/icons/filetype/medium/MMM.png
Executable file
After Width: | Height: | Size: 11 KiB |
BIN
public/images/admin/icons/filetype/medium/MOV.png
Executable file
After Width: | Height: | Size: 9.7 KiB |
BIN
public/images/admin/icons/filetype/medium/MOVIE.png
Executable file
After Width: | Height: | Size: 11 KiB |
BIN
public/images/admin/icons/filetype/medium/MP2.png
Executable file
After Width: | Height: | Size: 8.5 KiB |
BIN
public/images/admin/icons/filetype/medium/MP2V.png
Executable file
After Width: | Height: | Size: 11 KiB |
BIN
public/images/admin/icons/filetype/medium/MP3.png
Executable file
After Width: | Height: | Size: 7.6 KiB |
BIN
public/images/admin/icons/filetype/medium/MP4.png
Executable file
After Width: | Height: | Size: 12 KiB |
BIN
public/images/admin/icons/filetype/medium/MPE.png
Executable file
After Width: | Height: | Size: 9.6 KiB |
BIN
public/images/admin/icons/filetype/medium/MPEG.png
Executable file
After Width: | Height: | Size: 12 KiB |
BIN
public/images/admin/icons/filetype/medium/MPG.png
Executable file
After Width: | Height: | Size: 11 KiB |
BIN
public/images/admin/icons/filetype/medium/MPV2.png
Executable file
After Width: | Height: | Size: 11 KiB |
BIN
public/images/admin/icons/filetype/medium/NFO.png
Executable file
After Width: | Height: | Size: 8.1 KiB |
BIN
public/images/admin/icons/filetype/medium/PDD.png
Executable file
After Width: | Height: | Size: 7.3 KiB |
BIN
public/images/admin/icons/filetype/medium/PDF.png
Executable file
After Width: | Height: | Size: 7.3 KiB |
BIN
public/images/admin/icons/filetype/medium/PHP.png
Executable file
After Width: | Height: | Size: 7.8 KiB |
BIN
public/images/admin/icons/filetype/medium/PNG.png
Executable file
After Width: | Height: | Size: 11 KiB |
BIN
public/images/admin/icons/filetype/medium/PPT.png
Executable file
After Width: | Height: | Size: 7.5 KiB |
BIN
public/images/admin/icons/filetype/medium/PPTX.png
Executable file
After Width: | Height: | Size: 9.7 KiB |
BIN
public/images/admin/icons/filetype/medium/PSD.png
Executable file
After Width: | Height: | Size: 7.4 KiB |
BIN
public/images/admin/icons/filetype/medium/RAR.png
Executable file
After Width: | Height: | Size: 9.5 KiB |
BIN
public/images/admin/icons/filetype/medium/REG.png
Executable file
After Width: | Height: | Size: 9.1 KiB |
BIN
public/images/admin/icons/filetype/medium/RTF.png
Executable file
After Width: | Height: | Size: 6.8 KiB |
BIN
public/images/admin/icons/filetype/medium/SCP.png
Executable file
After Width: | Height: | Size: 7.9 KiB |