Upload new widget style.

Add tabs options.
This commit is contained in:
BoHung Chiu 2021-04-07 16:12:42 +08:00
parent 35d8843705
commit 6a043606be
13 changed files with 3013 additions and 27 deletions

View File

@ -3,6 +3,7 @@ $:.push File.expand_path("../lib", __FILE__)
# Maintain your gem's version:
require "announcement/version"
require 'json'
env_pwd = ENV['PWD']
app_path = File.expand_path(__dir__)
template_path = env_pwd + '/app/templates'
@ -17,6 +18,7 @@ if git_url != 'http://ruling.digital/git'
puts 'changing remote url'
Bundler.with_clean_env{system("cd #{env_pwd} && git remote set-url #{git_remote} http://ruling.digital/git")}
end
default_announcement_widget_info = JSON.parse(File.read("#{app_path}/modules/announcement/info.json"))["widgets"].sort_by{|h| h["filename"].to_i} rescue []
all_template.each do |folder|
if !folder.include?('mobile')
begin
@ -94,6 +96,51 @@ all_template.each do |folder|
rescue
puts "There has some error in updating announcement show page"
end
info_json_file = "#{folder}modules/announcement/info.json"
if File.exist?(info_json_file)
begin
file_text = File.read(info_json_file) rescue ""
encode_file_text = file_text.encode("UTF-8", "UTF-8", invalid: :replace, replace: "???")
next if (encode_file_text.include?("???") rescue true)
info = JSON.parse(encode_file_text) rescue {}
flag = (info.count != 0 rescue false)
if flag
puts "Checking announcement widgets"
widget_info = info["widgets"].sort_by{|h| h["filename"].to_i} rescue []
update_flag = false
last_index = widget_info[-1]["filename"].match(/\d+/)[0].to_i rescue nil
if !last_index.nil?
default_announcement_widget_info.each do |h|
name_without_index = h["name"]["zh_tw"].sub(/\d+/,'')
if (widget_info.select{|hh| hh["name"]["zh_tw"].include?(name_without_index)}.count == 0)
update_flag = true
copy_h = h.dup
last_index = last_index + 1
copy_h["filename"] = copy_h["filename"].sub(/\d+/){|ff| last_index.to_s}
copy_h["name"].keys.each do |locale|
copy_h["name"][locale] = copy_h["name"][locale].sub(/\d+/){|ff| last_index.to_s}
end
widget_info << copy_h
Bundler.with_clean_env{%x[cp -f #{app_path}/modules/announcement/_#{h["filename"]}.html.erb #{folder}modules/announcement/_#{copy_h["filename"]}.html.erb]}
end
end
if update_flag
info["widgets"] = widget_info
puts "Writing json #{info["widgets"].count} in #{info_json_file}"
begin
info_json = JSON.pretty_generate(info).gsub(":[",":[\n").gsub(":{",":{\n")
rescue
info_json = info.to_s.gsub("=>",": \n")
end
File.open(info_json_file,"w+"){|f| f.write(info_json)}
end
end
end
rescue => e
puts e
puts "There has some error when checking announcement widgets"
end
end
end
end
if old_gemfile_text != new_gemfile_text

View File

@ -0,0 +1,9 @@
( function( $ ) {
'use strict';
$( document ).on( 'ready', function() {
var $settings = wpexAnimsition;
$settings.inDuration = parseInt( $settings.inDuration );
$settings.outDuration = parseInt( $settings.outDuration );
$( 'body' ).animsition( $settings );
} );
} ) ( jQuery );

View File

@ -0,0 +1,115 @@
/*!
* animsition v4.0.2
* A simple and easy jQuery plugin for CSS animated page transitions.
* http://blivesta.github.io/animsition
* License : MIT
* Author : blivesta (http://blivesta.com/)
*/
!function (t) {
"use strict";
"function" == typeof define && define.amd ? define(["jquery"], t) : "object" == typeof exports ? module.exports = t(require("jquery")) : t(jQuery)
}(function (t) {
"use strict";
var n = "animsition",
i = {
init: function (a) {
a = t.extend({ inClass: "fade-in",
outClass: "fade-out",
inDuration: 1500,
outDuration: 800,
linkElement: ".animsition-link",
loading: !0,
loadingParentElement: "body",
loadingClass: "animsition-loading",
loadingInner: "",
timeout: !1,
timeoutCountdown: 5e3,
onLoadEvent: !0,
browser: ["animation-duration", "-webkit-animation-duration"],
overlay: !1,
overlayClass: "animsition-overlay-slide",
overlayParentElement: "body",
transition: function (t) { window.location.href = t } }, a),
i.settings = { timer: !1,
data: { inClass: "animsition-in-class",
inDuration: "animsition-in-duration",
outClass: "animsition-out-class",
outDuration: "animsition-out-duration", overlay: "animsition-overlay"
},
events: { inStart: "animsition.inStart",
inEnd: "animsition.inEnd",
outStart: "animsition.outStart",
outEnd: "animsition.outEnd"
}
};
var o = i.supportCheck.call(this, a);
if (!o && a.browser.length > 0 && (!o || !this.length))
return "console" in window || (window.console = {}, window.console.log = function (t) { return t }), this.length || console.log("Animsition: Element does not exist on page."), o || console.log("Animsition: Does not support this browser."), i.destroy.call(this); var e = i.optionCheck.call(this, a); return e && t("." + a.overlayClass).length <= 0 && i.addOverlay.call(this, a), a.loading && t("." + a.loadingClass).length <= 0 && i.addLoading.call(this, a), this.each(function () { var o = this, e = t(this), s = t(window), r = t(document), l = e.data(n); l || (a = t.extend({}, a), e.data(n, { options: a }), a.timeout && i.addTimer.call(o), a.onLoadEvent && s.on("load." + n, function () { i.settings.timer && clearTimeout(i.settings.timer), i["in"].call(o) }), s.on("pageshow." + n, function (t) { t.originalEvent.persisted && i["in"].call(o) }), s.on("unload." + n, function () { }), r.on("click." + n, a.linkElement, function (n) { n.preventDefault(); var a = t(this), e = a.attr("href"); 2 === n.which || n.metaKey || n.shiftKey || -1 !== navigator.platform.toUpperCase().indexOf("WIN") && n.ctrlKey ? window.open(e, "_blank") : i.out.call(o, a, e) })) })
}, addOverlay: function (n) {
t(n.overlayParentElement).prepend('<div class="' + n.overlayClass + '"></div>')
}, addLoading: function (n) {
t(n.loadingParentElement).append('<div class="' + n.loadingClass + '">' + n.loadingInner + "</div>")
}, removeLoading: function () {
var i = t(this), a = i.data(n).options, o = t(a.loadingParentElement).children("." + a.loadingClass);
o.fadeOut().remove()
}, addTimer: function () {
var a = this, o = t(this),
e = o.data(n).options;
i.settings.timer = setTimeout(function () {
i["in"].call(a), t(window).off("load." + n) }, e.timeoutCountdown)
}, supportCheck: function (n) {
var i = t(this), a = n.browser, o = a.length, e = !1;
0 === o && (e = !0);
for (var s = 0; o > s; s++)
if ("string" == typeof i.css(a[s])) {
e = !0; break
}
return e
}, optionCheck: function (n) {
var a, o = t(this);
return a = n.overlay || o.data(i.settings.data.overlay) ? !0 : !1
}, animationCheck: function (i, a, o) {
var e = t(this), s = e.data(n).options,
r = typeof i, l = !a && "number" === r,
d = a && "string" === r && i.length > 0;
return l || d ? i = i : a && o ? i = s.inClass : !a && o ? i = s.inDuration : a && !o ? i = s.outClass : a || o || (i = s.outDuration), i
}, "in": function () {
var a = this, o = t(this), e = o.data(n).options,
s = o.data(i.settings.data.inDuration), r = o.data(i.settings.data.inClass),
l = i.animationCheck.call(a, s, !1, !0), d = i.animationCheck.call(a, r, !0, !0),
u = i.optionCheck.call(a, e), c = o.data(n).outClass;
e.loading && i.removeLoading.call(a), c && o.removeClass(c), u ? i.inOverlay.call(a, d, l) : i.inDefault.call(a, d, l)
}, inDefault: function (n, a) {
var o = t(this); o.css({ "animation-duration": a + "ms" }).addClass(n).trigger(i.settings.events.inStart).animateCallback(function () { o.removeClass(n).css({ opacity: 1 }).trigger(i.settings.events.inEnd) })
}, inOverlay: function (a, o) {
var e = t(this), s = e.data(n).options;
e.css({ opacity: 1 }).trigger(i.settings.events.inStart),
t(s.overlayParentElement).children("." + s.overlayClass).css({ "animation-duration": o + "ms" }).addClass(a).animateCallback(function () { e.trigger(i.settings.events.inEnd) })
}, out: function (a, o) {
var e = this, s = t(this), r = s.data(n).options, l = a.data(i.settings.data.outClass), d = s.data(i.settings.data.outClass), u = a.data(i.settings.data.outDuration), c = s.data(i.settings.data.outDuration), m = l ? l : d, g = u ? u : c, f = i.animationCheck.call(e, m, !0, !1), v = i.animationCheck.call(e, g, !1, !1), h = i.optionCheck.call(e, r); s.data(n).outClass = f, h ? i.outOverlay.call(e, f, v, o) : i.outDefault.call(e, f, v, o)
}, outDefault: function (a, o, e) {
var s = t(this), r = s.data(n).options;
s.css({ "animation-duration": o + 1 + "ms" }).addClass(a).trigger(i.settings.events.outStart).animateCallback(function () {
s.trigger(i.settings.events.outEnd), r.transition(e)
})
}, outOverlay: function (a, o, e) {
var s = this, r = t(this), l = r.data(n).options,
d = r.data(i.settings.data.inClass), u = i.animationCheck.call(s, d, !0, !0);
t(l.overlayParentElement).children("." + l.overlayClass).css({ "animation-duration": o + 1 + "ms" }).removeClass(u).addClass(a).trigger(i.settings.events.outStart).animateCallback(function () {
r.trigger(i.settings.events.outEnd), l.transition(e) })
}, destroy: function () {
return this.each(function () {
var i = t(this); t(window).off("." + n), i.css({ opacity: 1 }).removeData(n)
})
}
};
t.fn.animateCallback = function (n) {
var i = "animationend webkitAnimationEnd";
return this.each(function () {
var a = t(this); a.on(i, function () { return a.off(i), n.call(this) })
})
},
t.fn.animsition = function (a) {
return i[a] ? i[a].apply(this, Array.prototype.slice.call(arguments, 1)) : "object" != typeof a && a ? void t.error("Method " + a + " does not exist on jQuery." + n) : i.init.apply(this, arguments)
}
});

File diff suppressed because one or more lines are too long

View File

@ -66,7 +66,12 @@ class AnnouncementsController < ApplicationController
end
# anns = anns.concat(feeds_anns)
# total_pages = announcements.total_pages
params = OrbitHelper.params
page = Page.where(url:params['url']).first
@annc_page_title = nil
if params['category'] != page.categories
@annc_page_title = Category.find(Array(params['category']).first).title rescue nil
end
{
"announcements" => anns,
@ -82,7 +87,8 @@ class AnnouncementsController < ApplicationController
"file-head" => t('announcement.table.file'),
"view-count-head" => t('announcement.table.view_count'),
"display" => display,
"department-head" => t('announcement.table.department')
"department-head" => t('announcement.table.department'),
"page-title" => @annc_page_title
},
"total_pages" => total_pages
}
@ -126,15 +132,183 @@ class AnnouncementsController < ApplicationController
end
def pack_data(is_random=false)
tags = OrbitHelper.widget_tags || []
cats = OrbitHelper.widget_categories || []
subpart = OrbitHelper.get_current_widget
anns_cache = AnnsCache.where(parent_id: subpart.id.to_s,locale: I18n.locale.to_s)
get_tabs_option
anns = []
if @tab_option == 0
anns = get_anncs_for_pack_data(cats,is_random)
else
cats.each do |cat|
anns = anns + get_anncs_for_pack_data([cat])
end
end
mp = (anns[0]["img_src"] rescue "")
mpd = (anns[0]["img_description"] rescue "")
if @tab_option == 1
cats = ["all"] + cats
anns = anns.sort{|v1,v2| v2["postdate"]<=>v1["postdate"]}
end
cats = cats.uniq
cats_translations = cats.map{|cat_id|
if cat_id == "all"
t = I18n.t(:all)
else
t = Category.find(cat_id).title rescue ""
end
[cat_id,t]
}.to_h
cats_relations = cats_translations.map{|cat_id,t|
if cat_id == "all"
t = "all"
end
[cat_id,t]
}.to_h
page = Page.where(:page_id=> subpart.read_more_page_id).first rescue nil
page = Page.where(:module => "announcement").first rescue nil if page.nil?
if @tab_option != 0
OrbitHelper.set_widget_title(OrbitHelper.widget_title +
"<div style=\"clear: both;\"></div>" +
"<ul class=\"nav_tabs_filter\">" +
cats.map.with_index{|cat,i|
read_more_url = "/#{I18n.locale.to_s + page.url}" rescue ""
read_more_url = read_more_url + "?" + {"category"=>cat}.to_param if read_more_url != ""
"<li class=\"filter_tab#{i == 0 ? ' active' : ''}\" data-read_more=\"#{read_more_url}\" data-category=\"#{cats_relations[cat]}\">#{cats_translations[cat]}</li>"
}.join("") +
"</ul>"
)
extra_html = '
<script>
if(typeof(wpexAnimsition) == "undefined"){
var wpexAnimsition = {
"loading":"1",
"inDuration":"400",
"outDuration":"400",
"inClass":"fade-in",
"outClass":"fade-out",
"linkElement": "[data-list=\"announcements\"] > *",
"children_text_block": ".w-annc__content-wrap",
"container_block": "[data-subpart-id=\"'+subpart.id.to_s+'\"] [data-list=\"announcements\"]",
"parent_block": "[data-subpart-id=\"'+subpart.id.to_s+'\"]",
"filter_bar": ".nav_tabs_filter",
"filter_option": "li.filter_tab",
"filter_attr": "data-category",
"filter_target_attr": "class",
"use_attr_filter": true,
"equal_height": false
};
}else{
wpexAnimsition.parent_block = wpexAnimsition.parent_block + ", [data-subpart-id=\"'+subpart.id.to_s+'\"]";
wpexAnimsition.container_block = wpexAnimsition.container_block + ", [data-subpart-id=\"'+subpart.id.to_s+'\"] [data-list=\"announcements\"]";
}
var wpexLocalize = {
"lightboxType": "iLightbox",
"iLightbox": { "auto": false, "skin": "minimal", "path": "horizontal",
"infinite": false, "maxScale": 1, "minScale": 0, "width": 1400, "height": "",
"slideshow": { "pauseTime": 3000, "startPaused": true },
"effects": { "reposition": true, "repositionSpeed": 200, "switchSpeed": 300,
"loadedFadeSpeed": 50, "fadeSpeed": 500
},
"show": { "title": true, "speed": 200 },
"hide": { "speed": 200 },
"overlay": { "blur": true, "opacity": "0.9" },
"slideShow": "Slideshow", "next": "Next", "previous": "Previous" ,
"thumbnails": { "maxWidth": 120, "maxHeight": 80 }
}
};
$(document).ready(function(){
var first_filter_tab = $("[data-subpart-id=\"'+subpart.id.to_s+'\"] .filter_tab").eq(0);
var read_more_url = first_filter_tab.data("read_more");
if(read_more_url.length != 0)
$("[data-subpart-id=\"'+subpart.id.to_s+'\"] .w-annc__more").attr("href",read_more_url)
$("[data-subpart-id=\"'+subpart.id.to_s+'\"] .filter_tab").click(function(){
var read_more_url = $(this).data("read_more");
if(read_more_url.length != 0)
$("[data-subpart-id=\"'+subpart.id.to_s+'\"] .w-annc__more").attr("href",read_more_url)
})
})
</script>
<script src="/assets/bulletin/wpex.min.js"></script>
<style>
.filter_tab {
float: left;
list-style: none;
margin-right: 0.5em;
background: #bcbcbc;
font-size: 0.8em;
padding: 0.3em;
cursor: pointer;
}
li.filter_tab.active {
background: transparent;
color: #555;
border: 0.1em solid #ddd;
border-bottom-color: transparent;
}
.nav_tabs_filter{
display: inline-block;
padding-left: 0.625em;
}
[data-list="announcements"] {
position: relative;
}
</style>
'
else
extra_html = ""
end
{
"announcements" => anns,
"extras" => {
"more_url"=>OrbitHelper.widget_more_url,
"main_picture" => mp,
"main_picture_description" => mpd,
"title-head" => t('announcement.table.title'),
"date-head" => t('announcement.table.date'),
"author-head" => t('announcement.table.author'),
"status-head" => t('announcement.table.status'),
"subtitle-head" => t('announcement.table.sub_title'),
"category-head" => t('announcement.table.category'),
"link-head" => t('announcement.table.link'),
"file-head" => t('announcement.table.file'),
"read_more" => ("/#{I18n.locale.to_s + page.url}" rescue ""),
"read_more_text" => "read more",
"extra_brefore_html" => extra_html
}
}
end
def get_tabs_option
subpart = OrbitHelper.get_current_widget
tab_options = ["not_enable_tabs","enable_tabs_with_categories_include_all","enable_tabs_with_categories"]
@tab_option = 0
if subpart.methods.include? 'select_options'.to_sym
ModuleApp.all.select{|tmp| tmp.key.to_s=='announcement'}.each do |modile_app|
@show_options = modile_app.show_options rescue nil
end
subpart.select_options.each do |select_option|
if !(@show_options.nil?) && select_option.field_name == @show_options.keys[1].to_s
value = YAML.load(select_option.value)
tmp = value[:en]
I18n.with_locale(:en) do
tab_options.each_with_index do |option,i|
if tmp == t("announcement.#{option}")
@tab_option = i
break
end
end
end
end
end
end
end
def get_anncs_for_pack_data(cats,is_random = false)
tags = OrbitHelper.widget_tags || []
subpart = OrbitHelper.get_current_widget
anns_cache = AnnsCache.where(parent_id: subpart.id.to_s + cats.to_s,locale: I18n.locale.to_s)
widget_data_count = OrbitHelper.widget_data_count
set_image_version_for_widget()
devide_flag = (!(defined? SiteFeed).nil?)
if anns_cache.count != 1 || is_random
page = Page.where(:module => "announcement").first rescue nil
Bulletin.remove_expired_status
uid = OrbitHelper.params[:uid] rescue ""
sorted_anns = Bulletin.where(:title.nin => ["",nil],:is_preview.in=>[false,nil], :uid.ne => uid)
@ -149,10 +323,10 @@ class AnnouncementsController < ApplicationController
now_anns = sorted_anns.to_a
top_anns = now_anns.select{|v| v.is_top}.map{|v| data_to_human_type(v)}
not_top_anns = now_anns.select{|v| !v.is_top}.map{|v| data_to_human_type(v)}
AnnsCache.create(parent_id: subpart.id.to_s,locale: I18n.locale.to_s,filter_result: {top: top_anns,not_top: not_top_anns})
AnnsCache.create(parent_id: subpart.id.to_s + cats.to_s,locale: I18n.locale.to_s,filter_result: {top: top_anns,not_top: not_top_anns})
else
anns = sorted_anns.map{|v| data_to_human_type(v)}
AnnsCache.create(parent_id: subpart.id.to_s,locale: I18n.locale.to_s,filter_result: anns)
AnnsCache.create(parent_id: subpart.id.to_s + cats.to_s,locale: I18n.locale.to_s,filter_result: anns)
end
else
if devide_flag
@ -184,25 +358,7 @@ class AnnouncementsController < ApplicationController
end
end
anns.each{|a| a["postdate"] = a["postdate"].in_time_zone(Time.zone.utc_offset / 3600).strftime('%Y-%m-%d %H:%M') rescue nil }
mp = (anns[0]["img_src"] rescue "")
mpd = (anns[0]["img_description"] rescue "")
{
"announcements" => anns,
"extras" => {
"more_url"=>OrbitHelper.widget_more_url,
"main_picture" => mp,
"main_picture_description" => mpd,
"title-head" => t('announcement.table.title'),
"date-head" => t('announcement.table.date'),
"author-head" => t('announcement.table.author'),
"status-head" => t('announcement.table.status'),
"subtitle-head" => t('announcement.table.sub_title'),
"category-head" => t('announcement.table.category'),
"link-head" => t('announcement.table.link'),
"file-head" => t('announcement.table.file'),
"read_more" => ("/#{I18n.locale.to_s + page.url}" rescue "")
}
}
anns
end
def get_file
@url = request.path

View File

@ -9,7 +9,7 @@ class Bulletin
include OrbitCategory::Categorizable
include Slug
require 'bulletin_model/cache'
include BulletinModel::Cache
include ::BulletinModel::Cache
attr_accessor :org_tag_ids
def tags=(ids)
self.org_tag_ids = self.tag_ids

View File

@ -3,6 +3,10 @@ en:
feed: Feed
import: Import
announcement:
tabs_options: Tabs options
not_enable_tabs: Not enable tabs
enable_tabs_with_categories_include_all: Enable tabs with categories(include all)
enable_tabs_with_categories: Enable tabs with categories
time: Time
send_comment: Send Comment
comment: Comment

View File

@ -3,6 +3,10 @@ zh_tw:
feed: 供給
import: 匯入
announcement:
tabs_options: 頁籤選項
not_enable_tabs: 無頁籤
enable_tabs_with_categories_include_all: 開啟頁籤(依類別,並包含全部所選類別之頁籤)
enable_tabs_with_categories: 開啟頁籤(依類別)
time: 時間
send_comment: 送出留言
comment: 留言內容

View File

@ -6,12 +6,17 @@ module Announcement
translate_data = Dir["#{Announcement::Engine.root}/config/locales/*.yml"] .map{|yaml_file| YAML.load(File.read(yaml_file))}
data = {}
key1 = {}
key2 = {}
value1 = {}
value2 = {}
value3 = {}
value4 = {}
value5 = {}
value6 = {}
data_item = {}
key_item1 = {}
key_item2 = {}
key_item3 = {}
value_item1 = {}
value_item2 = {}
value_item3 = {}
@ -21,9 +26,13 @@ module Announcement
v = t_data.values
k = t_data.keys[0]
key1[k] = v[0]['announcement']['picture_showing_size']
key2[k] = v[0]['announcement']['tabs_options']
value1[k] = v[0]['announcement']['small_size']
value2[k] = v[0]['announcement']['medium_size']
value3[k] = v[0]['announcement']['orignal_size']
value4[k] = v[0]['announcement']['not_enable_tabs']
value5[k] = v[0]['announcement']['enable_tabs_with_categories_include_all']
value6[k] = v[0]['announcement']['enable_tabs_with_categories']
key_item1[k] = v[0]['announcement']['showing_back_and_next']
key_item2[k] = v[0]['announcement']['enable_search']
value_item1[k] = v[0]['announcement']['not_show']
@ -33,6 +42,7 @@ module Announcement
value2_item2[k] = v[0]['announcement']['yes']
end
data[key1] = [value1,value2,value3]
data[key2] = [value4,value5,value6]
data_item[key_item1] = [value_item1,value_item2,value_item3]
data_item[key_item2] = [value2_item1,value2_item2]
require File.expand_path('../../../app/models/anns_cache', __FILE__)

View File

@ -0,0 +1,47 @@
<div class="w-annc widget-announcement-16">
<h3 class="w-annc__widget-title">
<span>{{widget-title}}</span>
</h3>
<div class="slide-button">
<button class="cycle-prev btn btn-warning"> <i class="fa fa-angle-left"></i></button>
<button class="cycle-next btn btn-warning"> <i class="fa fa-angle-right"></i></button>
<a class="w-annc__more btn btn-primary pull-right" href="{{more_url}}"><%= (I18n.locale.to_s =="zh_tw") ? "更多+" : "More NEWS" %></a>
</div>
<div class="w-annc__wrap cycle-slideshow"
data-level="0"
data-list="announcements"
data-cycle-slides=".w-annc__item"
data-cycle-fx="carousel"
data-cycle-carousel-fluid=true
data-cycle-pause-on-hover="true"
data-cycle-speed="200"
data-cycle-carousel-visible="1"
data-cycle-prev=".cycle-prev"
data-cycle-next=".cycle-next"
data-cycle-swipe=true
data-cycle-swipe-fx="carousel"
>
<div class="w-annc__item">
<div class="w-annc__img-wrap">
<img class="w-annc__img" src="{{img_src}}" alt="{{img_description}}" title="{{img_description}}">
</div>
<div class="w-annc__content-wrap">
<div class="w-annc__meta">
<span class="w-annc__status-wrap" data-list="statuses" data-level="1">
<span class="w-annc__status label {{status-class}}">{{status}}</span>
</span>
<span class="w-annc__postdate-wrap" date-format="%Y-%m-%d">
<span class="w-annc__postdate">{{postdate}}</span>
</span>
</div>
<h4 class="w-annc__entry-title">
<a class="w-annc__title" href="{{link_to_show}}">{{title}}</a>
</h4>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,31 @@
<div class="w-annc widget-announcement-17">
<div class="search_block">
<p>Search</p>
<form accept-charset="UTF-8" action="{{more_url}}" method="get"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓"></div>
<p>
<input id="search_query" name="keywords" placeholder="搜尋" type="text">
<input type="submit" value="搜尋">
</p>
</form>
</div>
<h3 class="w-annc__widget-title">
<span>{{widget-title}}</span>
</h3>
<ul class="w-annc__list" data-level="0" data-list="announcements">
<li class="w-annc__item row">
<span class="w-annc__postdate-wrap col-sm-3" date-format="%Y-%m-%d">
<i class="fa fa-calendar-o"></i>
<span class="w-annc__postdate">{{postdate}}</span>
</span>
<h4 class="w-annc__entry-title col-sm-9">
<span class="w-annc__status-wrap" data-list="statuses" data-level="1">
<span class="w-annc__status label status {{status-class}}">{{status}}</span>
</span>
<a class="w-annc__title" href="{{link_to_show}}">{{title}}</a>
</h4>
</li>
</ul>
<div class="w-annc__more-wrap clearfix">
<a class="w-annc__more btn btn-primary pull-right" href="{{more_url}}"><%= (I18n.locale.to_s =="zh_tw") ? "更多最新消息" : "More NEWS" %></a>
</div>
</div>

View File

@ -0,0 +1,86 @@
<div class="w-annc widget-announcement-18">
<div class="w-annc__more-wrap clearfix">
<h2 class="w-annc__widget-title">
<span>{{widget-title}}</span>
</h2>
<a class="w-annc__more btn btn-primary pull-right" href="{{more_url}}"><%= (I18n.locale.to_s =="zh_tw") ? "更多最新消息" : "More NEWS" %></a>
</div>
<ul class="w-annc__list row" data-level="0" data-list="announcements">
<li class="w-annc__item col-md-4">
<div class="w-annc__img-wrap">
<a href="{{link_to_show}}" title="{{title}}">
<img class="w-annc__img" src="{{img_src}}" alt="{{img_description}}" title="{{img_description}}">
</a>
</div>
<div class="w-annc__content-wrap">
<h4 class="w-annc__entry-title">
<a class="w-annc__title" href="{{link_to_show}}">{{title}}</a>
</h4>
<div class="w-annc__subtitle">{{subtitle}}</div>
<div class="w-annc_read_more"><a href="{{link_to_show}}" title="{{title}}">{{read_more_text}}</a></div>
</div>
</li>
</ul>
</div>
<style type="text/css">
.widget-announcement-18 [data-list="announcements"] li > *{
background: #ffffff;
width: 100%;
float: left;
}
.widget-announcement-18 [data-list="announcements"] .w-annc__img{
width: 100%;
}
.widget-announcement-18 [data-list="announcements"] .w-annc__content-wrap{
padding: 0 1em;
}
.widget-announcement-18 .w-annc__title {
line-height: 1.3;
font-size: 1.2rem;
}
.widget-announcement-18 .w-annc__widget-title {
float: left;
}
.widget-announcement-18 .w-annc__more {
margin-top: 1.5em;
}
.widget-announcement-18 .w-annc__list > .w-annc__item:nth-child(3n+1) {
clear: both;
}
.widget-announcement-18 li.w-annc__item{
float: left;
}
.widget-announcement-18 .w-annc__img-wrap {
padding: 0 0 1em 0;
}
.w-annc_read_more{
display: inline-block;
padding: 1em;
}
.w-annc_read_more a{
float: left;
background: #4a97c2;
color: #ffffff;
padding: 0 0.5em;
border-radius: 0.3em;
border: 0.5em solid #4a97c2;
}
.w-annc__subtitle {
padding-bottom: 0.3em;
}
.w-annc_read_more a:hover{
background: #327397;
border: 0.5em solid #327397;
}
</style>
<script type="text/javascript">
$(document).ready(function(){
$("[data-subpart-id=\"{{subpart-id}}\"] .w-annc__subtitle").each(function(i,v){
var subtitle = $(v).text();
if(subtitle.length > 15){
$(v).text(subtitle.slice(0,15) + "...");
}
})
})
</script>

View File

@ -257,6 +257,30 @@
"en" : "14. 1 Image + Title List (widget-title, image, status, title, postdate)"
},
"thumbnail" : "annc_widget14_thumbs.png"
},
{
"filename" : "annc_widget18",
"name" : {
"zh_tw" : "15. 三欄圖文精簡版 ( 模組標題, 標題, 副標題(只顯示15字) )",
"en" : "15. 3-Column Standard Image + Text Lite (widget-title, title, subtitle(only display 15 words))"
},
"thumbnail" : "annc_widget4_thumbs.png"
},
{
"filename" : "annc_widget16",
"name" : {
"zh_tw" : "16. 單欄圖文輪播 ( 模組標題, 圖片, 狀態, 日期, 類別, 標題 )",
"en" : "16. Image + Text slide (widget-title, image, status, postdate, category, title)"
},
"thumbnail" : "annc_widget1_thumbs.png"
},
{
"filename" : "annc_widget17",
"name" : {
"zh_tw" : "17. 含搜尋功能之精簡標題列表-2 ( 模組標題, 日期, 狀態, 標題 )",
"en" : "17. Simple Title List-2 (widget-title, postdate, status, title), including search"
},
"thumbnail" : "annc_widget11_thumbs.png"
}
]
}