blog-gem 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +98 -0
- data/Rakefile +37 -0
- data/app/assets/config/blog_gem_manifest.js +2 -0
- data/app/assets/javascripts/blog.js +15 -0
- data/app/assets/stylesheets/blog.sass +199 -0
- data/app/controllers/blog/gem/application_controller.rb +15 -0
- data/app/controllers/blog/gem/authors_controller.rb +93 -0
- data/app/controllers/blog/gem/blog_controller.rb +60 -0
- data/app/controllers/blog/gem/posts_controller.rb +63 -0
- data/app/helpers/blog/gem/application_helper.rb +13 -0
- data/app/models/blog/gem/application_record.rb +7 -0
- data/app/models/blog/gem/author.rb +34 -0
- data/app/models/blog/gem/post.rb +48 -0
- data/app/views/blog/_blog_archive.slim +7 -0
- data/app/views/blog/_posts_box.slim +15 -0
- data/app/views/blog/gem/authors/_avatar.slim +21 -0
- data/app/views/blog/gem/authors/_contact.slim +15 -0
- data/app/views/blog/gem/authors/_form.slim +17 -0
- data/app/views/blog/gem/authors/_user.slim +9 -0
- data/app/views/blog/gem/authors/edit.html.slim +5 -0
- data/app/views/blog/gem/authors/index.html.slim +37 -0
- data/app/views/blog/gem/authors/login.slim +8 -0
- data/app/views/blog/gem/authors/new.html.slim +7 -0
- data/app/views/blog/gem/blog/_author.slim +12 -0
- data/app/views/blog/gem/blog/_item.slim +15 -0
- data/app/views/blog/gem/blog/_sidebar.slim +54 -0
- data/app/views/blog/gem/blog/index.atom.builder +16 -0
- data/app/views/blog/gem/blog/index.slim +50 -0
- data/app/views/blog/gem/blog/show.slim +54 -0
- data/app/views/blog/gem/posts/_form.html.slim +15 -0
- data/app/views/blog/gem/posts/edit.html.slim +4 -0
- data/app/views/blog/gem/posts/new.html.slim +6 -0
- data/config/locales/de.yml +75 -0
- data/config/routes.rb +16 -0
- data/db/migrate/20160315062930_create_posts_and_authors.rb +50 -0
- data/lib/blog/gem/engine.rb +7 -0
- data/lib/blog/gem/version.rb +5 -0
- data/lib/blog/gem.rb +44 -0
- data/lib/tasks/blog/gem_tasks.rake +4 -0
- metadata +255 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
class Blog::Gem::Post < Blog::Gem::ApplicationRecord
|
|
2
|
+
include ::PgSearch
|
|
3
|
+
|
|
4
|
+
belongs_to :author
|
|
5
|
+
|
|
6
|
+
acts_as_taggable
|
|
7
|
+
|
|
8
|
+
has_attached_file :thumbnail, styles: { medium: "750x300#"}, path: ":rails_root/public#{Blog::Gem.image_path}/posts/:id/:style.:extension", url: "#{Blog::Gem.image_path}/posts/:id/:style.:extension"
|
|
9
|
+
validates_attachment_content_type :thumbnail, content_type: /\Aimage\/.*\Z/
|
|
10
|
+
|
|
11
|
+
acts_as_url :title
|
|
12
|
+
|
|
13
|
+
before_save{self.url = self.title.to_url}
|
|
14
|
+
|
|
15
|
+
pg_search_scope :search, :against => [:title, :body, :teaser]
|
|
16
|
+
|
|
17
|
+
scope :find_by_category, -> (name) { where(category_id: Blog::Gem.categories[name]) }
|
|
18
|
+
scope :by_datetime, -> (dt) { where("published_at >= ? and published_at <= ?", dt.beginning_of_month, dt.end_of_month) }
|
|
19
|
+
scope :published, -> { where("published_at <= ?", Time.now).order('published_at desc') }
|
|
20
|
+
scope :unpublished, -> { where("published_at > ?", Time.now).order('published_at desc') }
|
|
21
|
+
|
|
22
|
+
def author_name
|
|
23
|
+
if author.present?
|
|
24
|
+
author.name
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def to_path
|
|
29
|
+
"#{Blog::Gem.path}/#{url}"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def to_url
|
|
33
|
+
"#{Blog::Gem.url}#{to_path}"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def tags
|
|
37
|
+
tag_list.join(", ")
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def category
|
|
41
|
+
if category_id.present?
|
|
42
|
+
category = Blog::Gem.categories.index(category_id)
|
|
43
|
+
{name: category.humanize, link: "#{Blog::Gem.path}/category/#{category}"}
|
|
44
|
+
else
|
|
45
|
+
{name: "<i>#{I18n.t("blog.no_category")}</i>", link: Blog::Gem.path}
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
.widget
|
|
2
|
+
ul.archive.arrow
|
|
3
|
+
- @posts_month = @posts_month||Blog::Gem::Post.published.group_by{|post| post.published_at.beginning_of_month}
|
|
4
|
+
- @posts_month.first(Blog::Gem.archive_count).each do |date, c|
|
|
5
|
+
li = link_to "#{I18n.l(date, format: :month)} #{date.year}", "/blog/archive/#{date.month}-#{date.year}"
|
|
6
|
+
- if @posts_month.count > Blog::Gem.archive_count
|
|
7
|
+
li = link_to t("bog.archive.more"), blogs_path
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
.gap
|
|
2
|
+
.row
|
|
3
|
+
- Blog::Gem::Post.published.first(Blog::Gem.home_posts_count).each do |post|
|
|
4
|
+
.col-sm-3
|
|
5
|
+
.row.box.well
|
|
6
|
+
p
|
|
7
|
+
= link_to image_tag(post.thumbnail.url(:medium), class: "img-responsive"), post.to_path
|
|
8
|
+
h5 = link_to post.title, post.to_path
|
|
9
|
+
p.teaser = raw post.teaser.split(" ").first(30).join(" ")
|
|
10
|
+
= link_to "#{t("blog.read_more")} #{icon("angle-right")}".html_safe, post.to_path, class: "btn btn-primary pull-right"
|
|
11
|
+
- if Blog::Gem::Post.published.count > Blog::Gem.home_posts_count
|
|
12
|
+
.row
|
|
13
|
+
.col-lg-12
|
|
14
|
+
.text-center
|
|
15
|
+
= link_to "#{t("blog.all_posts")} #{icon("angle-right")}".html_safe, "post.to_path", class: "btn btn-primary btn-lg"
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
= f.input :avatar_or_gravatar, collection: [["Gravatar", "gravatar"], ["Avatar", "avatar"]]
|
|
2
|
+
|
|
3
|
+
.row
|
|
4
|
+
.col-sm-6
|
|
5
|
+
h3 Avatar Upload
|
|
6
|
+
= f.input :avatar
|
|
7
|
+
- if @author.avatar.present?
|
|
8
|
+
= image_tag @author.avatar.url, width: "200"
|
|
9
|
+
.col-sm-6
|
|
10
|
+
h3 Gravatar
|
|
11
|
+
.row.form-group
|
|
12
|
+
.col-sm-3
|
|
13
|
+
= f.label :gravatar, "Gravatar E-mail"
|
|
14
|
+
.col-sm-9
|
|
15
|
+
strong
|
|
16
|
+
= @author.private_email
|
|
17
|
+
.row.form-group
|
|
18
|
+
.col-sm-3
|
|
19
|
+
= f.label :gravatar_url, "Gravatar Vorschau"
|
|
20
|
+
.col-sm-9
|
|
21
|
+
= image_tag @author.gravatar_url, width: "200"
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
.row
|
|
2
|
+
.col-sm-6
|
|
3
|
+
= f.input :shubbl_id
|
|
4
|
+
= f.input :facebook
|
|
5
|
+
= f.input :twitter
|
|
6
|
+
= f.input :xing
|
|
7
|
+
= f.input :instagram
|
|
8
|
+
= f.input :phone
|
|
9
|
+
.col-sm-6
|
|
10
|
+
= f.input :homepage
|
|
11
|
+
= f.input :github
|
|
12
|
+
= f.input :google_plus
|
|
13
|
+
= f.input :linkedin
|
|
14
|
+
= f.input :youtube
|
|
15
|
+
= f.input :mobile
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
= simple_form_for @author do |f|
|
|
2
|
+
ul.nav.nav-tabs
|
|
3
|
+
li.active
|
|
4
|
+
a data-toggle="tab" href="#user" User Settings
|
|
5
|
+
li
|
|
6
|
+
a data-toggle="tab" href="#contact" Contact
|
|
7
|
+
li
|
|
8
|
+
a data-toggle="tab" href="#image" Avatar
|
|
9
|
+
.tab-content
|
|
10
|
+
br
|
|
11
|
+
#user.tab-pane.fade.active.in
|
|
12
|
+
= render "user", f: f
|
|
13
|
+
#contact.tab-pane.fade
|
|
14
|
+
= render "contact", f: f
|
|
15
|
+
#image.tab-pane.fade
|
|
16
|
+
= render "avatar", f: f
|
|
17
|
+
= f.submit class: "btn btn-primary btn-lg pull-right"
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
= f.input :name
|
|
2
|
+
.row
|
|
3
|
+
.col-sm-6
|
|
4
|
+
= f.input :private_email, hint: "Use for #{link_to " Gravatar ", "https://gravatar.com/", target: "_blank"}".html_safe
|
|
5
|
+
= f.input :public_email, hint: "Show on Page and use for authentication"
|
|
6
|
+
.col-sm-6
|
|
7
|
+
= f.input :password
|
|
8
|
+
= f.input :password_confirmation
|
|
9
|
+
= f.input :description, input_html: {rows: 5}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
section#author-index.container
|
|
2
|
+
.page-header
|
|
3
|
+
= link_to new_author_path, class: 'btn btn-primary pull-right' do
|
|
4
|
+
span.glyphicon.glyphicon-plus
|
|
5
|
+
| New Author
|
|
6
|
+
h1
|
|
7
|
+
| Listing Authors
|
|
8
|
+
|
|
9
|
+
.table-responsive
|
|
10
|
+
table.table.table-striped.table-bordered.table-hover
|
|
11
|
+
thead
|
|
12
|
+
tr
|
|
13
|
+
th
|
|
14
|
+
#
|
|
15
|
+
th
|
|
16
|
+
| Name
|
|
17
|
+
th
|
|
18
|
+
| Private email
|
|
19
|
+
th
|
|
20
|
+
| Public email
|
|
21
|
+
th
|
|
22
|
+
th
|
|
23
|
+
tbody
|
|
24
|
+
- @authors.each do | author |
|
|
25
|
+
tr
|
|
26
|
+
td
|
|
27
|
+
= author.id
|
|
28
|
+
td
|
|
29
|
+
= author.name
|
|
30
|
+
td
|
|
31
|
+
= author.private_email
|
|
32
|
+
td
|
|
33
|
+
= author.public_email
|
|
34
|
+
td
|
|
35
|
+
= link_to 'Edit', edit_author_path(author)
|
|
36
|
+
td
|
|
37
|
+
= link_to 'Destroy', author, method: :delete, data: { confirm: 'Are you sure?' }
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
.container
|
|
2
|
+
= form_tag "/blog/login", class: "form-signin" do
|
|
3
|
+
h2.form-signin-heading Author Login
|
|
4
|
+
label.sr-only for="inputEmail" Email address
|
|
5
|
+
input#inputEmail.form-control autofocus="" placeholder=("Email address") required="" type="email" name="email"
|
|
6
|
+
label.sr-only for="inputPassword" Password
|
|
7
|
+
input#inputPassword.form-control placeholder="Password" required="" type="password" name="password"
|
|
8
|
+
button.btn.btn-lg.btn-primary.btn-block type="submit" Sign in
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
.user-info.media.box
|
|
2
|
+
.pull-left = link_to image_tag(author.image, class: "img-thumbnail", width: 180), author.to_path
|
|
3
|
+
.media-body
|
|
4
|
+
h4.author-img = link_to author.name, author.to_path
|
|
5
|
+
p = raw author.description
|
|
6
|
+
.author-meta
|
|
7
|
+
- [:homepage, :facebook, :twitter, :xing, :instagram, :github, :google_plus, :linkedin, :youtube, :phone, :mobile].each do |x|
|
|
8
|
+
- name = author.send(x)
|
|
9
|
+
- if name.present?
|
|
10
|
+
= link_to (t("social.#{x}.url")+name), target: "_blank", title: t("social.#{x}.name"), class: "btn btn-social btn-#{x}"
|
|
11
|
+
= icon("#{t("social.#{x}.icon")} fa-fw")
|
|
12
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
h2 = link_to post.title, post.to_path
|
|
2
|
+
- if post.published_at > Time.now
|
|
3
|
+
.alert
|
|
4
|
+
h4 Warning!
|
|
5
|
+
h5 = "This post will published at #{l(post.published_at)}"
|
|
6
|
+
.blog-meta.clearfix
|
|
7
|
+
p.pull-left
|
|
8
|
+
- if post.show_author
|
|
9
|
+
span.blog-meta-margin
|
|
10
|
+
= raw "#{icon('user')} #{t("blog.by")} #{link_to post.author.name, post.author.to_path} "
|
|
11
|
+
span.blog-meta-margin
|
|
12
|
+
= raw "#{icon('folder')} #{t("blog.category_label")}: #{link_to post.category[:name].html_safe, post.category[:link]} "
|
|
13
|
+
span.blog-meta-margin
|
|
14
|
+
= raw "#{icon('calendar')} #{l(post.published_at)}"
|
|
15
|
+
= link_to image_tag(post.thumbnail.url(:medium), class: "img-responsive img-thumbnail thumbnail"), post.to_path
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
- @all_posts = @all_posts||Blog::Gem::Post.published
|
|
2
|
+
aside.col-sm-4.well
|
|
3
|
+
.widget.search
|
|
4
|
+
form action=blogs_path
|
|
5
|
+
.input-group.btn-lg-group
|
|
6
|
+
input.form-control.input-block-level placeholder=t("blog.search.placeholder") value=params[:q] name="q" type="text"
|
|
7
|
+
button.btn.btn-large.btn-primary type="submit" = t("blog.search.button")
|
|
8
|
+
.widget.widget-popular
|
|
9
|
+
h3 = t("blog.last_posts")
|
|
10
|
+
.widget-blog-items
|
|
11
|
+
- @all_posts.first(Blog::Gem.widget_posts_count).each do |post|
|
|
12
|
+
.widget-blog-item.media
|
|
13
|
+
.pull-left
|
|
14
|
+
= link_to post.to_path, title: l(post.published_at)
|
|
15
|
+
.date
|
|
16
|
+
span.month = l(post.published_at, format: :month)
|
|
17
|
+
span.day = post.published_at.day
|
|
18
|
+
.media-body
|
|
19
|
+
= link_to post.to_path
|
|
20
|
+
h5 = post.title
|
|
21
|
+
- if @all_posts.count > Blog::Gem.widget_posts_count
|
|
22
|
+
.pull-right
|
|
23
|
+
= link_to t("blog.all_posts"), blogs_path
|
|
24
|
+
.widget
|
|
25
|
+
h3 = t("blog.categories")
|
|
26
|
+
div
|
|
27
|
+
.row
|
|
28
|
+
.col-sm-6
|
|
29
|
+
ul.arrow
|
|
30
|
+
- Blog::Gem.categories.each_with_index.select{|x, i| i.even? }.each do |category, i|
|
|
31
|
+
li = link_to category.first.to_s.humanize, blog_category_path(category.first.to_s)
|
|
32
|
+
.col-sm-6
|
|
33
|
+
ul.arrow
|
|
34
|
+
- Blog::Gem.categories.each_with_index.select{|x, i| !i.even? }.each do |category, i|
|
|
35
|
+
li = link_to category.first.to_s.humanize, blog_category_path(category.first.to_s)
|
|
36
|
+
.widget
|
|
37
|
+
h3 = t("blog.tags")
|
|
38
|
+
- @blog_tags = @blog_tags||Blog::Gem::Post.tag_counts_on(:tags)
|
|
39
|
+
.blog-gem-taglist-first
|
|
40
|
+
- @blog_tags.first(Blog::Gem.tags_count).each do |tag|
|
|
41
|
+
a.btn.btn-xs.btn-primary href=blog_tag_path(tag.to_s.downcase) = tag.to_s.humanize
|
|
42
|
+
- if @blog_tags.count > Blog::Gem.tags_count
|
|
43
|
+
.blog-gem-taglist-all.hidden
|
|
44
|
+
- @blog_tags.each do |tag|
|
|
45
|
+
a.btn.btn-xs.btn-primary href=blog_tag_path(tag.to_s.downcase) = tag.to_s.humanize
|
|
46
|
+
= button_tag t("blog.archives.show_tags"), class: "btn btn-xs btn-link pull-right", id: "blog-archive-trigger", data: {hidden: t("blog.archives.hidden_tags"), show: t("blog.archives.show_tags"), current: "hidden"}
|
|
47
|
+
.widget
|
|
48
|
+
h3 = t("blog.archive")
|
|
49
|
+
ul.arrow
|
|
50
|
+
- @posts_month = @posts_month||@all_posts.group_by{|post| post.published_at.beginning_of_month}
|
|
51
|
+
- @posts_month.first(Blog::Gem.archive_count).each do |date, c|
|
|
52
|
+
li = link_to "#{I18n.l(date, format: :month)} #{date.year}", "#{Blog::Gem.path}/archive/#{date.month}-#{date.year}"
|
|
53
|
+
- if @posts_month.count > Blog::Gem.archive_count
|
|
54
|
+
li = link_to t("bottom.archive.more"), blogs_path
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
atom_feed(language: 'de', url: root_url) do |feed|
|
|
2
|
+
feed.title t("blog.index.page_title")
|
|
3
|
+
feed.updated @posts.maximum(:published_at)
|
|
4
|
+
|
|
5
|
+
@posts.each do |post|
|
|
6
|
+
feed.entry post, {published: post.published_at, updated: post.updated_at} do |entry|
|
|
7
|
+
entry.title post.title
|
|
8
|
+
entry.content post.body, type: 'html'
|
|
9
|
+
entry.author do |author|
|
|
10
|
+
author.name post.author.name
|
|
11
|
+
end
|
|
12
|
+
entry.url post_url(post)
|
|
13
|
+
entry.summary post.teaser, type: 'html'
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
.blog-container
|
|
2
|
+
- if Blog::Gem.title_enable
|
|
3
|
+
h1.blog-page-title = link_to @page_title, blogs_path
|
|
4
|
+
.text-muted.blog-page-text = t("blog.index.text")
|
|
5
|
+
- if current_author.present?
|
|
6
|
+
.well-blog
|
|
7
|
+
h3 Author Actions
|
|
8
|
+
.btn-group
|
|
9
|
+
a.btn.btn-primary href="#{Blog::Gem.path}/posts/new" New Blog-Post
|
|
10
|
+
.btn-group
|
|
11
|
+
a.btn.btn-primary href="#{Blog::Gem.path}/authors/me/edit" Edit my Author Profile
|
|
12
|
+
- if current_author.admin?
|
|
13
|
+
.btn-toolbar
|
|
14
|
+
a.btn.btn-primary href="#{Blog::Gem.path}/authors" Authors Index
|
|
15
|
+
br
|
|
16
|
+
br
|
|
17
|
+
h4 Unpublished articles
|
|
18
|
+
table class="table table-bordered"
|
|
19
|
+
tr
|
|
20
|
+
th name
|
|
21
|
+
th published date
|
|
22
|
+
th
|
|
23
|
+
- Blog::Gem::Post.unpublished.each do |post|
|
|
24
|
+
tr
|
|
25
|
+
td
|
|
26
|
+
= link_to post.title, post.to_path
|
|
27
|
+
td
|
|
28
|
+
= l(post.published_at)
|
|
29
|
+
td
|
|
30
|
+
= link_to 'edit', edit_post_path(post), class: "btn btn-primary btn-block"
|
|
31
|
+
.row
|
|
32
|
+
.col-sm-8
|
|
33
|
+
.blog
|
|
34
|
+
- if @author.present?
|
|
35
|
+
= render "author", author: @author
|
|
36
|
+
- if @posts.present?
|
|
37
|
+
- @posts.each do |post|
|
|
38
|
+
.blog-item.well-blog
|
|
39
|
+
= render "item", post: post
|
|
40
|
+
p = raw post.teaser
|
|
41
|
+
= link_to "#{t("blog.read_more")} #{icon("angle-right")}".html_safe, post.to_path, class: "btn btn-link"
|
|
42
|
+
.gap
|
|
43
|
+
= will_paginate @posts
|
|
44
|
+
- else
|
|
45
|
+
h2 = t("blog.not_found.heading")
|
|
46
|
+
h5 = t("blog.not_found.lead")
|
|
47
|
+
- if false
|
|
48
|
+
.center
|
|
49
|
+
= link_to t("blog.your_story.button"), your_story_path, class: "btn btn-primary"
|
|
50
|
+
= render "sidebar"
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
- content_for :meta do
|
|
2
|
+
meta name="news_keywords" content=@post.tag_list.map{|x| x.humanize}.join(", ")
|
|
3
|
+
meta property="og:type" content="article"
|
|
4
|
+
.blog-container
|
|
5
|
+
- if Blog::Gem.title_enable
|
|
6
|
+
h1.blog-page-title = link_to t("blog.index.page_title"), blogs_path
|
|
7
|
+
.text-muted.blog-page-text = t("blog.index.text")
|
|
8
|
+
|
|
9
|
+
- if current_author.present? && (current_author == @post.author || current_author.admin? )
|
|
10
|
+
.well-blog
|
|
11
|
+
h3 Author Actions
|
|
12
|
+
.btn-group
|
|
13
|
+
= link_to 'Edit this Blog-Post', edit_post_path(@post), class: "btn btn-primary"
|
|
14
|
+
.btn-group
|
|
15
|
+
= link_to 'Destroy this Blog-Post', @post, method: :delete, data: { confirm: 'Are you sure?' }, class: "btn btn-primary"
|
|
16
|
+
br
|
|
17
|
+
button.btn.btn-social.btn-facebook data-target="#fb-modal" data-toggle="modal" type="button"
|
|
18
|
+
| Text 4 Facebook
|
|
19
|
+
#fb-modal.modal.fade role="dialog" tabindex="-1"
|
|
20
|
+
.modal-dialog role="document"
|
|
21
|
+
.modal-content
|
|
22
|
+
.modal-header
|
|
23
|
+
button.close aria-label="Close" data-dismiss="modal" type="button"
|
|
24
|
+
span aria-hidden="true" ×
|
|
25
|
+
h4#myModalLabel.modal-title Text 4 Facebook
|
|
26
|
+
.modal-body
|
|
27
|
+
= @post.title
|
|
28
|
+
br
|
|
29
|
+
br
|
|
30
|
+
= "► #{@post.to_url}"
|
|
31
|
+
br
|
|
32
|
+
br
|
|
33
|
+
= raw facebook_html(@post.body)
|
|
34
|
+
br
|
|
35
|
+
br
|
|
36
|
+
= @post.tag_list.map{|x| "##{x.humanize}"}.join(", ")
|
|
37
|
+
br
|
|
38
|
+
= link_to "original thumbnail", @post.thumbnail.url(:original), target: "_blank"
|
|
39
|
+
.row
|
|
40
|
+
.col-sm-8
|
|
41
|
+
.blog
|
|
42
|
+
.blog-item.well-blog
|
|
43
|
+
= render "item", post: @post
|
|
44
|
+
.blog-content
|
|
45
|
+
= raw @post.body
|
|
46
|
+
.well-blog.row style="margin-left: 0px; margin-top: 25px"
|
|
47
|
+
h4 = t("blog.keywords")
|
|
48
|
+
.tag-cloud.unstyled
|
|
49
|
+
- @post.tag_list.each do |tag|
|
|
50
|
+
= link_to tag.humanize, blog_tag_path(tag.downcase), class: "btn btn-xs btn-primary"
|
|
51
|
+
- if @post.show_author
|
|
52
|
+
p
|
|
53
|
+
= render "author", author: @post.author
|
|
54
|
+
= render "sidebar"
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
= simple_form_for @post do |f|
|
|
2
|
+
= f.input :title
|
|
3
|
+
= f.input :body, input_html: {rows: 20}
|
|
4
|
+
= f.input :teaser, input_html: {rows: 5}
|
|
5
|
+
= f.input :tag_list, input_html: {value: @post.tag_list.join(", ")}
|
|
6
|
+
= f.input :published_at
|
|
7
|
+
= f.input :category_id, collection: Blog::Gem.categories.each_with_index.map{ |c, i| [c.humanize, i] }
|
|
8
|
+
= f.input :show_author
|
|
9
|
+
= f.input :thumbnail
|
|
10
|
+
- if @post.thumbnail.present?
|
|
11
|
+
= image_tag @post.thumbnail.url, width: "200"
|
|
12
|
+
- if current_author.admin?
|
|
13
|
+
= f.input :author_id, collection: Blog::Gem::Author.all.map{ |a| [a.name, a.id] }
|
|
14
|
+
= f.input :path
|
|
15
|
+
= f.submit class: "btn btn-primary btn-lg btn-block pull-right", style: "width: 400px"
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
de:
|
|
2
|
+
blog:
|
|
3
|
+
archives:
|
|
4
|
+
show_tags: "Mehr Schlagwörter anzeigen"
|
|
5
|
+
hidden_tags: "Weniger Schlagwörter anzeigen"
|
|
6
|
+
more: "Mehr Anzeigen"
|
|
7
|
+
not_found:
|
|
8
|
+
heading: "Es wurden leider keine Artikel gefunden."
|
|
9
|
+
lead: "Wir haben hier leider noch keine Blog Artikel."
|
|
10
|
+
all_posts: "Weitere Blog Artikel anzeigen"
|
|
11
|
+
category_label: "Kategorie"
|
|
12
|
+
search_by: "gesuchte nach:"
|
|
13
|
+
tagged_with: "mit dem Schlagwort:"
|
|
14
|
+
categoryed_with: "aus der Kategorie:"
|
|
15
|
+
by_author: "geschrieben von:"
|
|
16
|
+
from_month: "aus dem: "
|
|
17
|
+
by: "von"
|
|
18
|
+
search:
|
|
19
|
+
placeholder: "Artikel Suche"
|
|
20
|
+
button: "Los"
|
|
21
|
+
archive: "Archiv"
|
|
22
|
+
tags: "Schlagwörter"
|
|
23
|
+
last_posts: "Letzten Artikel"
|
|
24
|
+
read_more: "Weiter lesen"
|
|
25
|
+
categories: "Kategorien"
|
|
26
|
+
no_category: "Keine Kategorie"
|
|
27
|
+
keywords: "Schlagwörter: "
|
|
28
|
+
index:
|
|
29
|
+
page_title: "Blog - aktuelle Themen & Nachrichten"
|
|
30
|
+
text: "Lese alles zu den Themen und Nachrichten die uns bewegen."
|
|
31
|
+
social:
|
|
32
|
+
homepage:
|
|
33
|
+
name: "Homepage"
|
|
34
|
+
icon: "globe"
|
|
35
|
+
url: ""
|
|
36
|
+
facebook:
|
|
37
|
+
name: "Facebook"
|
|
38
|
+
icon: "facebook"
|
|
39
|
+
url: "https://www.facebook.com/"
|
|
40
|
+
twitter:
|
|
41
|
+
name: "Twitter"
|
|
42
|
+
icon: "twitter"
|
|
43
|
+
url: "https://twitter.com/"
|
|
44
|
+
xing:
|
|
45
|
+
name: "Xing"
|
|
46
|
+
icon: "xing"
|
|
47
|
+
url: "https://www.xing.com/profile/"
|
|
48
|
+
instagram:
|
|
49
|
+
name: Instagram
|
|
50
|
+
icon: "instagram"
|
|
51
|
+
url: "https://www.instagram.com/"
|
|
52
|
+
github:
|
|
53
|
+
name: "Github"
|
|
54
|
+
icon: "github"
|
|
55
|
+
url: "https://github.com/"
|
|
56
|
+
google_plus:
|
|
57
|
+
name: "Google+"
|
|
58
|
+
icon: "google-plus"
|
|
59
|
+
url: "https://plus.google.com/u/"
|
|
60
|
+
linkedin:
|
|
61
|
+
name: "LinkedIn"
|
|
62
|
+
icon: "linkedin"
|
|
63
|
+
url: "https://de.linkedin.com/in/"
|
|
64
|
+
youtube:
|
|
65
|
+
name: "YouTube"
|
|
66
|
+
icon: "youtube"
|
|
67
|
+
url: "https://www.youtube.com/"
|
|
68
|
+
phone:
|
|
69
|
+
name: "Telefone"
|
|
70
|
+
icon: "phone"
|
|
71
|
+
url: "tel:"
|
|
72
|
+
mobile:
|
|
73
|
+
name: "Mobil"
|
|
74
|
+
icon: "mobile"
|
|
75
|
+
url: "tel:"
|
data/config/routes.rb
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
Blog::Gem::Engine.routes.draw do
|
|
2
|
+
|
|
3
|
+
get "/" => "blog#index", as: :blogs
|
|
4
|
+
|
|
5
|
+
get "/tag/:tag" => "blog#index", as: :blog_tag
|
|
6
|
+
get "/category/:category" => "blog#index", as: :blog_category
|
|
7
|
+
get "/archive/:date" => "blog#index", as: :blog_date
|
|
8
|
+
get "/author/:author" => "blog#index", as: :blog_author
|
|
9
|
+
get "/login" => "authors#login"
|
|
10
|
+
post "/login" => "authors#login_submit", as: :author_login_submit
|
|
11
|
+
get "/logout" => "authors#logout", as: :author_logout
|
|
12
|
+
resources :authors, except: :show
|
|
13
|
+
resources :posts, except: [:show, :index]
|
|
14
|
+
|
|
15
|
+
get ":name" => "blog#show", as: :blog
|
|
16
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
class CreatePostsAndAuthors < ActiveRecord::Migration
|
|
2
|
+
def change
|
|
3
|
+
create_table "blog_gem_posts", force: :cascade do |t|
|
|
4
|
+
t.string "title"
|
|
5
|
+
t.text "body"
|
|
6
|
+
t.text "teaser"
|
|
7
|
+
t.datetime "published_at"
|
|
8
|
+
t.integer "author_id"
|
|
9
|
+
t.integer "category_id"
|
|
10
|
+
t.datetime "created_at", null: false
|
|
11
|
+
t.datetime "updated_at", null: false
|
|
12
|
+
t.string "thumbnail_file_name"
|
|
13
|
+
t.string "thumbnail_content_type"
|
|
14
|
+
t.integer "thumbnail_file_size"
|
|
15
|
+
t.datetime "thumbnail_updated_at"
|
|
16
|
+
t.string "url"
|
|
17
|
+
t.boolean "show_author"
|
|
18
|
+
t.string "path"
|
|
19
|
+
end
|
|
20
|
+
create_table "blog_gem_authors", force: :cascade do |t|
|
|
21
|
+
t.string "name"
|
|
22
|
+
t.string "private_email"
|
|
23
|
+
t.string "public_email"
|
|
24
|
+
t.string "password_digest"
|
|
25
|
+
t.text "description"
|
|
26
|
+
t.integer "shubbl_id"
|
|
27
|
+
t.string "facebook"
|
|
28
|
+
t.string "twitter"
|
|
29
|
+
t.string "xing"
|
|
30
|
+
t.string "instagram"
|
|
31
|
+
t.string "homepage"
|
|
32
|
+
t.string "github"
|
|
33
|
+
t.string "google_plus"
|
|
34
|
+
t.string "linkedin"
|
|
35
|
+
t.string "youtube"
|
|
36
|
+
t.string "phone"
|
|
37
|
+
t.string "mobile"
|
|
38
|
+
t.string "avatar_or_gravatar"
|
|
39
|
+
t.boolean "admin"
|
|
40
|
+
t.datetime "created_at", null: false
|
|
41
|
+
t.datetime "updated_at", null: false
|
|
42
|
+
t.string "avatar_file_name"
|
|
43
|
+
t.string "avatar_content_type"
|
|
44
|
+
t.integer "avatar_file_size"
|
|
45
|
+
t.datetime "avatar_updated_at"
|
|
46
|
+
t.string "url"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
end
|
|
50
|
+
end
|
data/lib/blog/gem.rb
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require "pg_search"
|
|
2
|
+
require "paperclip"
|
|
3
|
+
require "sass-rails"
|
|
4
|
+
require "acts-as-taggable-on"
|
|
5
|
+
require "stringex"
|
|
6
|
+
require "gravtastic"
|
|
7
|
+
require "bcrypt"
|
|
8
|
+
require "will_paginate"
|
|
9
|
+
require "simple_form"
|
|
10
|
+
require "nokogiri"
|
|
11
|
+
require "blog/gem/engine"
|
|
12
|
+
|
|
13
|
+
module Blog
|
|
14
|
+
module Gem
|
|
15
|
+
class << self
|
|
16
|
+
mattr_accessor :archive_count
|
|
17
|
+
mattr_accessor :home_posts_count
|
|
18
|
+
mattr_accessor :tags_count
|
|
19
|
+
mattr_accessor :widget_posts_count
|
|
20
|
+
mattr_accessor :categories
|
|
21
|
+
mattr_accessor :path
|
|
22
|
+
mattr_accessor :url
|
|
23
|
+
mattr_accessor :image_path
|
|
24
|
+
mattr_accessor :title_enable
|
|
25
|
+
|
|
26
|
+
self.archive_count = 13
|
|
27
|
+
self.home_posts_count = 6
|
|
28
|
+
self.tags_count = 24
|
|
29
|
+
self.widget_posts_count = 6
|
|
30
|
+
self.categories = {}
|
|
31
|
+
self.path = "/blog"
|
|
32
|
+
self.image_path = "/uploads"
|
|
33
|
+
self.title_enable = true
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def self.setup(&block)
|
|
37
|
+
yield self
|
|
38
|
+
|
|
39
|
+
if Rails.env != "production"
|
|
40
|
+
self.url = "http://localhost:3000"
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|