refactor admin post blog feature without angularjs
This commit is contained in:
parent
368467dfad
commit
3615504b76
|
@ -14,3 +14,4 @@
|
||||||
/public/assets/*
|
/public/assets/*
|
||||||
*.old
|
*.old
|
||||||
*.bak
|
*.bak
|
||||||
|
.byebug_history
|
||||||
|
|
4
Gemfile
4
Gemfile
|
@ -12,6 +12,8 @@ gem 'foundation-rails', '~> 6.2.1'
|
||||||
gem 'foundation-icons-sass-rails'
|
gem 'foundation-icons-sass-rails'
|
||||||
gem 'font-awesome-sass'
|
gem 'font-awesome-sass'
|
||||||
gem 'angularjs-rails'
|
gem 'angularjs-rails'
|
||||||
|
gem 'carrierwave'
|
||||||
|
gem 'kaminari', git: 'git@github.com:amatsuda/kaminari.git'
|
||||||
|
|
||||||
gem 'jbuilder'
|
gem 'jbuilder'
|
||||||
gem 'pg'
|
gem 'pg'
|
||||||
|
@ -48,6 +50,8 @@ group :development do
|
||||||
gem 'spring'
|
gem 'spring'
|
||||||
gem 'spring-watcher-listen', '~> 2.0.0'
|
gem 'spring-watcher-listen', '~> 2.0.0'
|
||||||
|
|
||||||
|
gem 'byebug'
|
||||||
|
|
||||||
gem 'rack-cors', :require => 'rack/cors'
|
gem 'rack-cors', :require => 'rack/cors'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
17
Gemfile.lock
17
Gemfile.lock
|
@ -1,3 +1,11 @@
|
||||||
|
GIT
|
||||||
|
remote: git@github.com:amatsuda/kaminari.git
|
||||||
|
revision: 0e21d52feca1f79a9aca83613cf053eb5273827e
|
||||||
|
specs:
|
||||||
|
kaminari (1.0.0.alpha)
|
||||||
|
actionpack (>= 3.0.0)
|
||||||
|
activesupport (>= 3.0.0)
|
||||||
|
|
||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
|
@ -46,6 +54,7 @@ GEM
|
||||||
babel-source (>= 4.0, < 6)
|
babel-source (>= 4.0, < 6)
|
||||||
execjs (~> 2.0)
|
execjs (~> 2.0)
|
||||||
builder (3.2.2)
|
builder (3.2.2)
|
||||||
|
byebug (8.2.4)
|
||||||
capybara (2.7.0)
|
capybara (2.7.0)
|
||||||
addressable
|
addressable
|
||||||
mime-types (>= 1.16)
|
mime-types (>= 1.16)
|
||||||
|
@ -53,6 +62,11 @@ GEM
|
||||||
rack (>= 1.0.0)
|
rack (>= 1.0.0)
|
||||||
rack-test (>= 0.5.4)
|
rack-test (>= 0.5.4)
|
||||||
xpath (~> 2.0)
|
xpath (~> 2.0)
|
||||||
|
carrierwave (0.11.0)
|
||||||
|
activemodel (>= 3.2.0)
|
||||||
|
activesupport (>= 3.2.0)
|
||||||
|
json (>= 1.7)
|
||||||
|
mime-types (>= 1.16)
|
||||||
chunky_png (1.3.5)
|
chunky_png (1.3.5)
|
||||||
codeclimate-test-reporter (0.5.0)
|
codeclimate-test-reporter (0.5.0)
|
||||||
simplecov (>= 0.7.1, < 1.0.0)
|
simplecov (>= 0.7.1, < 1.0.0)
|
||||||
|
@ -306,7 +320,9 @@ PLATFORMS
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
angularjs-rails
|
angularjs-rails
|
||||||
|
byebug
|
||||||
capybara
|
capybara
|
||||||
|
carrierwave
|
||||||
chunky_png
|
chunky_png
|
||||||
codeclimate-test-reporter
|
codeclimate-test-reporter
|
||||||
coffee-rails (~> 4.1.0)
|
coffee-rails (~> 4.1.0)
|
||||||
|
@ -322,6 +338,7 @@ DEPENDENCIES
|
||||||
html_truncator
|
html_truncator
|
||||||
jbuilder
|
jbuilder
|
||||||
jquery-rails
|
jquery-rails
|
||||||
|
kaminari!
|
||||||
listen (~> 3.0.5)
|
listen (~> 3.0.5)
|
||||||
mina
|
mina
|
||||||
mina-multistage
|
mina-multistage
|
||||||
|
|
|
@ -8,11 +8,31 @@ $(document).ready ->
|
||||||
$('input[type=file]').show().focus().click().hide()
|
$('input[type=file]').show().focus().click().hide()
|
||||||
false
|
false
|
||||||
|
|
||||||
|
$('#tabs').on 'change.zf.tabs', ()->
|
||||||
|
if $('#preview:visible').length > 0
|
||||||
|
$('#preview').text('Loading...')
|
||||||
|
$.ajax
|
||||||
|
url: '/admin/posts/preview'
|
||||||
|
type: 'POST'
|
||||||
|
data:
|
||||||
|
content: $('#content-input').val()
|
||||||
|
success: (data)->
|
||||||
|
$('#preview').html(data)
|
||||||
|
|
||||||
|
$('a.tag').click (event)->
|
||||||
|
event.preventDefault()
|
||||||
|
new_labels = $(this).text()
|
||||||
|
if $('#labels').val() == ''
|
||||||
|
labels = new_labels
|
||||||
|
else
|
||||||
|
labels = $('#labels').val() + ", #{new_labels}"
|
||||||
|
$('#labels').val(labels)
|
||||||
|
|
||||||
opt =
|
opt =
|
||||||
type: 'POST'
|
type: 'POST'
|
||||||
url: "/photos"
|
url: "/photos"
|
||||||
success: (data,status,xhr)->
|
success: (data,status,xhr)->
|
||||||
txtBox = $("#post_content")
|
txtBox = $("#content-input")
|
||||||
caret_pos = txtBox.caret('pos')
|
caret_pos = txtBox.caret('pos')
|
||||||
src_merged = "\n" + data + "\n"
|
src_merged = "\n" + data + "\n"
|
||||||
source = txtBox.val()
|
source = txtBox.val()
|
||||||
|
@ -22,5 +42,4 @@ $(document).ready ->
|
||||||
txtBox.scope().content = txtBox.val()
|
txtBox.scope().content = txtBox.val()
|
||||||
txtBox.focus()
|
txtBox.focus()
|
||||||
|
|
||||||
|
|
||||||
$('input[type=file]').fileUpload opt
|
$('input[type=file]').fileUpload opt
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
@app.controller 'AdminPostsController', [ '$scope', '$http', '$location', '$timeout', '$cookies', '$sce', ($scope, $http, $location, $timeout, $cookies, $sce)->
|
|
||||||
|
|
||||||
$scope.body_active = true
|
|
||||||
|
|
||||||
$scope.init = (id)->
|
|
||||||
url = '/admin/posts/' + id + '.json'
|
|
||||||
$http
|
|
||||||
url: url
|
|
||||||
method: 'GET'
|
|
||||||
.success (res)->
|
|
||||||
$scope.title = res.title
|
|
||||||
$scope.type = res.type
|
|
||||||
$scope.labels = res.labels
|
|
||||||
$scope.content = res.content
|
|
||||||
|
|
||||||
$scope.changeToBody = ->
|
|
||||||
$scope.body_active = true
|
|
||||||
|
|
||||||
$scope.changeToPreview = ->
|
|
||||||
$scope.body_active = false
|
|
||||||
$scope.previewHTML = 'Loading...'
|
|
||||||
$http.post '/admin/posts/preview', { content: $scope.content }
|
|
||||||
.success (res)->
|
|
||||||
$scope.previewHTML = res
|
|
||||||
|
|
||||||
$scope.trustAsPreviewHTML = ()->
|
|
||||||
$sce.trustAsHtml($scope.previewHTML)
|
|
||||||
|
|
||||||
$scope.addTag = (e)->
|
|
||||||
new_labels= $(e.target).text()
|
|
||||||
if $scope.labels
|
|
||||||
$scope.labels += ", #{new_labels}"
|
|
||||||
else
|
|
||||||
$scope.labels = new_labels
|
|
||||||
]
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
$(document).ready ()->
|
||||||
|
$('#qrcode-link').click (event)->
|
||||||
|
event.preventDefault()
|
||||||
|
$('.social-share').toggle()
|
|
@ -233,7 +233,7 @@ $breadcrumbs-item-slash: true;
|
||||||
// 11. Button
|
// 11. Button
|
||||||
// ----------
|
// ----------
|
||||||
|
|
||||||
$button-padding: 0.85em 1em;
|
$button-padding: 1rem 2rem 1.0625rem 2rem;
|
||||||
$button-margin: 0 0 $global-margin 0;
|
$button-margin: 0 0 $global-margin 0;
|
||||||
$button-fill: solid;
|
$button-fill: solid;
|
||||||
$button-background: $primary-color;
|
$button-background: $primary-color;
|
||||||
|
@ -512,12 +512,12 @@ $show-header-for-stacked: false;
|
||||||
$tab-margin: 0;
|
$tab-margin: 0;
|
||||||
$tab-background: $white;
|
$tab-background: $white;
|
||||||
$tab-background-active: $light-gray;
|
$tab-background-active: $light-gray;
|
||||||
$tab-item-font-size: rem-calc(12);
|
$tab-item-font-size: rem-calc(16);
|
||||||
$tab-item-background-hover: $white;
|
$tab-item-background-hover: $white;
|
||||||
$tab-item-padding: 1.25rem 1.5rem;
|
$tab-item-padding: 1.25rem 1.5rem;
|
||||||
$tab-expand-max: 6;
|
$tab-expand-max: 6;
|
||||||
$tab-content-background: $white;
|
$tab-content-background: $white;
|
||||||
$tab-content-border: $light-gray;
|
$tab-content-border: none;
|
||||||
$tab-content-color: foreground($tab-background, $primary-color);
|
$tab-content-color: foreground($tab-background, $primary-color);
|
||||||
$tab-content-padding: 1rem;
|
$tab-content-padding: 1rem;
|
||||||
|
|
||||||
|
|
|
@ -7,10 +7,14 @@
|
||||||
margin-bottom: 2rem;
|
margin-bottom: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
#post_content {
|
#content-input {
|
||||||
min-height: 20rem;
|
min-height: 20rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.content-field {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.preview {
|
.preview {
|
||||||
min-height: 20rem;
|
min-height: 20rem;
|
||||||
border: 1px solid #DDDDDD;
|
border: 1px solid #DDDDDD;
|
||||||
|
@ -25,7 +29,7 @@
|
||||||
|
|
||||||
#upload_photo {
|
#upload_photo {
|
||||||
float: right;
|
float: right;
|
||||||
margin-top: 2rem;
|
margin-top: 1.875rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr {
|
tr {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
@import 'font-awesome-sprockets';
|
@import 'font-awesome-sprockets';
|
||||||
@import 'font-awesome';
|
@import 'font-awesome';
|
||||||
@import 'foundation_and_overrides';
|
@import 'foundation_and_overrides';
|
||||||
|
@import 'foundation-icons';
|
||||||
|
|
||||||
@import 'aboutme_welcome';
|
@import 'aboutme_welcome';
|
||||||
@import 'archives';
|
@import 'archives';
|
||||||
|
|
|
@ -69,6 +69,10 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.social-share {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
.qrcode-wrapper {
|
.qrcode-wrapper {
|
||||||
float: right;
|
float: right;
|
||||||
margin-top: -2rem;
|
margin-top: -2rem;
|
||||||
|
|
|
@ -10,16 +10,6 @@ class Admin::PostsController < ApplicationController
|
||||||
@post = Post.find( params[:id] )
|
@post = Post.find( params[:id] )
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
|
||||||
post = Post.find( params[:id] )
|
|
||||||
render :json=> {
|
|
||||||
title: post.title,
|
|
||||||
type: post.type,
|
|
||||||
labels: post.labels_content(true),
|
|
||||||
content: post.content
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
@post = Post.find( params[:id] )
|
@post = Post.find( params[:id] )
|
||||||
if @post.destroy
|
if @post.destroy
|
||||||
|
@ -32,7 +22,7 @@ class Admin::PostsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@posts = Post.desc(:created_at)
|
@posts = Post.order(created_at: :desc).page(params[:page]).per(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
|
@ -71,7 +61,7 @@ class Admin::PostsController < ApplicationController
|
||||||
private
|
private
|
||||||
def initialize_or_create_labels(labels)
|
def initialize_or_create_labels(labels)
|
||||||
@post.labels = []
|
@post.labels = []
|
||||||
labels.split(",").each do |name|
|
labels.split(",").map { |i| i.strip }.uniq.each do |name|
|
||||||
label = Label.find_or_initialize_by(name: name.strip)
|
label = Label.find_or_initialize_by(name: name.strip)
|
||||||
label.save!
|
label.save!
|
||||||
@post.labels << label
|
@post.labels << label
|
||||||
|
|
|
@ -5,17 +5,19 @@ class Admin::SessionsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
#TODO
|
|
||||||
if ENV['ADMIN_USER'].blank?
|
if ENV['ADMIN_USER'].blank?
|
||||||
render :json=> { success: false, message: t('admin.session.no_configuration') }
|
flash.now[:alert] = t('admin.session.no_configuration')
|
||||||
|
render :new
|
||||||
elsif ENV['ADMIN_USER'] != params[:username]
|
elsif ENV['ADMIN_USER'] != params[:username]
|
||||||
render :json=> { success: false, message: t('admin.session.username_error') }
|
flash.now[:alert] = t('admin.session.username_error')
|
||||||
|
render :new
|
||||||
elsif ENV['ADMIN_PASSWORD'] != params[:password]
|
elsif ENV['ADMIN_PASSWORD'] != params[:password]
|
||||||
render :json=> { success: false, message: t('admin.session.password_error') }
|
flash.now[:alert] = t('admin.session.password_error')
|
||||||
|
render :new
|
||||||
else
|
else
|
||||||
flash[:notice] = t('admin.session.login_success')
|
flash[:notice] = t('admin.session.login_success')
|
||||||
session[:login] = true
|
session[:login] = true
|
||||||
render :json=> { success: true }
|
redirect_to admin_root_path
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,60 +1,5 @@
|
||||||
class ArchivesController < ApplicationController
|
class ArchivesController < ApplicationController
|
||||||
def index
|
def index
|
||||||
type = map[params[:type]]
|
@posts = Post.order(created_at: :desc)
|
||||||
limit = 10
|
|
||||||
start_with = params[:start_with]
|
|
||||||
@posts = Post.desc(:created_at)
|
|
||||||
|
|
||||||
if type
|
|
||||||
@posts = @posts.where(type: type)
|
|
||||||
@type = type
|
|
||||||
end
|
|
||||||
|
|
||||||
# all 与 start_with 参数同在, 说明是要获取所有start_with之前的数据
|
|
||||||
if params[:all] and params[:start_with]
|
|
||||||
@posts = @posts.where(:created_at.gte => Time.at(start_with.to_i))
|
|
||||||
else
|
|
||||||
@posts = @posts.limit(limit)
|
|
||||||
end
|
|
||||||
|
|
||||||
if !params[:all] and start_with
|
|
||||||
@posts = @posts.where(:created_at.lt => Time.at(start_with.to_i))
|
|
||||||
end
|
|
||||||
|
|
||||||
#update start_with
|
|
||||||
unless @posts.empty?
|
|
||||||
start_with = @posts[-1].created_at.to_i.to_s
|
|
||||||
end
|
|
||||||
|
|
||||||
respond_to do |format|
|
|
||||||
format.json do
|
|
||||||
render :json => {
|
|
||||||
posts: @posts.collect { |post| build_summary(post) },
|
|
||||||
start_with: start_with
|
|
||||||
}
|
|
||||||
end
|
|
||||||
format.html
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
def map
|
|
||||||
{
|
|
||||||
"life"=> "生活",
|
|
||||||
"tech"=> "技术",
|
|
||||||
"creator"=> "创业"
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def build_summary(post)
|
|
||||||
{
|
|
||||||
title: post.title,
|
|
||||||
type: post.type_en,
|
|
||||||
created_at: format_date(post.created_at),
|
|
||||||
id: post.id.to_s,
|
|
||||||
liked_count: post.liked_count,
|
|
||||||
visited_count: post.visited_count,
|
|
||||||
labels: post.labels_content
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -19,9 +19,10 @@ class BlogsController < ApplicationController
|
||||||
def show
|
def show
|
||||||
@post = Post.find(params[:id])
|
@post = Post.find(params[:id])
|
||||||
@post.visited
|
@post.visited
|
||||||
@prev = Post.where(:created_at.lt => @post.created_at).desc(:created_at).where(:id.ne => @post.id).first
|
@prev = Post.where('created_at < ?', @post.created_at).order(created_at: :desc).first
|
||||||
@next = Post.where(:created_at.gt => @post.created_at).asc(:created_at).where(:id.ne => @post.id).first
|
@prev = Post.where('created_at > ?', @post.created_at).order(created_at: :asc).first
|
||||||
@comments = @post.comments
|
@comments = @post.comments
|
||||||
|
@likes_count = @post.likes.count
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html
|
format.html
|
||||||
format.json
|
format.json
|
||||||
|
|
|
@ -1,2 +1,5 @@
|
||||||
module ApplicationHelper
|
module ApplicationHelper
|
||||||
|
def format_date(time)
|
||||||
|
time.strftime('%Y-%m-%d')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,14 +2,11 @@
|
||||||
= simple_form_for(@post, url: url, html: {novalidate: '' }) do |f|
|
= simple_form_for(@post, url: url, html: {novalidate: '' }) do |f|
|
||||||
.row
|
.row
|
||||||
.large-6.columns
|
.large-6.columns
|
||||||
= f.input :title, label: t('admin.posts_attributes.title'), "ng-model"=>"title", input_html: { name: 'title' }
|
= f.input :title, label: t('admin.posts_attributes.title'), input_html: { name: 'title' }
|
||||||
.row
|
|
||||||
.small-6.large-3.columns
|
|
||||||
= f.input :type, :as=>:select, :collection=> [ Post::TECH, Post::LIFE, Post::CREATOR ], label: t('admin.posts_attributes.type'), "ng-model"=>"type", input_html: { name: 'type' }
|
|
||||||
.row
|
.row
|
||||||
.small-12.large-6.columns
|
.small-12.large-6.columns
|
||||||
= label_tag :labels, t('admin.posts_attributes.labels')
|
= label_tag :labels, t('admin.posts_attributes.labels')
|
||||||
= text_field_tag :labels, @post.labels_content(true), "ng-model"=>"labels", "ng-initial" => ''
|
= text_field_tag :labels, @post.labels_content(true)
|
||||||
|
|
||||||
.row
|
.row
|
||||||
.small-12.columns
|
.small-12.columns
|
||||||
|
@ -17,22 +14,23 @@
|
||||||
| #{t('admin.posts_attributes.already_labels')}
|
| #{t('admin.posts_attributes.already_labels')}
|
||||||
span
|
span
|
||||||
- Label.all.each do |label|
|
- Label.all.each do |label|
|
||||||
a.tag href="#" ng-click="addTag($event)" #{label.name}
|
a.tag href="#" #{label.name}
|
||||||
|
|
||||||
/ tabs and upload file field
|
/ tabs and upload file field
|
||||||
dl.tabs
|
ul.tabs#tabs data-tabs=''
|
||||||
dd ng-class="{ active: body_active }"
|
li.tabs-title.is-active
|
||||||
a href="" ng-click="changeToBody()" #{t('admin.posts_attributes.content')}
|
a href="#content" #{t('admin.posts_attributes.content')}
|
||||||
dd ng-class="{ active: !body_active }"
|
li.tabs-title
|
||||||
a href="#" ng-click="changeToPreview()" #{t('admin.posts_attributes.preview')}
|
a href="#preview" #{t('admin.posts_attributes.preview')}
|
||||||
= link_to t('admin.posts_attributes.upload_photo'), "#", :id=>'upload_photo'
|
= link_to t('admin.posts_attributes.upload_photo'), "#", :id=>'upload_photo'
|
||||||
input[type="file" style="display: none;"]
|
input[type="file" style="display: none;"]
|
||||||
|
|
||||||
.content-field ng-show="body_active" ng-model= 'content'
|
.tabs-content data-tabs-content='tabs'
|
||||||
= f.input :content, :as=> :text, :label => false, input_html: { name: 'content', "ng-model"=>'content', 'ng-initial'=>'' }
|
.tabs-panel.content-field.is-active#content
|
||||||
|
= f.input :content, :as=> :text, :label => false, input_html: { name: 'content', id: 'content-input' }
|
||||||
|
|
||||||
.preview.markdown ng-hide="body_active" ng-bind-html=" trustAsPreviewHTML() "
|
.tabs-panel.preview.markdown#preview
|
||||||
|
|
||||||
.row
|
.row
|
||||||
.small-12.large-6.columns.posts-button
|
.small-12.large-6.columns.posts-button
|
||||||
button #{t('admin.posts_attributes.submit')}
|
button.button type='submit' #{t('admin.posts_attributes.submit')}
|
||||||
|
|
|
@ -15,8 +15,6 @@
|
||||||
td.admin-post-summary-field
|
td.admin-post-summary-field
|
||||||
i.fi-calendar
|
i.fi-calendar
|
||||||
span #{format_time(post.created_at)}
|
span #{format_time(post.created_at)}
|
||||||
i.fi-list
|
|
||||||
span #{ post.type_en }
|
|
||||||
i.fi-pricetag-multiple
|
i.fi-pricetag-multiple
|
||||||
span #{ post.labels_content }
|
span #{ post.labels_content }
|
||||||
i.fi-torsos
|
i.fi-torsos
|
||||||
|
@ -27,3 +25,4 @@
|
||||||
= link_to t('comment'), admin_post_comments_path(post.id), class: 'edit-post-link'
|
= link_to t('comment'), admin_post_comments_path(post.id), class: 'edit-post-link'
|
||||||
= link_to t('edit'), edit_admin_post_path(post), class: 'edit-post-link'
|
= link_to t('edit'), edit_admin_post_path(post), class: 'edit-post-link'
|
||||||
= link_to t('destroy'), admin_post_path(post), method: 'DELETE', 'data-confirm' => '确认删除?'
|
= link_to t('destroy'), admin_post_path(post), method: 'DELETE', 'data-confirm' => '确认删除?'
|
||||||
|
== paginate @posts
|
||||||
|
|
|
@ -1,16 +1,12 @@
|
||||||
.row ng-controller="AdminSessionsController"
|
.row ng-controller="AdminSessionsController"
|
||||||
.small-12.large-8.columns
|
.small-12.large-8.columns
|
||||||
h3.blog-title #{t('admin.session.title')}
|
h3.blog-title #{t('admin.session.title')}
|
||||||
form ng-submit="login()"
|
= form_tag admin_sessions_path
|
||||||
.row
|
.row
|
||||||
.small-12.large-8.columns
|
.small-12.large-8.columns
|
||||||
= label_tag 'username', t('admin.session.username')
|
= label_tag 'username', t('admin.session.username')
|
||||||
= text_field_tag 'username', nil, placeholder: t('admin.session.username_placeholder'), "ng-model"=>"username"
|
= text_field_tag 'username', params[:username], placeholder: t('admin.session.username_placeholder')
|
||||||
= label_tag 'username', t('admin.session.password')
|
= label_tag 'username', t('admin.session.password')
|
||||||
= password_field_tag 'password', nil, placeholder: t('admin.session.password_placeholder'), "ng-model"=>"password"
|
= password_field_tag 'password', params[:password], placeholder: t('admin.session.password_placeholder')
|
||||||
|
|
||||||
p
|
button.button type='submit' #{t('admin.session.login_button')}
|
||||||
.alert-box.warning ng-show=" error_msg "
|
|
||||||
|{{ error_msg }}
|
|
||||||
|
|
||||||
button #{t('admin.session.login_button')}
|
|
||||||
|
|
|
@ -1,30 +1,21 @@
|
||||||
- content_for(:title) do
|
- content_for(:title) do
|
||||||
| #{@type ? @type : t('title.timeline')}
|
| #{t('title.timeline')}
|
||||||
.row ng-controller="ArchivesController" ng-cloak=""
|
.row
|
||||||
.small-12.large-9.large-centered.columns
|
.small-12.large-9.large-centered.columns
|
||||||
ul.archives-field ng-model="type" ng-init=" type= '#{@type}' "
|
ul.archives-field
|
||||||
li ng-repeat=" post in posts "
|
- @posts.each do |post|
|
||||||
a.blog-title ng-href="{{ visit(post.id) }}"
|
li
|
||||||
|{{ post.title }}
|
= link_to post.title, blog_path(post), class: 'blog-title'
|
||||||
p.tags-field
|
p.tags-field
|
||||||
i.fi-calendar
|
i.fi-calendar
|
||||||
span
|
span
|
||||||
|{{ post.created_at }}
|
= format_date(post.created_at)
|
||||||
i.fi-list-thumbnails
|
|
||||||
span
|
|
||||||
|{{ post.type }}
|
|
||||||
i.fi-pricetag-multiple
|
i.fi-pricetag-multiple
|
||||||
span
|
span
|
||||||
|{{ post.labels }}
|
= post.labels_content
|
||||||
i.fi-torsos
|
i.fi-torsos
|
||||||
span
|
span
|
||||||
|{{ post.visited_count }}
|
= post.visited_count
|
||||||
i.fi-heart
|
i.fi-heart
|
||||||
span
|
span
|
||||||
|{{ post.liked_count }}
|
= post.liked_count
|
||||||
.no-more-field
|
|
||||||
p ng-show="no_more_flag" #{t('nocontent')}
|
|
||||||
|
|
||||||
.load-more
|
|
||||||
button.small ng-click="load()" ng-show="!loading_flag" Load More
|
|
||||||
button.small ng-show="loading_flag" Loading
|
|
||||||
|
|
|
@ -1,21 +1,22 @@
|
||||||
.row ng-controller="CommentsController" ng-cloak=""
|
.row
|
||||||
.small-12.large-9.large-centered.columns
|
.small-12.large-9.large-centered.columns
|
||||||
form novalidate='' name='form'
|
form novalidate='' name='form'
|
||||||
|
= form_for Comment.new, url: blog_comments_path(@post) do |f|
|
||||||
.row
|
.row
|
||||||
.small-12.large-12.columns
|
.small-12.large-12.columns
|
||||||
= text_area_tag(:content, nil, placeholder: t('comment_placeholder.content'), 'ng-model'=> 'content', 'ng-required'=> true)
|
= f.text_area :content, placeholder: t('comment_placeholder.content')
|
||||||
.row
|
.row
|
||||||
.small-12.large-6.columns
|
.small-12.large-6.columns
|
||||||
= text_field_tag(:name, nil, placeholder: t('comment_placeholder.name'), 'ng-model'=> 'name', 'ng-required'=> 'true')
|
= f.text_field :name, placeholder: t('comment_placeholder.name')
|
||||||
= text_field_tag(:email, nil, placeholder: t('comment_placeholder.email'), 'ng-model'=> 'email', 'ng-pattern'=>"/^.+@.+$/", 'ng-required'=>"true")
|
= f.text_field :email, placeholder: t('comment_placeholder.email')
|
||||||
button.comment-submit ng-click="submit()" ng-disabled="form.$invalid || submitting" {{ submitting && "#{t('comment_placeholder.submitting')}" || "#{t('comment_placeholder.submit')}" }}
|
button.button.comment-submit type='submit' #{t('comment_placeholder.submit')}
|
||||||
p.comment-success ng-show="publish_success" #{t('comment_placeholder.publish_success')}
|
|
||||||
p.comment-fail ng-show="publish_success == false" #{t('comment_placeholder.publish_fail')}: {{ publish_fail_msg }}
|
|
||||||
.comment-diag
|
.comment-diag
|
||||||
.comment-wrapper ng-repeat=" comment in comments "
|
.comment-wrapper
|
||||||
|
- comments.each do |comment|
|
||||||
p.name
|
p.name
|
||||||
|{{ comment.name + " • " }}
|
| #{comment.name}
|
||||||
|
| " • "
|
||||||
span.created-at
|
span.created-at
|
||||||
|{{ comment.created_at }}
|
| #{comment.created_at }
|
||||||
/ ignore "white-space: pre" 's effect
|
/ ignore "white-space: pre" 's effect
|
||||||
<p class=comment-content>{{ comment.content }}</p>
|
<p class=comment-content>#{comment.content}</p>
|
||||||
|
|
|
@ -8,21 +8,15 @@ p.ptag.published-at
|
||||||
span #{format_date(post.created_at)}
|
span #{format_date(post.created_at)}
|
||||||
|
|
||||||
= render 'common/copyright'
|
= render 'common/copyright'
|
||||||
|
|
||||||
hr.blog-over
|
hr.blog-over
|
||||||
p ng-controller="LikesController" ng-cloak=""
|
p
|
||||||
button.like-button ng-show="! is_liked " ng-click="submit()"
|
button.button.like-button type='button'
|
||||||
|{{ count }}
|
| #{@likes_count} Like
|
||||||
span Like
|
|
||||||
button.like-button.liked ng-show=" is_liked " ng-click="cancel()"
|
|
||||||
|{{ count }}
|
|
||||||
span Like
|
|
||||||
div ng-controller = "QRCodesController"
|
|
||||||
.qrcode
|
.qrcode
|
||||||
a href="#" ng-model="qrcode" ng-init="qrcode=false" ng-click="show()"
|
a#qrcode-link href="#"
|
||||||
i.fi-link
|
i.fi-link
|
||||||
| #{t('qr_code')}
|
| #{t('qr_code')}
|
||||||
|
|
||||||
.social-share ng-show='qrcode'
|
.social-share
|
||||||
.qrcode-wrapper
|
.qrcode-wrapper
|
||||||
= render partial: "qrcode", locals: { str: blog_url(post) }
|
= render partial: "qrcode", locals: { str: blog_url(post) }
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
/ require: locals: { post : post }
|
/ require: locals: { post : post }
|
||||||
h2.blog-title #{post.title}
|
h2.blog-title #{post.title}
|
||||||
p.ptag
|
p.ptag
|
||||||
span
|
|
||||||
i.fi-list-thumbnails
|
|
||||||
span #{post.type_en}
|
|
||||||
span
|
span
|
||||||
i.fi-pricetag-multiple
|
i.fi-pricetag-multiple
|
||||||
span #{post.labels_content}
|
span #{post.labels_content}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
/ Non-link tag that stands for skipped pages...
|
||||||
|
- available local variables
|
||||||
|
current_page : a page object for the currently displayed page
|
||||||
|
total_pages : total number of pages
|
||||||
|
per_page : number of items to fetch per page
|
||||||
|
remote : data-remote
|
||||||
|
li.ellipsis
|
|
@ -0,0 +1,10 @@
|
||||||
|
/ Link to the "Last" page
|
||||||
|
- available local variables
|
||||||
|
url : url to the last page
|
||||||
|
current_page : a page object for the currently displayed page
|
||||||
|
total_pages : total number of pages
|
||||||
|
per_page : number of items to fetch per page
|
||||||
|
remote : data-remote
|
||||||
|
span.last
|
||||||
|
== link_to_unless current_page.last?, t('views.pagination.last').html_safe, url, :remote => remote
|
||||||
|
'
|
|
@ -0,0 +1,10 @@
|
||||||
|
/ Link to the "Next" page
|
||||||
|
- available local variables
|
||||||
|
url : url to the next page
|
||||||
|
current_page : a page object for the currently displayed page
|
||||||
|
total_pages : total number of pages
|
||||||
|
per_page : number of items to fetch per page
|
||||||
|
remote : data-remote
|
||||||
|
li.pagination-next class="#{'disabled' if current_page.last?}"
|
||||||
|
== link_to_unless current_page.last?, t('views.pagination.next').html_safe, url, :rel => 'next', :remote => remote
|
||||||
|
'
|
|
@ -0,0 +1,11 @@
|
||||||
|
/ Link showing page number
|
||||||
|
- available local variables
|
||||||
|
page : a page object for "this" page
|
||||||
|
url : url to this page
|
||||||
|
current_page : a page object for the currently displayed page
|
||||||
|
total_pages : total number of pages
|
||||||
|
per_page : number of items to fetch per page
|
||||||
|
remote : data-remote
|
||||||
|
li class="page#{' current' if page.current?}"
|
||||||
|
== link_to_unless page.current?, page, url, {:remote => remote, :rel => page.rel}
|
||||||
|
'
|
|
@ -0,0 +1,17 @@
|
||||||
|
/ The container tag
|
||||||
|
- available local variables
|
||||||
|
current_page : a page object for the currently displayed page
|
||||||
|
total_pages : total number of pages
|
||||||
|
per_page : number of items to fetch per page
|
||||||
|
remote : data-remote
|
||||||
|
paginator : the paginator that renders the pagination tags inside
|
||||||
|
|
||||||
|
== paginator.render do
|
||||||
|
ul.pagination
|
||||||
|
== prev_page_tag
|
||||||
|
- each_page do |page|
|
||||||
|
- if page.left_outer? || page.right_outer? || page.inside_window?
|
||||||
|
== page_tag page
|
||||||
|
- elsif !page.was_truncated?
|
||||||
|
== gap_tag
|
||||||
|
== next_page_tag
|
|
@ -0,0 +1,10 @@
|
||||||
|
/ Link to the "Previous" page
|
||||||
|
- available local variables
|
||||||
|
url : url to the previous page
|
||||||
|
current_page : a page object for the currently displayed page
|
||||||
|
total_pages : total number of pages
|
||||||
|
per_page : number of items to fetch per page
|
||||||
|
remote : data-remote
|
||||||
|
li.pagination-previous class="#{'disabled' if current_page.first?}"
|
||||||
|
== link_to_unless current_page.first?, t('views.pagination.previous').html_safe, url, :rel => 'prev', :remote => remote
|
||||||
|
'
|
|
@ -10,7 +10,7 @@ html
|
||||||
= favicon_link_tag 'favicon.png', type: 'image/png'
|
= favicon_link_tag 'favicon.png', type: 'image/png'
|
||||||
= javascript_include_tag "application"
|
= javascript_include_tag "application"
|
||||||
= csrf_meta_tags
|
= csrf_meta_tags
|
||||||
body
|
body data-whatinput="mouse"
|
||||||
- if content_for?(:main)
|
- if content_for?(:main)
|
||||||
= yield(:main)
|
= yield(:main)
|
||||||
- else
|
- else
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
Kaminari.configure do |config|
|
||||||
|
config.default_per_page = 10
|
||||||
|
# config.max_per_page = nil
|
||||||
|
# config.window = 4
|
||||||
|
# config.outer_window = 0
|
||||||
|
# config.left = 0
|
||||||
|
# config.right = 0
|
||||||
|
# config.page_method_name = :page
|
||||||
|
# config.param_name = :page
|
||||||
|
end
|
|
@ -25,7 +25,7 @@ WBlog::Application.routes.draw do
|
||||||
get '/qrcodes' => 'qrcodes#show'
|
get '/qrcodes' => 'qrcodes#show'
|
||||||
|
|
||||||
namespace :admin do
|
namespace :admin do
|
||||||
resources :posts do
|
resources :posts, except: [:show] do
|
||||||
collection do
|
collection do
|
||||||
post :preview
|
post :preview
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
class CreateLabelsPosts < ActiveRecord::Migration[5.0]
|
||||||
|
def change
|
||||||
|
create_table :labels_posts, id: false do |t|
|
||||||
|
t.integer :label_id
|
||||||
|
t.integer :post_id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
class ChangeColumnDefaultVisitedCountToPosts < ActiveRecord::Migration[5.0]
|
||||||
|
def change
|
||||||
|
change_column_default :posts, :visited_count, 0
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
class RenameColumnContentToComments < ActiveRecord::Migration[5.0]
|
||||||
|
def change
|
||||||
|
rename_column :comments, :conent, :content
|
||||||
|
end
|
||||||
|
end
|
11
db/schema.rb
11
db/schema.rb
|
@ -11,7 +11,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 20160420082909) do
|
ActiveRecord::Schema.define(version: 20160421062614) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
|
@ -19,7 +19,7 @@ ActiveRecord::Schema.define(version: 20160420082909) do
|
||||||
create_table "comments", force: :cascade do |t|
|
create_table "comments", force: :cascade do |t|
|
||||||
t.string "name"
|
t.string "name"
|
||||||
t.string "email"
|
t.string "email"
|
||||||
t.text "conent"
|
t.text "content"
|
||||||
t.integer "post_id"
|
t.integer "post_id"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
|
@ -31,6 +31,11 @@ ActiveRecord::Schema.define(version: 20160420082909) do
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_table "labels_posts", id: false, force: :cascade do |t|
|
||||||
|
t.integer "label_id"
|
||||||
|
t.integer "post_id"
|
||||||
|
end
|
||||||
|
|
||||||
create_table "likes", force: :cascade do |t|
|
create_table "likes", force: :cascade do |t|
|
||||||
t.integer "post_id"
|
t.integer "post_id"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
|
@ -46,7 +51,7 @@ ActiveRecord::Schema.define(version: 20160420082909) do
|
||||||
create_table "posts", force: :cascade do |t|
|
create_table "posts", force: :cascade do |t|
|
||||||
t.string "title"
|
t.string "title"
|
||||||
t.text "content"
|
t.text "content"
|
||||||
t.integer "visited_count"
|
t.integer "visited_count", default: 0
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue