cambium 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/cambium.gemspec +25 -23
- data/lib/cambium/version.rb +1 -1
- data/lib/generators/cambium/helpers/_autoloader.rb +12 -0
- data/lib/generators/cambium/helpers/dependencies_helper.rb +58 -0
- data/lib/generators/cambium/helpers/generators_helper.rb +227 -0
- data/lib/generators/cambium/install/admin_generator.rb +68 -74
- data/lib/generators/cambium/install/app_generator.rb +86 -95
- data/lib/generators/cambium/install/config_generator.rb +98 -108
- data/lib/generators/cambium/install/utilities_generator.rb +2 -50
- data/lib/generators/cambium/model/image_generator.rb +67 -0
- data/lib/generators/cambium/model/page_generator.rb +131 -0
- data/lib/generators/cambium/model/post_generator.rb +71 -0
- data/lib/generators/cambium/model/tag_generator.rb +40 -0
- data/lib/generators/cambium/model/user_generator.rb +78 -0
- data/lib/generators/cambium/templates/Gemfile +43 -0
- data/lib/generators/cambium/templates/_partials/pages/admin_icon.rb +6 -0
- data/lib/generators/cambium/templates/app/assets/javascripts/admin/admin.js.coffee +3 -1
- data/lib/generators/cambium/templates/app/assets/javascripts/admin/models/image.js.coffee +14 -0
- data/lib/generators/cambium/templates/app/assets/javascripts/admin/models/tag.js.coffee +14 -0
- data/lib/generators/cambium/templates/app/assets/javascripts/admin/parser_rules/custom.js +552 -0
- data/lib/generators/cambium/templates/app/assets/javascripts/admin/routers/router.js.coffee +21 -0
- data/lib/generators/cambium/templates/app/assets/javascripts/admin/tag.jst.ejs +7 -0
- data/lib/generators/cambium/templates/app/assets/javascripts/admin/templates/image.jst.ejs +3 -0
- data/lib/generators/cambium/templates/app/assets/javascripts/admin/templates/post_tag.jst.ejs +1 -0
- data/lib/generators/cambium/templates/app/assets/javascripts/admin/views/image_upload.js.coffee +28 -0
- data/lib/generators/cambium/templates/app/assets/javascripts/admin/views/tags.js.coffee +158 -0
- data/lib/generators/cambium/templates/app/assets/javascripts/admin/views/wysiwyg.js.coffee +77 -0
- data/lib/generators/cambium/templates/app/controllers/admin/images_controller.rb +45 -0
- data/lib/generators/cambium/templates/app/controllers/admin/pages_controller.rb +42 -0
- data/lib/generators/cambium/templates/app/controllers/admin/posts_controller.rb +39 -0
- data/lib/generators/cambium/templates/app/controllers/admin/taggings_controller.rb +69 -0
- data/lib/generators/cambium/templates/app/controllers/admin/tags_controller.rb +11 -0
- data/lib/generators/cambium/templates/app/controllers/admin_controller.rb +11 -2
- data/lib/generators/cambium/templates/app/controllers/application_controller.rb +2 -2
- data/lib/generators/cambium/templates/app/controllers/images_controller.rb +45 -0
- data/lib/generators/cambium/templates/app/controllers/pages_controller.rb +12 -0
- data/lib/generators/cambium/templates/app/controllers/posts_controller.rb +11 -0
- data/lib/generators/cambium/templates/app/helpers/admin/pages_controller.rb +47 -0
- data/lib/generators/cambium/templates/app/helpers/admin_helper.rb +1 -1
- data/lib/generators/cambium/templates/app/models/concerns/image_cropper.rb +24 -0
- data/lib/generators/cambium/templates/app/models/concerns/publishable.rb +32 -4
- data/lib/generators/cambium/templates/app/models/concerns/slug.rb +4 -0
- data/lib/generators/cambium/templates/app/models/concerns/tags.rb +6 -1
- data/lib/generators/cambium/templates/app/models/image.rb +43 -0
- data/lib/generators/cambium/templates/app/models/page.rb +81 -0
- data/lib/generators/cambium/templates/app/models/post.rb +45 -0
- data/lib/generators/cambium/templates/app/models/tag.rb +33 -0
- data/lib/generators/cambium/templates/app/models/tagging.rb +20 -0
- data/lib/generators/cambium/templates/app/uploaders/image_uploader.rb +91 -0
- data/lib/generators/cambium/templates/app/views/admin/images/_image.html.erb +1 -0
- data/lib/generators/cambium/templates/app/views/admin/images/create.js.erb +7 -0
- data/lib/generators/cambium/templates/app/views/admin/images/index.json.jbuilder +4 -0
- data/lib/generators/cambium/templates/app/views/admin/pages/_form.html.erb +26 -0
- data/lib/generators/cambium/templates/app/views/admin/posts/_form.html.erb +40 -0
- data/lib/generators/cambium/templates/app/views/admin/shared/_insert_image.html.erb +12 -0
- data/lib/generators/cambium/templates/app/views/admin/shared/forms/_editor.html.erb +3 -3
- data/lib/generators/cambium/templates/app/views/admin/shared/forms/_form_page.html.erb +5 -1
- data/lib/generators/cambium/templates/app/views/home/index.html.erb +7 -0
- data/lib/generators/cambium/templates/app/views/page_templates/default.html.erb +2 -0
- data/lib/generators/cambium/templates/app/views/posts/_post.html.erb +4 -0
- data/lib/generators/cambium/templates/app/views/posts/index.html.erb +1 -0
- data/lib/generators/cambium/templates/app/views/posts/show.html.erb +10 -0
- data/lib/generators/cambium/templates/config/app_routes.rb +77 -0
- data/lib/generators/cambium/templates/config/routes.rb.erb +11 -2
- data/lib/generators/cambium/templates/db/migrate/create_pages.rb.erb +24 -0
- data/lib/generators/cambium/templates/db/migrate/create_posts.rb +19 -0
- data/lib/generators/cambium/templates/gitignore +1 -0
- metadata +52 -256
- data/lib/generators/cambium/install/users_generator.rb +0 -104
- data/lib/generators/cambium/templates/app/assets/stylesheets/admin/partials/_icons.scss +0 -5194
@@ -17,6 +17,10 @@ module Publishable
|
|
17
17
|
(active_at IS ? AND inactive_at IS ?)",
|
18
18
|
Time.now, Time.now, nil, nil) }
|
19
19
|
|
20
|
+
# --------------------------------- Callbacks
|
21
|
+
|
22
|
+
before_save :convert_dates
|
23
|
+
|
20
24
|
end
|
21
25
|
|
22
26
|
# --------------------------------- Instance Methods
|
@@ -28,13 +32,16 @@ module Publishable
|
|
28
32
|
end
|
29
33
|
|
30
34
|
def formatted_active_date
|
31
|
-
|
32
|
-
active_at.strftime("%d %B, %Y")
|
35
|
+
formatted_date(active_at)
|
33
36
|
end
|
34
37
|
|
35
38
|
def formatted_inactive_date
|
36
|
-
|
37
|
-
|
39
|
+
formatted_date(inactive_at)
|
40
|
+
end
|
41
|
+
|
42
|
+
def formatted_date(date)
|
43
|
+
return '' if date.nil?
|
44
|
+
date.strftime("%d %B, %Y")
|
38
45
|
end
|
39
46
|
|
40
47
|
def formatted_active_time
|
@@ -47,4 +54,25 @@ module Publishable
|
|
47
54
|
inactive_at.strftime("%l:%M %p")
|
48
55
|
end
|
49
56
|
|
57
|
+
def convert_dates
|
58
|
+
self.active_time = Time.now.strftime("%l:%M %p") if self.active_time.blank?
|
59
|
+
self.inactive_time = '12:00 AM' if self.inactive_time.blank?
|
60
|
+
if self.active_date.blank?
|
61
|
+
self.active_at = nil
|
62
|
+
else
|
63
|
+
self.active_at = DateTime.strptime("#{self.active_date}
|
64
|
+
#{self.active_time}", "%d %B, %Y %l:%M %p")
|
65
|
+
end
|
66
|
+
if self.inactive_date.blank?
|
67
|
+
self.inactive_at = nil
|
68
|
+
else
|
69
|
+
self.inactive_at = DateTime.strptime("#{self.inactive_date}
|
70
|
+
#{self.inactive_time}", "%d %B, %Y %l:%M %p")
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def publish!
|
75
|
+
update_column :active_at, Time.now
|
76
|
+
end
|
77
|
+
|
50
78
|
end
|
@@ -18,7 +18,12 @@ module Tags
|
|
18
18
|
name.strip!
|
19
19
|
if !used_tags.include?(name) && name.present?
|
20
20
|
used_tags << name
|
21
|
-
tag = Tag.
|
21
|
+
tag = Tag.where(:ci_name => name.downcase).first
|
22
|
+
if tag.nil?
|
23
|
+
tag = Tag.create(:name => name)
|
24
|
+
else
|
25
|
+
tag.update(:name => name) unless name == tag.name
|
26
|
+
end
|
22
27
|
self.tags << tag
|
23
28
|
end
|
24
29
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
class Image < ActiveRecord::Base
|
2
|
+
|
3
|
+
# ------------------------------------------ Plugins
|
4
|
+
|
5
|
+
# As you might suspect, this concern (app/models/concerns/image_cropper.rb)
|
6
|
+
# add all the methods we need to control cropping our images manually. If you
|
7
|
+
# aren't going to use that feature, just get rid of this line.
|
8
|
+
#
|
9
|
+
include ImageCropper
|
10
|
+
|
11
|
+
# ------------------------------------------ Uploaders
|
12
|
+
|
13
|
+
# This is a carrierwave method that uses our ImageUploader
|
14
|
+
# (app/uploaders/image_uploader.rb) to manage the uploading process and
|
15
|
+
# creating versions
|
16
|
+
#
|
17
|
+
mount_uploader :filename, ImageUploader
|
18
|
+
|
19
|
+
# ------------------------------------------ Validations
|
20
|
+
|
21
|
+
# Require a file to actually be present when we try to create a new record
|
22
|
+
#
|
23
|
+
validates :filename, :presence => true
|
24
|
+
|
25
|
+
# ------------------------------------------ Scopes
|
26
|
+
|
27
|
+
# We don't like to use default scopes. But many times we'll reference a
|
28
|
+
# listing of the images by the date they were creating.
|
29
|
+
#
|
30
|
+
scope :recent, -> { order('created_at DESC') }
|
31
|
+
|
32
|
+
# ------------------------------------------ Instance Methods
|
33
|
+
|
34
|
+
# This helps up with jQuery uploading (doing it on the fly vs. reloading a
|
35
|
+
# page).
|
36
|
+
#
|
37
|
+
def to_jq_upload
|
38
|
+
{
|
39
|
+
"name" => read_attribute(:filename)
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
class Page < ActiveRecord::Base
|
4
|
+
|
5
|
+
# --------------------------------- plugins
|
6
|
+
|
7
|
+
include Publishable, Slug
|
8
|
+
# multisearchable :against => [:title, :body, :description], :using => :tsearch
|
9
|
+
has_ancestry
|
10
|
+
|
11
|
+
# --------------------------------- Associations
|
12
|
+
|
13
|
+
# belongs_to :user, :as => :author
|
14
|
+
|
15
|
+
# --------------------------------- Callbacks
|
16
|
+
|
17
|
+
# --------------------------------- Validations
|
18
|
+
|
19
|
+
validates :title, :presence => true
|
20
|
+
|
21
|
+
# --------------------------------- Scopes
|
22
|
+
|
23
|
+
default_scope { order('ancestry DESC, position ASC') }
|
24
|
+
scope :for_nav, -> { where(:in_nav => true) }
|
25
|
+
|
26
|
+
# --------------------------------- instance methods
|
27
|
+
|
28
|
+
def parent_options
|
29
|
+
if id.present?
|
30
|
+
Page.unscoped.where('id != ?', id).order(:title)
|
31
|
+
else
|
32
|
+
Page.all.unscoped.order(:title)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_s
|
37
|
+
title
|
38
|
+
end
|
39
|
+
|
40
|
+
def ancestral_title
|
41
|
+
ancestors.collect(&:title).push(title).join(' : ')
|
42
|
+
end
|
43
|
+
|
44
|
+
def template_name
|
45
|
+
template.humanize
|
46
|
+
end
|
47
|
+
|
48
|
+
def template_value(field_name)
|
49
|
+
if template_data.present? && template_data.has_key?(field_name.to_s)
|
50
|
+
template_data[field_name.to_s]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def template_fields
|
55
|
+
template_file = "#{Rails.application.config.template_directory}/#{self.template}.yml"
|
56
|
+
if File.exists?(template_file)
|
57
|
+
template_yaml = YAML.load_file(template_file)
|
58
|
+
template_yaml['fields']
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def has_nav_children?
|
63
|
+
children.for_nav.published.count > 0
|
64
|
+
end
|
65
|
+
|
66
|
+
# --------------------------------- class methods
|
67
|
+
|
68
|
+
def self.options_for_select
|
69
|
+
Page.unscoped.published.order(:title).collect do |p|
|
70
|
+
[p.title, "/#{p.slug}"]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.template_options
|
75
|
+
templates = []
|
76
|
+
Dir["#{Rails.application.config.template_directory}/*.erb"].collect{|f| f.split('/').pop.split('.').shift}.each do |t|
|
77
|
+
templates << [t.titleize, t]
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class Post < ActiveRecord::Base
|
2
|
+
|
3
|
+
# --------------------------------- plugins
|
4
|
+
|
5
|
+
include Publishable, Slug, Tags
|
6
|
+
# include PgSearch
|
7
|
+
# multisearchable :against => [:title, :body], :using => :tsearch
|
8
|
+
mount_uploader :main_image, ImageUploader
|
9
|
+
paginates_per 10
|
10
|
+
|
11
|
+
# --------------------------------- associations
|
12
|
+
|
13
|
+
belongs_to :user
|
14
|
+
|
15
|
+
# --------------------------------- validations
|
16
|
+
|
17
|
+
validates :title, :presence => true
|
18
|
+
|
19
|
+
# --------------------------------- scopes
|
20
|
+
|
21
|
+
default_scope { order(:active_at => :desc) }
|
22
|
+
scope :featured, -> { where(:is_featured => true) }
|
23
|
+
scope :during, ->(year, month) { where(
|
24
|
+
:active_at => "#{year}-#{month}-1".to_date..."#{year}-#{month}-1".to_date+1.month
|
25
|
+
) }
|
26
|
+
|
27
|
+
# --------------------------------- instance methods
|
28
|
+
|
29
|
+
def to_s
|
30
|
+
self.title
|
31
|
+
end
|
32
|
+
|
33
|
+
def author
|
34
|
+
self.user
|
35
|
+
end
|
36
|
+
|
37
|
+
def author_name
|
38
|
+
author.full_name if author.present?
|
39
|
+
end
|
40
|
+
|
41
|
+
def summary_text
|
42
|
+
"#{title} - #{active_at}, #{author.name}"
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# == Schema Information
|
2
|
+
#
|
3
|
+
# Table name: tags
|
4
|
+
#
|
5
|
+
# id :integer not null, primary key
|
6
|
+
# name :string(255)
|
7
|
+
# ci_name :string(255)
|
8
|
+
# slug :string(255)
|
9
|
+
# created_at :datetime
|
10
|
+
# updated_at :datetime
|
11
|
+
#
|
12
|
+
|
13
|
+
class Tag < ActiveRecord::Base
|
14
|
+
|
15
|
+
# ------------------------------------------ Plugins
|
16
|
+
|
17
|
+
include Slug, Title
|
18
|
+
|
19
|
+
# ------------------------------------------ Associations
|
20
|
+
|
21
|
+
has_many :tag_assignments
|
22
|
+
|
23
|
+
# ------------------------------------------ Callbacks
|
24
|
+
|
25
|
+
before_save :downcase_name
|
26
|
+
|
27
|
+
# ------------------------------------------ Instance Methods
|
28
|
+
|
29
|
+
def downcase_name
|
30
|
+
self.ci_name = self.name.downcase
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# == Schema Information
|
2
|
+
#
|
3
|
+
# Table name: taggings
|
4
|
+
#
|
5
|
+
# id :integer not null, primary key
|
6
|
+
# tag_id :integer
|
7
|
+
# taggable_id :integer
|
8
|
+
# taggable_type :string(255)
|
9
|
+
# created_at :datetime
|
10
|
+
# updated_at :datetime
|
11
|
+
#
|
12
|
+
|
13
|
+
class Tagging < ActiveRecord::Base
|
14
|
+
|
15
|
+
# ------------------------------------------ Associations
|
16
|
+
|
17
|
+
belongs_to :tag
|
18
|
+
belongs_to :taggable, :polymorphic => true
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
class ImageUploader < CarrierWave::Uploader::Base
|
4
|
+
|
5
|
+
include CarrierWave::RMagick
|
6
|
+
include CarrierWave::MimeTypes
|
7
|
+
|
8
|
+
# This is our standard storage method, which stores the files to the file
|
9
|
+
# system. In some cases, you might need to upload to a remote server. In that
|
10
|
+
# case, we recommend using CarrierWave Direct:
|
11
|
+
#
|
12
|
+
# https://github.com/dwilkie/carrierwave_direct
|
13
|
+
#
|
14
|
+
storage :file
|
15
|
+
|
16
|
+
# This is the path at which your images will be stored. This is different than
|
17
|
+
# the default, but keeps the path to images nice and clean. Feel free to
|
18
|
+
# change to your liking.
|
19
|
+
#
|
20
|
+
def store_dir
|
21
|
+
"media/images/#{model.id}"
|
22
|
+
end
|
23
|
+
|
24
|
+
# These are the "versions" created when a new image is uploaded. You can
|
25
|
+
# change these to meet your preferences, noting the comments below.
|
26
|
+
#
|
27
|
+
# For example, if the version is "thumb," you'll be able to get the image by
|
28
|
+
# calling something like this:
|
29
|
+
#
|
30
|
+
# image = Image.find(1)
|
31
|
+
# image.filename.thumb.url OR image.filename.url(:thumb)
|
32
|
+
#
|
33
|
+
version :thumb do
|
34
|
+
#
|
35
|
+
# resize_to_fill will automatically crop the image (to the middle),
|
36
|
+
# resulting in an image of the dimensions you pass.
|
37
|
+
#
|
38
|
+
process :resize_to_fill => [150,150]
|
39
|
+
end
|
40
|
+
|
41
|
+
version :tile do
|
42
|
+
#
|
43
|
+
# If you want to override the manual crop (with the cropping tool), you need
|
44
|
+
# to call this method (process :crop) before you process the resizing.
|
45
|
+
#
|
46
|
+
process :crop
|
47
|
+
process :resize_to_fill => [240,180]
|
48
|
+
end
|
49
|
+
|
50
|
+
# This is the version we use for cropping. You need to ensure:
|
51
|
+
#
|
52
|
+
# 1. the process method is passing ":resize_to_limit" and NOT
|
53
|
+
# ":resize_to_fill"
|
54
|
+
#
|
55
|
+
# 2. the dimensions are taller and wider than your version that calls
|
56
|
+
# "process :crop"
|
57
|
+
#
|
58
|
+
version :to_crop do
|
59
|
+
process :resize_to_limit => [500,500]
|
60
|
+
end
|
61
|
+
|
62
|
+
# If you wish to limit the file extensions, edit this list as necessary
|
63
|
+
#
|
64
|
+
# If, instead, you don't care about the file extension (although you should,
|
65
|
+
# since the is an "image" uploader), you can delete this method.
|
66
|
+
#
|
67
|
+
def extension_white_list
|
68
|
+
%w(jpg jpeg gif png)
|
69
|
+
end
|
70
|
+
|
71
|
+
# This method is physically preparing the method for manual cropping.
|
72
|
+
#
|
73
|
+
# MAKE SURE your "resize_to_limit" call here passes the dimensions IDENTICAL
|
74
|
+
# TO YOUR :crop VERSION
|
75
|
+
#
|
76
|
+
# Other than that, you can leave this method alone.
|
77
|
+
#
|
78
|
+
def crop
|
79
|
+
if model.crop_x.present?
|
80
|
+
resize_to_limit(500,500)
|
81
|
+
manipulate! do |img|
|
82
|
+
x = model.crop_x.to_i
|
83
|
+
y = model.crop_y.to_i
|
84
|
+
w = model.crop_w.to_i
|
85
|
+
h = model.crop_h.to_i
|
86
|
+
img.crop!(x, y, w, h)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= image_tag image.filename.url(:thumb), class: "project-preview", data: { id: image.id } %>
|
@@ -0,0 +1,7 @@
|
|
1
|
+
<% if @image.new_record? %>
|
2
|
+
alert("Failed to upload image: <%= j @image.errors.full_messages.join(', ').html_safe %>");
|
3
|
+
<% elsif @project %>
|
4
|
+
$(".images-container").prepend("<div class=\"image\"><a href='<%= edit_admin_project_image_path(@project,@image) %>' class='edit'><i class=\"icon-pencil\"></i></a><a href='#' class='delete' data-id=\"<%= @image.id %>\"><i class=\"icon-remove2\"></i></a><img src=\"<%= @image.filename.thumb.url %>\" class=\"project-preview\" data-id=\"<%= @image.id %>\"></div>");
|
5
|
+
<% elsif @page or @post %>
|
6
|
+
$(".images-container").prepend("<div class=\"image\"><img src=\"<%= @image.filename.thumb.url %>\" data-src=\"<%= @image.filename.url %>\" class=\"\" data-id=\"<%= @image.id %>\"></div>");
|
7
|
+
<% end -%>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<%= render :partial => 'admin/shared/insert_image' %>
|
2
|
+
<%= simple_form_for @item, :url => @url do |f| %>
|
3
|
+
|
4
|
+
<%= form_column 'overview' do %>
|
5
|
+
<%= f.input :title %>
|
6
|
+
<%= f.input :description %>
|
7
|
+
<%= f.input :slug, :label => 'URL' %>
|
8
|
+
<%= f.input :parent_id,
|
9
|
+
:label => 'Parent Page',
|
10
|
+
:collection => @item.parent_options %>
|
11
|
+
<%= f.input :template, :collection => Page.template_options %>
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
<%= form_column 'publish', 'right' do %>
|
15
|
+
<%= publishable_fields(f) %>
|
16
|
+
<%= f.input :position, :label => 'Sort order', :collection => (1..@item.siblings.count) %>
|
17
|
+
<%= f.input :in_nav, :label => 'display in menu' %>
|
18
|
+
<% end %>
|
19
|
+
|
20
|
+
<%= form_section 'body' do %>
|
21
|
+
<%= wysiwyg(f) %>
|
22
|
+
<% end %>
|
23
|
+
|
24
|
+
<%= f.button :submit %>
|
25
|
+
|
26
|
+
<% end %>
|
@@ -0,0 +1,40 @@
|
|
1
|
+
<%= render :partial => 'admin/shared/insert_image' %>
|
2
|
+
<%= simple_form_for @item, :url => @url do |f| %>
|
3
|
+
|
4
|
+
<%= form_column 'overview' do %>
|
5
|
+
<%= f.input :title %>
|
6
|
+
<%= f.input :slug, :label => 'URL' %>
|
7
|
+
<div class="fields">
|
8
|
+
<div id="tag-container">
|
9
|
+
<input type="text" placeholder="add tags" id="new-tag-title" class="new-tag-title">
|
10
|
+
<div class="tagging-errors"></div>
|
11
|
+
<ul class="autocomplete"></ul>
|
12
|
+
<p class="loading">Loading...</p>
|
13
|
+
<ul id="tag-list"></ul>
|
14
|
+
</div>
|
15
|
+
</div>
|
16
|
+
<div class="image-uploader">
|
17
|
+
<%= f.input :main_image %>
|
18
|
+
<% if @item.main_image.to_s.present? %>
|
19
|
+
<%= content_tag :div, :class => 'control-group' do %>
|
20
|
+
<%= image_tag(@item.main_image.thumb.url) %>
|
21
|
+
<br>
|
22
|
+
<%= f.check_box :remove_main_image %> Remove image
|
23
|
+
<% end %>
|
24
|
+
<% end %>
|
25
|
+
</div>
|
26
|
+
|
27
|
+
<% end %>
|
28
|
+
|
29
|
+
<%= form_column 'publish', 'right' do %>
|
30
|
+
<%= publishable_fields(f) %>
|
31
|
+
<%= f.input(:is_featured) %>
|
32
|
+
<% end %>
|
33
|
+
|
34
|
+
<%= form_section 'body' do %>
|
35
|
+
<%= wysiwyg(f) %>
|
36
|
+
<% end %>
|
37
|
+
|
38
|
+
<%= f.button :submit %>
|
39
|
+
|
40
|
+
<% end %>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<div id="wysihtml5-insert-image-modal">
|
2
|
+
<div class="modal">
|
3
|
+
<a href="#" class="close">X</a>
|
4
|
+
<h1>Insert Image</h1>
|
5
|
+
<hr>
|
6
|
+
<%= form_for @image, url: @image_url do |f| %>
|
7
|
+
<%= f.file_field :filename, multiple: true %>
|
8
|
+
<% end %>
|
9
|
+
<hr>
|
10
|
+
<div class="images-container">Images Loading...</div>
|
11
|
+
</div>
|
12
|
+
</div>
|
@@ -28,19 +28,19 @@
|
|
28
28
|
|
29
29
|
<div class="group">
|
30
30
|
<%= wysihtml5_icon 'createLink', 'link' %>
|
31
|
-
|
31
|
+
<%= wysihtml5_icon 'insertImage', 'image', { :id => 'wysihtml5-insert-image' } %>
|
32
32
|
|
33
33
|
<div class="dialog" data-wysihtml5-dialog="createLink" style="display: none;">
|
34
34
|
<input type="text" data-wysihtml5-dialog-field="href" value="http://" class="text">
|
35
35
|
<a class="margin-right-medium" data-wysihtml5-dialog-action="save">Insert</a>
|
36
36
|
<a data-wysihtml5-dialog-action="cancel">Cancel</a>
|
37
37
|
</div>
|
38
|
-
|
38
|
+
<div class="dialog" data-wysihtml5-dialog="insertImage" style="display: none; margin-left: 36px;">
|
39
39
|
<input type="text" data-wysihtml5-dialog-field="src" value="http://" class="insert-image">
|
40
40
|
<a class="insert-image" class="margin-right-medium" data-wysihtml5-dialog-action="save">Insert</a>
|
41
41
|
<a class="browse-images">Browse Images</a>
|
42
42
|
<a data-wysihtml5-dialog-action="cancel">Cancel</a>
|
43
|
-
</div>
|
43
|
+
</div>
|
44
44
|
</div>
|
45
45
|
|
46
46
|
<div class="group right">
|
@@ -12,7 +12,11 @@
|
|
12
12
|
|
13
13
|
<section class="form-container">
|
14
14
|
<%= render :partial => 'admin/shared/status' %>
|
15
|
-
|
15
|
+
<% if action_name == 'edit' || action_name == 'edit' %>
|
16
|
+
<%= render :partial => 'edit_form' %>
|
17
|
+
<% else %>
|
18
|
+
<%= render :partial => 'form' %>
|
19
|
+
<% end %>
|
16
20
|
</section>
|
17
21
|
|
18
22
|
</div>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render @posts %>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<section class="post-detail" id="post-detail=<%= @post.id %>">
|
2
|
+
<header>
|
3
|
+
<%= image_tag(@post.main_image.to_crop.url) if @post.main_image.to_s %>
|
4
|
+
</header>
|
5
|
+
<article>
|
6
|
+
<h1><%= @post.title %></h1>
|
7
|
+
<%= content_tag :h2, "by #{@post.author_name}" if @post.author_name %>
|
8
|
+
<%= @post.body.html_safe %>
|
9
|
+
</article>
|
10
|
+
</section>
|
@@ -0,0 +1,77 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
######################################################################
|
4
|
+
# BEGIN Cambium
|
5
|
+
######################################################################
|
6
|
+
#
|
7
|
+
# The following are Cambium's default routes. Feel free to customize (or
|
8
|
+
# delete) these to fit your needs.
|
9
|
+
#
|
10
|
+
######################################################################
|
11
|
+
# WARNING: MAKE SURE YOU REMOVE ANY DUPLICATES AND REARRANGE TO AVOID
|
12
|
+
# CONFLICTS WITH YOUR EXISTING ROUTES.
|
13
|
+
######################################################################
|
14
|
+
#
|
15
|
+
# ------------------------------------------ Devise
|
16
|
+
#
|
17
|
+
# Only use this section if you've installed Cambium's user authentication
|
18
|
+
# system (which uses Devise).
|
19
|
+
#
|
20
|
+
# The following line is necessary to add Devise's routes. The :skip argument
|
21
|
+
# is ommitting registration routes, since we don't use the registration module
|
22
|
+
# by default. And we only skip sessions because we rewrite those routes below
|
23
|
+
# so they are a little cleaner.
|
24
|
+
#
|
25
|
+
# devise_for :users, :skip => [:sessions, :registrations]
|
26
|
+
# devise_scope :user do
|
27
|
+
# get '/login' => 'devise/sessions#new', :as => :new_user_session
|
28
|
+
# post '/login' => 'devise/sessions#create', :as => :user_session
|
29
|
+
# get '/logout' => 'devise/sessions#destroy', :as => :destroy_user_session
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# ------------------------------------------ Admin
|
33
|
+
#
|
34
|
+
# Only use this section if you plan to implement Cambium's admin module. Do
|
35
|
+
# note, if you accidentally delete it before you run the admin generator, they
|
36
|
+
# will be regenerated.
|
37
|
+
#
|
38
|
+
# This routes to our admin dashboard, which we don't use by default. It really
|
39
|
+
# just redirects to the controller of your choosing.
|
40
|
+
#
|
41
|
+
# get '/admin' => 'admin#dashboard', :as => :admin_dashboard
|
42
|
+
#
|
43
|
+
# All additional admin routes should be nested under the :admin namespace.
|
44
|
+
# Here we show an example that includes the users routes.
|
45
|
+
#
|
46
|
+
# namespace :admin do
|
47
|
+
# resources :users, :except => [:show]
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
# ------------------------------------------ JSON
|
51
|
+
#
|
52
|
+
# If you plan to use any public json routes, it's good to nest them in their
|
53
|
+
# own scope. We use a scope instead of a namespace because a controller action
|
54
|
+
# can have routes to it in different formats, so namespacing is unecessary.
|
55
|
+
#
|
56
|
+
# scope 'json' do
|
57
|
+
# 'users' => 'users#index'
|
58
|
+
# end
|
59
|
+
#
|
60
|
+
# ------------------------------------------ Public
|
61
|
+
#
|
62
|
+
# After we define all namespaced routes, we can move on to those routes that
|
63
|
+
# are not namespaced.
|
64
|
+
#
|
65
|
+
# resources :users
|
66
|
+
#
|
67
|
+
# ------------------------------------------ Home Page
|
68
|
+
#
|
69
|
+
# We end the routes file with the root route, which defines our application's
|
70
|
+
# home page. This is essential and should only be defined once -- after all
|
71
|
+
# other routes.
|
72
|
+
#
|
73
|
+
# root :to => 'home#index'
|
74
|
+
#
|
75
|
+
######################################################################
|
76
|
+
# END Cambium
|
77
|
+
######################################################################
|