nisetegami 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/app/assets/javascripts/nisetegami/application.js +15 -0
- data/app/assets/javascripts/nisetegami/nisetegami.bootstrap.min.js +7 -0
- data/app/assets/javascripts/nisetegami/templates.js.coffee +18 -0
- data/app/assets/stylesheets/nisetegami/application.css.scss +4 -0
- data/app/assets/stylesheets/nisetegami/nisetegami.bootstrap.min.css +363 -0
- data/app/assets/stylesheets/nisetegami/templates.css.scss +19 -0
- data/app/controllers/nisetegami/application_controller.rb +4 -0
- data/app/controllers/nisetegami/templates_controller.rb +52 -0
- data/app/models/nisetegami/template.rb +15 -6
- data/app/views/layouts/nisetegami/application.html.erb +27 -0
- data/app/views/nisetegami/templates/_delete_button.html.erb +5 -0
- data/app/views/nisetegami/templates/_edit_form_buttons.html.erb +3 -0
- data/app/views/nisetegami/templates/_field.html.erb +6 -0
- data/app/views/nisetegami/templates/_filters.html.erb +35 -0
- data/app/views/nisetegami/templates/_test_mail.html.erb +26 -0
- data/app/views/nisetegami/templates/_var.html.erb +4 -0
- data/app/views/nisetegami/templates/edit.html.erb +36 -0
- data/app/views/nisetegami/templates/index.html.erb +42 -0
- data/config/locales/nisetegami.en.yml +56 -0
- data/config/locales/nisetegami.ru.yml +56 -0
- data/config/routes.rb +6 -0
- data/lib/nisetegami.rb +5 -0
- data/lib/nisetegami/action_mailer_extensions.rb +4 -6
- data/lib/nisetegami/engine.rb +0 -2
- data/lib/nisetegami/mapping.rb +8 -8
- data/lib/nisetegami/railtie.rb +9 -0
- data/lib/nisetegami/template_presenter.rb +34 -0
- data/lib/nisetegami/version.rb +1 -1
- data/lib/tasks/nisetegami_tasks.rake +8 -4
- metadata +24 -18
@@ -0,0 +1,15 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// the compiled file.
|
9
|
+
//
|
10
|
+
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
|
11
|
+
// GO AFTER THE REQUIRES BELOW.
|
12
|
+
//
|
13
|
+
//= require jquery
|
14
|
+
//= require jquery_ujs
|
15
|
+
//= require_tree .
|
@@ -0,0 +1,7 @@
|
|
1
|
+
/**
|
2
|
+
* Bootstrap.js by @fat & @mdo
|
3
|
+
* plugins: bootstrap-alert.js
|
4
|
+
* Copyright 2012 Twitter, Inc.
|
5
|
+
* http://www.apache.org/licenses/LICENSE-2.0.txt
|
6
|
+
*/
|
7
|
+
!function(a){var b='[data-dismiss="alert"]',c=function(c){a(c).on("click",b,this.close)};c.prototype.close=function(b){function f(){e.trigger("closed").remove()}var c=a(this),d=c.attr("data-target"),e;d||(d=c.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),e=a(d),b&&b.preventDefault(),e.length||(e=c.hasClass("alert")?c:c.parent()),e.trigger(b=a.Event("close"));if(b.isDefaultPrevented())return;e.removeClass("in"),a.support.transition&&e.hasClass("fade")?e.on(a.support.transition.end,f):f()},a.fn.alert=function(b){return this.each(function(){var d=a(this),e=d.data("alert");e||d.data("alert",e=new c(this)),typeof b=="string"&&e[b].call(d)})},a.fn.alert.Constructor=c,a(document).on("click.alert.data-api",b,c.prototype.close)}(window.jQuery)
|
@@ -0,0 +1,18 @@
|
|
1
|
+
jQuery ->
|
2
|
+
$('button.reset').on 'click', (event) ->
|
3
|
+
event.preventDefault()
|
4
|
+
$(@).closest('form').find('input, select').not(':input[type=submit]').val('')
|
5
|
+
$('#mailer_action').text('')
|
6
|
+
|
7
|
+
$('#mailer').on 'change', (event) ->
|
8
|
+
mailer = $(@).val()
|
9
|
+
actionSelect = $('#mailer_action')
|
10
|
+
if mailer != ''
|
11
|
+
loc = window.location
|
12
|
+
port = unless loc.port == 80 then ":#{loc.port}" else ''
|
13
|
+
$.post "#{loc.protocol}//#{loc.hostname}#{port}#{loc.pathname}actions", mailer: mailer, (data) ->
|
14
|
+
console.log data
|
15
|
+
actionSelect.append($('<option></option>').val(action).text(action)) for action in data
|
16
|
+
else
|
17
|
+
actionSelect.text('')
|
18
|
+
|
@@ -0,0 +1,363 @@
|
|
1
|
+
/*!
|
2
|
+
* Bootstrap v2.2.1
|
3
|
+
*
|
4
|
+
* Copyright 2012 Twitter, Inc
|
5
|
+
* Licensed under the Apache License v2.0
|
6
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
7
|
+
*
|
8
|
+
* Designed and built with all the love in the world @twitter by @mdo and @fat.
|
9
|
+
*/
|
10
|
+
.clearfix{*zoom:1;}.clearfix:before,.clearfix:after{display:table;content:"";line-height:0;}
|
11
|
+
.clearfix:after{clear:both;}
|
12
|
+
.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0;}
|
13
|
+
.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;}
|
14
|
+
article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block;}
|
15
|
+
audio,canvas,video{display:inline-block;*display:inline;*zoom:1;}
|
16
|
+
audio:not([controls]){display:none;}
|
17
|
+
html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;}
|
18
|
+
a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;}
|
19
|
+
a:hover,a:active{outline:0;}
|
20
|
+
sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline;}
|
21
|
+
sup{top:-0.5em;}
|
22
|
+
sub{bottom:-0.25em;}
|
23
|
+
img{max-width:100%;width:auto\9;height:auto;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic;}
|
24
|
+
#map_canvas img,.google-maps img{max-width:none;}
|
25
|
+
button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle;}
|
26
|
+
button,input{*overflow:visible;line-height:normal;}
|
27
|
+
button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0;}
|
28
|
+
button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;}
|
29
|
+
input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield;}
|
30
|
+
input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none;}
|
31
|
+
textarea{overflow:auto;vertical-align:top;}
|
32
|
+
body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:20px;color:#333333;background-color:#ffffff;}
|
33
|
+
a{color:#0088cc;text-decoration:none;}
|
34
|
+
a:hover{color:#005580;text-decoration:underline;}
|
35
|
+
.img-rounded{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;}
|
36
|
+
.img-polaroid{padding:4px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0, 0, 0, 0.2);-webkit-box-shadow:0 1px 3px rgba(0, 0, 0, 0.1);-moz-box-shadow:0 1px 3px rgba(0, 0, 0, 0.1);box-shadow:0 1px 3px rgba(0, 0, 0, 0.1);}
|
37
|
+
.img-circle{-webkit-border-radius:500px;-moz-border-radius:500px;border-radius:500px;}
|
38
|
+
.row{margin-left:-20px;*zoom:1;}.row:before,.row:after{display:table;content:"";line-height:0;}
|
39
|
+
.row:after{clear:both;}
|
40
|
+
[class*="span"]{float:left;min-height:1px;margin-left:20px;}
|
41
|
+
.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px;}
|
42
|
+
.span12{width:940px;}
|
43
|
+
.span11{width:860px;}
|
44
|
+
.span10{width:780px;}
|
45
|
+
.span9{width:700px;}
|
46
|
+
.span8{width:620px;}
|
47
|
+
.span7{width:540px;}
|
48
|
+
.span6{width:460px;}
|
49
|
+
.span5{width:380px;}
|
50
|
+
.span4{width:300px;}
|
51
|
+
.span3{width:220px;}
|
52
|
+
.span2{width:140px;}
|
53
|
+
.span1{width:60px;}
|
54
|
+
.offset12{margin-left:980px;}
|
55
|
+
.offset11{margin-left:900px;}
|
56
|
+
.offset10{margin-left:820px;}
|
57
|
+
.offset9{margin-left:740px;}
|
58
|
+
.offset8{margin-left:660px;}
|
59
|
+
.offset7{margin-left:580px;}
|
60
|
+
.offset6{margin-left:500px;}
|
61
|
+
.offset5{margin-left:420px;}
|
62
|
+
.offset4{margin-left:340px;}
|
63
|
+
.offset3{margin-left:260px;}
|
64
|
+
.offset2{margin-left:180px;}
|
65
|
+
.offset1{margin-left:100px;}
|
66
|
+
.row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0;}
|
67
|
+
.row-fluid:after{clear:both;}
|
68
|
+
.row-fluid [class*="span"]{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;}
|
69
|
+
.row-fluid [class*="span"]:first-child{margin-left:0;}
|
70
|
+
.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.127659574468085%;}
|
71
|
+
.row-fluid .span12{width:100%;*width:99.94680851063829%;}
|
72
|
+
.row-fluid .span11{width:91.48936170212765%;*width:91.43617021276594%;}
|
73
|
+
.row-fluid .span10{width:82.97872340425532%;*width:82.92553191489361%;}
|
74
|
+
.row-fluid .span9{width:74.46808510638297%;*width:74.41489361702126%;}
|
75
|
+
.row-fluid .span8{width:65.95744680851064%;*width:65.90425531914893%;}
|
76
|
+
.row-fluid .span7{width:57.44680851063829%;*width:57.39361702127659%;}
|
77
|
+
.row-fluid .span6{width:48.93617021276595%;*width:48.88297872340425%;}
|
78
|
+
.row-fluid .span5{width:40.42553191489362%;*width:40.37234042553192%;}
|
79
|
+
.row-fluid .span4{width:31.914893617021278%;*width:31.861702127659576%;}
|
80
|
+
.row-fluid .span3{width:23.404255319148934%;*width:23.351063829787233%;}
|
81
|
+
.row-fluid .span2{width:14.893617021276595%;*width:14.840425531914894%;}
|
82
|
+
.row-fluid .span1{width:6.382978723404255%;*width:6.329787234042553%;}
|
83
|
+
.row-fluid .offset12{margin-left:104.25531914893617%;*margin-left:104.14893617021275%;}
|
84
|
+
.row-fluid .offset12:first-child{margin-left:102.12765957446808%;*margin-left:102.02127659574467%;}
|
85
|
+
.row-fluid .offset11{margin-left:95.74468085106382%;*margin-left:95.6382978723404%;}
|
86
|
+
.row-fluid .offset11:first-child{margin-left:93.61702127659574%;*margin-left:93.51063829787232%;}
|
87
|
+
.row-fluid .offset10{margin-left:87.23404255319149%;*margin-left:87.12765957446807%;}
|
88
|
+
.row-fluid .offset10:first-child{margin-left:85.1063829787234%;*margin-left:84.99999999999999%;}
|
89
|
+
.row-fluid .offset9{margin-left:78.72340425531914%;*margin-left:78.61702127659572%;}
|
90
|
+
.row-fluid .offset9:first-child{margin-left:76.59574468085106%;*margin-left:76.48936170212764%;}
|
91
|
+
.row-fluid .offset8{margin-left:70.2127659574468%;*margin-left:70.10638297872339%;}
|
92
|
+
.row-fluid .offset8:first-child{margin-left:68.08510638297872%;*margin-left:67.9787234042553%;}
|
93
|
+
.row-fluid .offset7{margin-left:61.70212765957446%;*margin-left:61.59574468085106%;}
|
94
|
+
.row-fluid .offset7:first-child{margin-left:59.574468085106375%;*margin-left:59.46808510638297%;}
|
95
|
+
.row-fluid .offset6{margin-left:53.191489361702125%;*margin-left:53.085106382978715%;}
|
96
|
+
.row-fluid .offset6:first-child{margin-left:51.063829787234035%;*margin-left:50.95744680851063%;}
|
97
|
+
.row-fluid .offset5{margin-left:44.68085106382979%;*margin-left:44.57446808510638%;}
|
98
|
+
.row-fluid .offset5:first-child{margin-left:42.5531914893617%;*margin-left:42.4468085106383%;}
|
99
|
+
.row-fluid .offset4{margin-left:36.170212765957444%;*margin-left:36.06382978723405%;}
|
100
|
+
.row-fluid .offset4:first-child{margin-left:34.04255319148936%;*margin-left:33.93617021276596%;}
|
101
|
+
.row-fluid .offset3{margin-left:27.659574468085104%;*margin-left:27.5531914893617%;}
|
102
|
+
.row-fluid .offset3:first-child{margin-left:25.53191489361702%;*margin-left:25.425531914893618%;}
|
103
|
+
.row-fluid .offset2{margin-left:19.148936170212764%;*margin-left:19.04255319148936%;}
|
104
|
+
.row-fluid .offset2:first-child{margin-left:17.02127659574468%;*margin-left:16.914893617021278%;}
|
105
|
+
.row-fluid .offset1{margin-left:10.638297872340425%;*margin-left:10.53191489361702%;}
|
106
|
+
.row-fluid .offset1:first-child{margin-left:8.51063829787234%;*margin-left:8.404255319148938%;}
|
107
|
+
[class*="span"].hide,.row-fluid [class*="span"].hide{display:none;}
|
108
|
+
[class*="span"].pull-right,.row-fluid [class*="span"].pull-right{float:right;}
|
109
|
+
.container{margin-right:auto;margin-left:auto;*zoom:1;}.container:before,.container:after{display:table;content:"";line-height:0;}
|
110
|
+
.container:after{clear:both;}
|
111
|
+
.container-fluid{padding-right:20px;padding-left:20px;*zoom:1;}.container-fluid:before,.container-fluid:after{display:table;content:"";line-height:0;}
|
112
|
+
.container-fluid:after{clear:both;}
|
113
|
+
p{margin:0 0 10px;}
|
114
|
+
.lead{margin-bottom:20px;font-size:21px;font-weight:200;line-height:30px;}
|
115
|
+
small{font-size:85%;}
|
116
|
+
strong{font-weight:bold;}
|
117
|
+
em{font-style:italic;}
|
118
|
+
cite{font-style:normal;}
|
119
|
+
.muted{color:#999999;}
|
120
|
+
.text-warning{color:#c09853;}
|
121
|
+
a.text-warning:hover{color:#a47e3c;}
|
122
|
+
.text-error{color:#b94a48;}
|
123
|
+
a.text-error:hover{color:#953b39;}
|
124
|
+
.text-info{color:#3a87ad;}
|
125
|
+
a.text-info:hover{color:#2d6987;}
|
126
|
+
.text-success{color:#468847;}
|
127
|
+
a.text-success:hover{color:#356635;}
|
128
|
+
h1,h2,h3,h4,h5,h6{margin:10px 0;font-family:inherit;font-weight:bold;line-height:20px;color:inherit;text-rendering:optimizelegibility;}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;line-height:1;color:#999999;}
|
129
|
+
h1,h2,h3{line-height:40px;}
|
130
|
+
h1{font-size:38.5px;}
|
131
|
+
h2{font-size:31.5px;}
|
132
|
+
h3{font-size:24.5px;}
|
133
|
+
h4{font-size:17.5px;}
|
134
|
+
h5{font-size:14px;}
|
135
|
+
h6{font-size:11.9px;}
|
136
|
+
h1 small{font-size:24.5px;}
|
137
|
+
h2 small{font-size:17.5px;}
|
138
|
+
h3 small{font-size:14px;}
|
139
|
+
h4 small{font-size:14px;}
|
140
|
+
.page-header{padding-bottom:9px;margin:20px 0 30px;border-bottom:1px solid #eeeeee;}
|
141
|
+
ul,ol{padding:0;margin:0 0 10px 25px;}
|
142
|
+
ul ul,ul ol,ol ol,ol ul{margin-bottom:0;}
|
143
|
+
li{line-height:20px;}
|
144
|
+
ul.unstyled,ol.unstyled{margin-left:0;list-style:none;}
|
145
|
+
dl{margin-bottom:20px;}
|
146
|
+
dt,dd{line-height:20px;}
|
147
|
+
dt{font-weight:bold;}
|
148
|
+
dd{margin-left:10px;}
|
149
|
+
.dl-horizontal{*zoom:1;}.dl-horizontal:before,.dl-horizontal:after{display:table;content:"";line-height:0;}
|
150
|
+
.dl-horizontal:after{clear:both;}
|
151
|
+
.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
|
152
|
+
.dl-horizontal dd{margin-left:180px;}
|
153
|
+
hr{margin:20px 0;border:0;border-top:1px solid #eeeeee;border-bottom:1px solid #ffffff;}
|
154
|
+
abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999999;}
|
155
|
+
abbr.initialism{font-size:90%;text-transform:uppercase;}
|
156
|
+
blockquote{padding:0 0 0 15px;margin:0 0 20px;border-left:5px solid #eeeeee;}blockquote p{margin-bottom:0;font-size:16px;font-weight:300;line-height:25px;}
|
157
|
+
blockquote small{display:block;line-height:20px;color:#999999;}blockquote small:before{content:'\2014 \00A0';}
|
158
|
+
blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eeeeee;border-left:0;}blockquote.pull-right p,blockquote.pull-right small{text-align:right;}
|
159
|
+
blockquote.pull-right small:before{content:'';}
|
160
|
+
blockquote.pull-right small:after{content:'\00A0 \2014';}
|
161
|
+
q:before,q:after,blockquote:before,blockquote:after{content:"";}
|
162
|
+
address{display:block;margin-bottom:20px;font-style:normal;line-height:20px;}
|
163
|
+
table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0;}
|
164
|
+
.table{width:100%;margin-bottom:20px;}.table th,.table td{padding:8px;line-height:20px;text-align:left;vertical-align:top;border-top:1px solid #dddddd;}
|
165
|
+
.table th{font-weight:bold;}
|
166
|
+
.table thead th{vertical-align:bottom;}
|
167
|
+
.table caption+thead tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.table thead:first-child tr:first-child td{border-top:0;}
|
168
|
+
.table tbody+tbody{border-top:2px solid #dddddd;}
|
169
|
+
.table-condensed th,.table-condensed td{padding:4px 5px;}
|
170
|
+
.table-bordered{border:1px solid #dddddd;border-collapse:separate;*border-collapse:collapse;border-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}.table-bordered th,.table-bordered td{border-left:1px solid #dddddd;}
|
171
|
+
.table-bordered caption+thead tr:first-child th,.table-bordered caption+tbody tr:first-child th,.table-bordered caption+tbody tr:first-child td,.table-bordered colgroup+thead tr:first-child th,.table-bordered colgroup+tbody tr:first-child th,.table-bordered colgroup+tbody tr:first-child td,.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0;}
|
172
|
+
.table-bordered thead:first-child tr:first-child th:first-child,.table-bordered tbody:first-child tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px;}
|
173
|
+
.table-bordered thead:first-child tr:first-child th:last-child,.table-bordered tbody:first-child tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px;}
|
174
|
+
.table-bordered thead:last-child tr:last-child th:first-child,.table-bordered tbody:last-child tr:last-child td:first-child,.table-bordered tfoot:last-child tr:last-child td:first-child{-webkit-border-radius:0 0 0 4px;-moz-border-radius:0 0 0 4px;border-radius:0 0 0 4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;}
|
175
|
+
.table-bordered thead:last-child tr:last-child th:last-child,.table-bordered tbody:last-child tr:last-child td:last-child,.table-bordered tfoot:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;}
|
176
|
+
.table-bordered caption+thead tr:first-child th:first-child,.table-bordered caption+tbody tr:first-child td:first-child,.table-bordered colgroup+thead tr:first-child th:first-child,.table-bordered colgroup+tbody tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px;}
|
177
|
+
.table-bordered caption+thead tr:first-child th:last-child,.table-bordered caption+tbody tr:first-child td:last-child,.table-bordered colgroup+thead tr:first-child th:last-child,.table-bordered colgroup+tbody tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px;}
|
178
|
+
.table-striped tbody tr:nth-child(odd) td,.table-striped tbody tr:nth-child(odd) th{background-color:#f9f9f9;}
|
179
|
+
.table-hover tbody tr:hover td,.table-hover tbody tr:hover th{background-color:#f5f5f5;}
|
180
|
+
table td[class*="span"],table th[class*="span"],.row-fluid table td[class*="span"],.row-fluid table th[class*="span"]{display:table-cell;float:none;margin-left:0;}
|
181
|
+
.table td.span1,.table th.span1{float:none;width:44px;margin-left:0;}
|
182
|
+
.table td.span2,.table th.span2{float:none;width:124px;margin-left:0;}
|
183
|
+
.table td.span3,.table th.span3{float:none;width:204px;margin-left:0;}
|
184
|
+
.table td.span4,.table th.span4{float:none;width:284px;margin-left:0;}
|
185
|
+
.table td.span5,.table th.span5{float:none;width:364px;margin-left:0;}
|
186
|
+
.table td.span6,.table th.span6{float:none;width:444px;margin-left:0;}
|
187
|
+
.table td.span7,.table th.span7{float:none;width:524px;margin-left:0;}
|
188
|
+
.table td.span8,.table th.span8{float:none;width:604px;margin-left:0;}
|
189
|
+
.table td.span9,.table th.span9{float:none;width:684px;margin-left:0;}
|
190
|
+
.table td.span10,.table th.span10{float:none;width:764px;margin-left:0;}
|
191
|
+
.table td.span11,.table th.span11{float:none;width:844px;margin-left:0;}
|
192
|
+
.table td.span12,.table th.span12{float:none;width:924px;margin-left:0;}
|
193
|
+
.table tbody tr.success td{background-color:#dff0d8;}
|
194
|
+
.table tbody tr.error td{background-color:#f2dede;}
|
195
|
+
.table tbody tr.warning td{background-color:#fcf8e3;}
|
196
|
+
.table tbody tr.info td{background-color:#d9edf7;}
|
197
|
+
.table-hover tbody tr.success:hover td{background-color:#d0e9c6;}
|
198
|
+
.table-hover tbody tr.error:hover td{background-color:#ebcccc;}
|
199
|
+
.table-hover tbody tr.warning:hover td{background-color:#faf2cc;}
|
200
|
+
.table-hover tbody tr.info:hover td{background-color:#c4e3f3;}
|
201
|
+
form{margin:0 0 20px;}
|
202
|
+
fieldset{padding:0;margin:0;border:0;}
|
203
|
+
legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:40px;color:#333333;border:0;border-bottom:1px solid #e5e5e5;}legend small{font-size:15px;color:#999999;}
|
204
|
+
label,input,button,select,textarea{font-size:14px;font-weight:normal;line-height:20px;}
|
205
|
+
input,button,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;}
|
206
|
+
label{display:block;margin-bottom:5px;}
|
207
|
+
select,textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{display:inline-block;height:20px;padding:4px 6px;margin-bottom:10px;font-size:14px;line-height:20px;color:#555555;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;vertical-align:middle;}
|
208
|
+
input,textarea,.uneditable-input{width:206px;}
|
209
|
+
textarea{height:auto;}
|
210
|
+
textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{background-color:#ffffff;border:1px solid #cccccc;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-webkit-transition:border linear .2s, box-shadow linear .2s;-moz-transition:border linear .2s, box-shadow linear .2s;-o-transition:border linear .2s, box-shadow linear .2s;transition:border linear .2s, box-shadow linear .2s;}textarea:focus,input[type="text"]:focus,input[type="password"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus,.uneditable-input:focus{border-color:rgba(82, 168, 236, 0.8);outline:0;outline:thin dotted \9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6);}
|
211
|
+
input[type="radio"],input[type="checkbox"]{margin:4px 0 0;*margin-top:0;margin-top:1px \9;line-height:normal;cursor:pointer;}
|
212
|
+
input[type="file"],input[type="image"],input[type="submit"],input[type="reset"],input[type="button"],input[type="radio"],input[type="checkbox"]{width:auto;}
|
213
|
+
select,input[type="file"]{height:30px;*margin-top:4px;line-height:30px;}
|
214
|
+
select{width:220px;border:1px solid #cccccc;background-color:#ffffff;}
|
215
|
+
select[multiple],select[size]{height:auto;}
|
216
|
+
select:focus,input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;}
|
217
|
+
.uneditable-input,.uneditable-textarea{color:#999999;background-color:#fcfcfc;border-color:#cccccc;-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);-moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);cursor:not-allowed;}
|
218
|
+
.uneditable-input{overflow:hidden;white-space:nowrap;}
|
219
|
+
.uneditable-textarea{width:auto;height:auto;}
|
220
|
+
input:-moz-placeholder,textarea:-moz-placeholder{color:#999999;}
|
221
|
+
input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999999;}
|
222
|
+
input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999999;}
|
223
|
+
.radio,.checkbox{min-height:20px;padding-left:20px;}
|
224
|
+
.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-20px;}
|
225
|
+
.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px;}
|
226
|
+
.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle;}
|
227
|
+
.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px;}
|
228
|
+
.input-mini{width:60px;}
|
229
|
+
.input-small{width:90px;}
|
230
|
+
.input-medium{width:150px;}
|
231
|
+
.input-large{width:210px;}
|
232
|
+
.input-xlarge{width:270px;}
|
233
|
+
.input-xxlarge{width:530px;}
|
234
|
+
input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"]{float:none;margin-left:0;}
|
235
|
+
.input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"]{display:inline-block;}
|
236
|
+
input,textarea,.uneditable-input{margin-left:0;}
|
237
|
+
.controls-row [class*="span"]+[class*="span"]{margin-left:20px;}
|
238
|
+
input.span12, textarea.span12, .uneditable-input.span12{width:926px;}
|
239
|
+
input.span11, textarea.span11, .uneditable-input.span11{width:846px;}
|
240
|
+
input.span10, textarea.span10, .uneditable-input.span10{width:766px;}
|
241
|
+
input.span9, textarea.span9, .uneditable-input.span9{width:686px;}
|
242
|
+
input.span8, textarea.span8, .uneditable-input.span8{width:606px;}
|
243
|
+
input.span7, textarea.span7, .uneditable-input.span7{width:526px;}
|
244
|
+
input.span6, textarea.span6, .uneditable-input.span6{width:446px;}
|
245
|
+
input.span5, textarea.span5, .uneditable-input.span5{width:366px;}
|
246
|
+
input.span4, textarea.span4, .uneditable-input.span4{width:286px;}
|
247
|
+
input.span3, textarea.span3, .uneditable-input.span3{width:206px;}
|
248
|
+
input.span2, textarea.span2, .uneditable-input.span2{width:126px;}
|
249
|
+
input.span1, textarea.span1, .uneditable-input.span1{width:46px;}
|
250
|
+
.controls-row{*zoom:1;}.controls-row:before,.controls-row:after{display:table;content:"";line-height:0;}
|
251
|
+
.controls-row:after{clear:both;}
|
252
|
+
.controls-row [class*="span"],.row-fluid .controls-row [class*="span"]{float:left;}
|
253
|
+
.controls-row .checkbox[class*="span"],.controls-row .radio[class*="span"]{padding-top:5px;}
|
254
|
+
input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eeeeee;}
|
255
|
+
input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent;}
|
256
|
+
.control-group.warning>label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853;}
|
257
|
+
.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853;}
|
258
|
+
.control-group.warning input,.control-group.warning select,.control-group.warning textarea{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #dbc59e;}
|
259
|
+
.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853;}
|
260
|
+
.control-group.error>label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48;}
|
261
|
+
.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48;}
|
262
|
+
.control-group.error input,.control-group.error select,.control-group.error textarea{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #d59392;}
|
263
|
+
.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48;}
|
264
|
+
.control-group.success>label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847;}
|
265
|
+
.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847;}
|
266
|
+
.control-group.success input,.control-group.success select,.control-group.success textarea{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7aba7b;}
|
267
|
+
.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847;}
|
268
|
+
.control-group.info>label,.control-group.info .help-block,.control-group.info .help-inline{color:#3a87ad;}
|
269
|
+
.control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea{color:#3a87ad;}
|
270
|
+
.control-group.info input,.control-group.info select,.control-group.info textarea{border-color:#3a87ad;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.control-group.info input:focus,.control-group.info select:focus,.control-group.info textarea:focus{border-color:#2d6987;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7ab5d3;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7ab5d3;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7ab5d3;}
|
271
|
+
.control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on{color:#3a87ad;background-color:#d9edf7;border-color:#3a87ad;}
|
272
|
+
input:focus:required:invalid,textarea:focus:required:invalid,select:focus:required:invalid{color:#b94a48;border-color:#ee5f5b;}input:focus:required:invalid:focus,textarea:focus:required:invalid:focus,select:focus:required:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7;}
|
273
|
+
.form-actions{padding:19px 20px 20px;margin-top:20px;margin-bottom:20px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1;}.form-actions:before,.form-actions:after{display:table;content:"";line-height:0;}
|
274
|
+
.form-actions:after{clear:both;}
|
275
|
+
.help-block,.help-inline{color:#595959;}
|
276
|
+
.help-block{display:block;margin-bottom:10px;}
|
277
|
+
.help-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle;padding-left:5px;}
|
278
|
+
.input-append,.input-prepend{margin-bottom:5px;font-size:0;white-space:nowrap;}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input,.input-append .dropdown-menu,.input-prepend .dropdown-menu{font-size:14px;}
|
279
|
+
.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;vertical-align:top;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;}.input-append input:focus,.input-prepend input:focus,.input-append select:focus,.input-prepend select:focus,.input-append .uneditable-input:focus,.input-prepend .uneditable-input:focus{z-index:2;}
|
280
|
+
.input-append .add-on,.input-prepend .add-on{display:inline-block;width:auto;height:20px;min-width:16px;padding:4px 5px;font-size:14px;font-weight:normal;line-height:20px;text-align:center;text-shadow:0 1px 0 #ffffff;background-color:#eeeeee;border:1px solid #ccc;}
|
281
|
+
.input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn{vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}
|
282
|
+
.input-append .active,.input-prepend .active{background-color:#a9dba9;border-color:#46a546;}
|
283
|
+
.input-prepend .add-on,.input-prepend .btn{margin-right:-1px;}
|
284
|
+
.input-prepend .add-on:first-child,.input-prepend .btn:first-child{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;}
|
285
|
+
.input-append input,.input-append select,.input-append .uneditable-input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;}.input-append input+.btn-group .btn,.input-append select+.btn-group .btn,.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;}
|
286
|
+
.input-append .add-on,.input-append .btn,.input-append .btn-group{margin-left:-1px;}
|
287
|
+
.input-append .add-on:last-child,.input-append .btn:last-child{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;}
|
288
|
+
.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}.input-prepend.input-append input+.btn-group .btn,.input-prepend.input-append select+.btn-group .btn,.input-prepend.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;}
|
289
|
+
.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;}
|
290
|
+
.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;}
|
291
|
+
.input-prepend.input-append .btn-group:first-child{margin-left:0;}
|
292
|
+
input.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px;}
|
293
|
+
.form-search .input-append .search-query,.form-search .input-prepend .search-query{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}
|
294
|
+
.form-search .input-append .search-query{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px;}
|
295
|
+
.form-search .input-append .btn{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0;}
|
296
|
+
.form-search .input-prepend .search-query{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0;}
|
297
|
+
.form-search .input-prepend .btn{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px;}
|
298
|
+
.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;*display:inline;*zoom:1;margin-bottom:0;vertical-align:middle;}
|
299
|
+
.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none;}
|
300
|
+
.form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{display:inline-block;}
|
301
|
+
.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0;}
|
302
|
+
.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle;}
|
303
|
+
.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0;}
|
304
|
+
.control-group{margin-bottom:10px;}
|
305
|
+
legend+.control-group{margin-top:20px;-webkit-margin-top-collapse:separate;}
|
306
|
+
.form-horizontal .control-group{margin-bottom:20px;*zoom:1;}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;content:"";line-height:0;}
|
307
|
+
.form-horizontal .control-group:after{clear:both;}
|
308
|
+
.form-horizontal .control-label{float:left;width:160px;padding-top:5px;text-align:right;}
|
309
|
+
.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:180px;*margin-left:0;}.form-horizontal .controls:first-child{*padding-left:180px;}
|
310
|
+
.form-horizontal .help-block{margin-bottom:0;}
|
311
|
+
.form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block{margin-top:10px;}
|
312
|
+
.form-horizontal .form-actions{padding-left:180px;}
|
313
|
+
.btn{display:inline-block;*display:inline;*zoom:1;padding:4px 12px;margin-bottom:0;font-size:14px;line-height:20px;*line-height:20px;text-align:center;vertical-align:middle;cursor:pointer;color:#333333;text-shadow:0 1px 1px rgba(255, 255, 255, 0.75);background-color:#f5f5f5;background-image:-moz-linear-gradient(top, #ffffff, #e6e6e6);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));background-image:-webkit-linear-gradient(top, #ffffff, #e6e6e6);background-image:-o-linear-gradient(top, #ffffff, #e6e6e6);background-image:linear-gradient(to bottom, #ffffff, #e6e6e6);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0);border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#e6e6e6;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);border:1px solid #bbbbbb;*border:0;border-bottom-color:#a2a2a2;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*margin-left:.3em;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);}.btn:hover,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333333;background-color:#e6e6e6;*background-color:#d9d9d9;}
|
314
|
+
.btn:active,.btn.active{background-color:#cccccc \9;}
|
315
|
+
.btn:first-child{*margin-left:0;}
|
316
|
+
.btn:hover{color:#333333;text-decoration:none;background-color:#e6e6e6;*background-color:#d9d9d9;background-position:0 -15px;-webkit-transition:background-position 0.1s linear;-moz-transition:background-position 0.1s linear;-o-transition:background-position 0.1s linear;transition:background-position 0.1s linear;}
|
317
|
+
.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;}
|
318
|
+
.btn.active,.btn:active{background-color:#e6e6e6;background-color:#d9d9d9 \9;background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);}
|
319
|
+
.btn.disabled,.btn[disabled]{cursor:default;background-color:#e6e6e6;background-image:none;opacity:0.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;}
|
320
|
+
.btn-large{padding:11px 19px;font-size:17.5px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;}
|
321
|
+
.btn-large [class^="icon-"],.btn-large [class*=" icon-"]{margin-top:2px;}
|
322
|
+
.btn-small{padding:2px 10px;font-size:11.9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
|
323
|
+
.btn-small [class^="icon-"],.btn-small [class*=" icon-"]{margin-top:0;}
|
324
|
+
.btn-mini{padding:1px 6px;font-size:10.5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
|
325
|
+
.btn-block{display:block;width:100%;padding-left:0;padding-right:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;}
|
326
|
+
.btn-block+.btn-block{margin-top:5px;}
|
327
|
+
input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%;}
|
328
|
+
.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255, 255, 255, 0.75);}
|
329
|
+
.btn{border-color:#c5c5c5;border-color:rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25);}
|
330
|
+
.btn-primary{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#006dcc;background-image:-moz-linear-gradient(top, #0088cc, #0044cc);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));background-image:-webkit-linear-gradient(top, #0088cc, #0044cc);background-image:-o-linear-gradient(top, #0088cc, #0044cc);background-image:linear-gradient(to bottom, #0088cc, #0044cc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0);border-color:#0044cc #0044cc #002a80;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#0044cc;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-primary:hover,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#ffffff;background-color:#0044cc;*background-color:#003bb3;}
|
331
|
+
.btn-primary:active,.btn-primary.active{background-color:#003399 \9;}
|
332
|
+
.btn-warning{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#faa732;background-image:-moz-linear-gradient(top, #fbb450, #f89406);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));background-image:-webkit-linear-gradient(top, #fbb450, #f89406);background-image:-o-linear-gradient(top, #fbb450, #f89406);background-image:linear-gradient(to bottom, #fbb450, #f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0);border-color:#f89406 #f89406 #ad6704;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#f89406;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-warning:hover,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#ffffff;background-color:#f89406;*background-color:#df8505;}
|
333
|
+
.btn-warning:active,.btn-warning.active{background-color:#c67605 \9;}
|
334
|
+
.btn-danger{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#da4f49;background-image:-moz-linear-gradient(top, #ee5f5b, #bd362f);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f));background-image:-webkit-linear-gradient(top, #ee5f5b, #bd362f);background-image:-o-linear-gradient(top, #ee5f5b, #bd362f);background-image:linear-gradient(to bottom, #ee5f5b, #bd362f);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffbd362f', GradientType=0);border-color:#bd362f #bd362f #802420;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#bd362f;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-danger:hover,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#ffffff;background-color:#bd362f;*background-color:#a9302a;}
|
335
|
+
.btn-danger:active,.btn-danger.active{background-color:#942a25 \9;}
|
336
|
+
.btn-success{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#5bb75b;background-image:-moz-linear-gradient(top, #62c462, #51a351);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351));background-image:-webkit-linear-gradient(top, #62c462, #51a351);background-image:-o-linear-gradient(top, #62c462, #51a351);background-image:linear-gradient(to bottom, #62c462, #51a351);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff51a351', GradientType=0);border-color:#51a351 #51a351 #387038;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#51a351;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-success:hover,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#ffffff;background-color:#51a351;*background-color:#499249;}
|
337
|
+
.btn-success:active,.btn-success.active{background-color:#408140 \9;}
|
338
|
+
.btn-info{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#49afcd;background-image:-moz-linear-gradient(top, #5bc0de, #2f96b4);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4));background-image:-webkit-linear-gradient(top, #5bc0de, #2f96b4);background-image:-o-linear-gradient(top, #5bc0de, #2f96b4);background-image:linear-gradient(to bottom, #5bc0de, #2f96b4);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2f96b4', GradientType=0);border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#2f96b4;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-info:hover,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#ffffff;background-color:#2f96b4;*background-color:#2a85a0;}
|
339
|
+
.btn-info:active,.btn-info.active{background-color:#24748c \9;}
|
340
|
+
.btn-inverse{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#363636;background-image:-moz-linear-gradient(top, #444444, #222222);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#444444), to(#222222));background-image:-webkit-linear-gradient(top, #444444, #222222);background-image:-o-linear-gradient(top, #444444, #222222);background-image:linear-gradient(to bottom, #444444, #222222);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444', endColorstr='#ff222222', GradientType=0);border-color:#222222 #222222 #000000;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#222222;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-inverse:hover,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#ffffff;background-color:#222222;*background-color:#151515;}
|
341
|
+
.btn-inverse:active,.btn-inverse.active{background-color:#080808 \9;}
|
342
|
+
button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px;}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0;}
|
343
|
+
button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px;}
|
344
|
+
button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px;}
|
345
|
+
button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px;}
|
346
|
+
.btn-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;}
|
347
|
+
.btn-link{border-color:transparent;cursor:pointer;color:#0088cc;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}
|
348
|
+
.btn-link:hover{color:#005580;text-decoration:underline;background-color:transparent;}
|
349
|
+
.btn-link[disabled]:hover{color:#333333;text-decoration:none;}
|
350
|
+
.alert{padding:8px 35px 8px 14px;margin-bottom:20px;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;color:#c09853;}
|
351
|
+
.alert h4{margin:0;}
|
352
|
+
.alert .close{position:relative;top:-2px;right:-21px;line-height:20px;}
|
353
|
+
.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#468847;}
|
354
|
+
.alert-danger,.alert-error{background-color:#f2dede;border-color:#eed3d7;color:#b94a48;}
|
355
|
+
.alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#3a87ad;}
|
356
|
+
.alert-block{padding-top:14px;padding-bottom:14px;}
|
357
|
+
.alert-block>p,.alert-block>ul{margin-bottom:0;}
|
358
|
+
.alert-block p+p{margin-top:5px;}
|
359
|
+
.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);}.well blockquote{border-color:#ddd;border-color:rgba(0, 0, 0, 0.15);}
|
360
|
+
.well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;}
|
361
|
+
.well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
|
362
|
+
.close{float:right;font-size:20px;font-weight:bold;line-height:20px;color:#000000;text-shadow:0 1px 0 #ffffff;opacity:0.2;filter:alpha(opacity=20);}.close:hover{color:#000000;text-decoration:none;cursor:pointer;opacity:0.4;filter:alpha(opacity=40);}
|
363
|
+
button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none;}
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require_dependency "nisetegami/application_controller"
|
2
|
+
|
3
|
+
module Nisetegami
|
4
|
+
class TemplatesController < ApplicationController
|
5
|
+
def index
|
6
|
+
@templates = Template.recent
|
7
|
+
params[:enabled] = params[:enabled] == 'true' ? true : false unless params[:enabled].blank?
|
8
|
+
%w(enabled mailer mailer_action).each do |attr|
|
9
|
+
@templates = @templates.where((attr == 'mailer_action' ? 'action' : attr) => params[attr]) unless params[attr].blank?
|
10
|
+
end
|
11
|
+
%w(name subject from reply_to cc bcc).each do |attr|
|
12
|
+
@templates = @templates.where(["#{attr} LIKE ?", "%#{params[attr]}%"]) unless params[attr].blank?
|
13
|
+
end
|
14
|
+
@templates = @templates.all
|
15
|
+
end
|
16
|
+
|
17
|
+
def actions
|
18
|
+
render json: [''] + Nisetegami.mapping.actions(params[:mailer])
|
19
|
+
end
|
20
|
+
|
21
|
+
def edit
|
22
|
+
@template = Template.find(params[:id])
|
23
|
+
end
|
24
|
+
|
25
|
+
def update
|
26
|
+
@template = Template.find(params[:id])
|
27
|
+
if @template.update_attributes(params[:template])
|
28
|
+
redirect_to templates_path, notice: t('nisetegami.templates.updated', template: @template.name)
|
29
|
+
else
|
30
|
+
render action: :edit
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def destroy
|
35
|
+
templates = Template.where(id: params[:template_ids])
|
36
|
+
template_names = templates.map(&:name).join(', ')
|
37
|
+
templates.destroy_all
|
38
|
+
redirect_to templates_path, notice: t('nisetegami.templates.destroyed', templates: template_names)
|
39
|
+
end
|
40
|
+
|
41
|
+
def test
|
42
|
+
template = Template.find(params[:id])
|
43
|
+
message = unless params[:recipient] =~ Nisetegami.email_re
|
44
|
+
{alert: t('nisetegami.templates.wrong_email')}
|
45
|
+
else
|
46
|
+
template.message(params[:recipient], params[:template]).deliver
|
47
|
+
{notice: t('nisetegami.templates.test_email_delivered')}
|
48
|
+
end
|
49
|
+
redirect_to edit_template_path(template), message
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
class Nisetegami::Template < ActiveRecord::Base
|
2
2
|
|
3
|
-
|
3
|
+
attr_accessible :name, :mailer, :action, :subject, :from,
|
4
|
+
:reply_to, :cc, :bcc, :enabled, :only_text,
|
5
|
+
:layout_text, :body_text, :layout_html, :body_html
|
4
6
|
|
5
7
|
## constants
|
6
8
|
|
@@ -9,6 +11,7 @@ class Nisetegami::Template < ActiveRecord::Base
|
|
9
11
|
|
10
12
|
## scopes
|
11
13
|
|
14
|
+
scope :recent, order('id DESC')
|
12
15
|
scope :by_mailer, ->(mailer){ where(mailer: mailer.respond_to?(:name) ? mailer.name : mailer) }
|
13
16
|
scope :by_action, ->(action){ where(action: action) }
|
14
17
|
scope :by_layout, ->(layout){ where(layout: layout) }
|
@@ -18,15 +21,19 @@ class Nisetegami::Template < ActiveRecord::Base
|
|
18
21
|
scope :text, where(only_text: true)
|
19
22
|
|
20
23
|
## validations
|
21
|
-
|
22
|
-
address_re = "(?:[^<@]+\\s+<#{email_re}>|#{email_re})"
|
24
|
+
|
25
|
+
address_re = "(?:[^<@]+\\s+<#{Nisetegami.email_re}>|#{Nisetegami.email_re})"
|
23
26
|
addresses_re = /^#{address_re}(?:\s*,\s*#{address_re})*$/i
|
24
27
|
validates_format_of :from, :reply_to, :cc, :bcc, with: addresses_re, allow_blank: true
|
25
|
-
validate :subject, :body_text, :layout_text,
|
28
|
+
validate :name, :subject, :body_text, :layout_text, presence: true
|
26
29
|
validate :body_html, :layout_html, presence: true, unless: :only_text?
|
27
30
|
validate :check_template_syntax
|
28
31
|
validate :check_mailer
|
29
32
|
|
33
|
+
## callbacks
|
34
|
+
|
35
|
+
before_validation :set_name_if_necessary
|
36
|
+
|
30
37
|
## class-methods
|
31
38
|
|
32
39
|
# Accepts an instance of the ActionMailer::Base subclass
|
@@ -36,8 +43,6 @@ class Nisetegami::Template < ActiveRecord::Base
|
|
36
43
|
relation.where(mailer: mailer_instance.class.name, action: mailer_instance.action_name).first
|
37
44
|
end
|
38
45
|
|
39
|
-
public
|
40
|
-
|
41
46
|
def layout_html_path
|
42
47
|
layout_html && File.join(Nisetegami.layouts_path, layout_html)
|
43
48
|
end
|
@@ -127,6 +132,10 @@ class Nisetegami::Template < ActiveRecord::Base
|
|
127
132
|
false
|
128
133
|
end
|
129
134
|
|
135
|
+
def set_name_if_necessary
|
136
|
+
self.name = "#{mailer}##{action}" unless name.present?
|
137
|
+
end
|
138
|
+
|
130
139
|
end
|
131
140
|
|
132
141
|
# == Schema Information
|
@@ -0,0 +1,27 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title><%= t('nisetegami.admin.title') %></title>
|
5
|
+
<%= stylesheet_link_tag "nisetegami/application", :media => "all" %>
|
6
|
+
<%= javascript_include_tag "nisetegami/application" %>
|
7
|
+
<%= csrf_meta_tags %>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
|
11
|
+
<div class="container-fluid">
|
12
|
+
<% flash.each do |kind, value| %>
|
13
|
+
<div class="alert alert-<%= kind == :alert ? 'error' : 'success' %>">
|
14
|
+
<button type="button" class="close" data-dismiss="alert">×</button>
|
15
|
+
<% if kind == :alert %>
|
16
|
+
<strong><%= t('nisetegami.flash.alert') %>:</strong> <%= value %>
|
17
|
+
<% else %>
|
18
|
+
<%= value %>
|
19
|
+
<% end %>
|
20
|
+
</div>
|
21
|
+
<% end %>
|
22
|
+
|
23
|
+
<%= yield %>
|
24
|
+
</div>
|
25
|
+
|
26
|
+
</body>
|
27
|
+
</html>
|
@@ -0,0 +1,35 @@
|
|
1
|
+
<%= form_tag '', method: :get, class: 'filters well' do %>
|
2
|
+
<table>
|
3
|
+
<tr>
|
4
|
+
<th colspan="2"><h3><%= t('.title') %></h3></th>
|
5
|
+
</tr>
|
6
|
+
<tr>
|
7
|
+
<th><%= Nisetegami::Template.human_attribute_name :name %></th>
|
8
|
+
<td><%= text_field_tag :name, params[:name] %></td>
|
9
|
+
</tr>
|
10
|
+
<tr>
|
11
|
+
<th><%= t('.state') %></th>
|
12
|
+
<td><%= select_tag :enabled, options_for_select([[''], [t('.enabled'), true], [t('.disabled'), false]], params[:enabled]) %></td>
|
13
|
+
</tr>
|
14
|
+
<tr>
|
15
|
+
<th><%= Nisetegami::Template.human_attribute_name :mailer %></th>
|
16
|
+
<td><%= select_tag :mailer, options_for_select(([''] + Nisetegami.mapping.mailers.to_a), params[:mailer]) %></td>
|
17
|
+
</tr>
|
18
|
+
<tr>
|
19
|
+
<th><%= Nisetegami::Template.human_attribute_name :action %></th>
|
20
|
+
<td><%= select_tag :mailer_action, options_for_select(params[:mailer].blank? ? '' : ([''] + Nisetegami.mapping.actions(params[:mailer]).to_a), params[:mailer_action]) %></td>
|
21
|
+
</tr>
|
22
|
+
<% %w(subject from reply_to cc bcc).each do |attr| %>
|
23
|
+
<tr>
|
24
|
+
<th><%= Nisetegami::Template.human_attribute_name attr %></th>
|
25
|
+
<td><%= text_field_tag attr, params[attr] %></td>
|
26
|
+
</tr>
|
27
|
+
<% end %>
|
28
|
+
<tr>
|
29
|
+
<th colspan="2" align="left">
|
30
|
+
<%= submit_tag t('.filter'), class: 'btn btn-primary' %>
|
31
|
+
<%= content_tag :button, t('.reset'), class: 'reset btn btn-inverse' %>
|
32
|
+
</th>
|
33
|
+
</tr>
|
34
|
+
</table>
|
35
|
+
<% end %>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<%= form_tag test_template_path(template), class: 'well' do %>
|
2
|
+
<h3><%= t('.title') %></h3>
|
3
|
+
|
4
|
+
<%= label_tag :recipient, t('.recipient') %>
|
5
|
+
<%= text_field_tag :recipient %>
|
6
|
+
|
7
|
+
<%- if template.variable_mapping.present? %>
|
8
|
+
<h5><%= t('.variables') %></h5>
|
9
|
+
<% end %>
|
10
|
+
|
11
|
+
<% template.variable_mapping.each do |var| %>
|
12
|
+
<% unless var.respond_to?(:keys) %>
|
13
|
+
<%= render 'var', var: "[#{var}]", label: var, i18n_label: "#{template.translate_variable(var)}" %>
|
14
|
+
<% else %>
|
15
|
+
<% var.each do |klass, attributes| %>
|
16
|
+
<% attributes.each do |attr| %>
|
17
|
+
<%= render 'var', var: "[#{klass}][#{attr}]", label: "#{klass}.#{attr}", i18n_label: "#{template.translate_variable(klass, attr)}" %>
|
18
|
+
<% end %>
|
19
|
+
<% end %>
|
20
|
+
<% end %>
|
21
|
+
<% end %>
|
22
|
+
<div class="buttons">
|
23
|
+
<%= submit_tag t('.send'), class: 'btn btn-primary' %>
|
24
|
+
<%= content_tag :button, t('.reset'), class: 'reset btn btn-inverse' %>
|
25
|
+
</div>
|
26
|
+
<% end %>
|
@@ -0,0 +1,36 @@
|
|
1
|
+
<h1><%= t('.title', title: @template.name) %></h1>
|
2
|
+
|
3
|
+
<div class="row-fluid">
|
4
|
+
<div class="span9">
|
5
|
+
<%= form_for @template, html: {class: 'well'} do |f| %>
|
6
|
+
<fieldset>
|
7
|
+
<%= render 'edit_form_buttons', f: f, bottom_margin: true %>
|
8
|
+
|
9
|
+
<% %w(name subject from reply_to cc bcc).each do |attr| %>
|
10
|
+
<%= render 'field', f: f, attr: attr %>
|
11
|
+
<% end %>
|
12
|
+
|
13
|
+
<% %w(enabled only_text).each do |attr| %>
|
14
|
+
<%= render layout: 'field', locals: {f: f, attr: attr} do %>
|
15
|
+
<%= f.check_box attr %>
|
16
|
+
<% end %>
|
17
|
+
<% end %>
|
18
|
+
|
19
|
+
<% %w(text html).each do |format| %>
|
20
|
+
<%= render layout: 'field', locals: {f: f, attr: "layout_#{format}"} do %>
|
21
|
+
<%= f.select "layout_#{format}", options_for_select([''] + Nisetegami.send("#{format}_layouts")) %>
|
22
|
+
<% end %>
|
23
|
+
<%= render layout: 'field', locals: {f: f, attr: "body_#{format}"} do %>
|
24
|
+
<%= f.text_area "body_#{format}", class: 'span12', rows: 10 %>
|
25
|
+
<% end %>
|
26
|
+
<% end %>
|
27
|
+
|
28
|
+
<%= render 'edit_form_buttons', f: f %>
|
29
|
+
</fieldset>
|
30
|
+
<% end %>
|
31
|
+
</div>
|
32
|
+
|
33
|
+
<div class="span3">
|
34
|
+
<%= render 'test_mail', template: Nisetegami::TemplatePresenter.new(@template) %>
|
35
|
+
</div>
|
36
|
+
</div>
|
@@ -0,0 +1,42 @@
|
|
1
|
+
<h1><%= t('.title') %></h1>
|
2
|
+
|
3
|
+
<div class="row-fluid">
|
4
|
+
<div class="span8">
|
5
|
+
<%= form_tag do %>
|
6
|
+
<table class="table table-striped">
|
7
|
+
<%- if @templates.empty? %>
|
8
|
+
<tr>
|
9
|
+
<th><%= t('.no_templates_found') %></th>
|
10
|
+
</tr>
|
11
|
+
<%- else %>
|
12
|
+
<thead>
|
13
|
+
<%= render "delete_button" %>
|
14
|
+
<tr>
|
15
|
+
<%- %w(name mailer action subject from reply_to enabled only_text).each do |attr| %>
|
16
|
+
<th><%= Nisetegami::Template.human_attribute_name(attr) %></th>
|
17
|
+
<% end %>
|
18
|
+
<th><%= t('.edit') %></th>
|
19
|
+
<th><%= t('.delete') %></th>
|
20
|
+
</tr>
|
21
|
+
</thead>
|
22
|
+
<tbody>
|
23
|
+
<%- @templates.map { |t| Nisetegami::TemplatePresenter.new(t) }.each do |t| %>
|
24
|
+
<tr>
|
25
|
+
<%- %w(name mailer action subject from reply_to enabled only_text).each do |attr| %>
|
26
|
+
<td><%= t.send(attr) %></td>
|
27
|
+
<% end %>
|
28
|
+
<td><%= link_to t('.edit'), edit_template_path(t) %></td>
|
29
|
+
<td><%= check_box_tag 'template_ids[]', t.id %></td>
|
30
|
+
</tr>
|
31
|
+
<% end %>
|
32
|
+
<%= render "delete_button" %>
|
33
|
+
</tbody>
|
34
|
+
<% end %>
|
35
|
+
</table>
|
36
|
+
<% end %>
|
37
|
+
</div>
|
38
|
+
|
39
|
+
<div class="span4">
|
40
|
+
<%= render 'filters' %>
|
41
|
+
</div>
|
42
|
+
</div>
|
@@ -0,0 +1,56 @@
|
|
1
|
+
en:
|
2
|
+
activerecord:
|
3
|
+
models:
|
4
|
+
nisetegami/template: "Mail Template"
|
5
|
+
attributes:
|
6
|
+
nisetegami/template:
|
7
|
+
name: "Name"
|
8
|
+
mailer: "Mailer"
|
9
|
+
action: "Action"
|
10
|
+
subject: "Subject"
|
11
|
+
from: "From"
|
12
|
+
reply_to: "Reply to"
|
13
|
+
cc: "CC"
|
14
|
+
bcc: "BCC"
|
15
|
+
body_text: "Body text"
|
16
|
+
body_html: "Body html"
|
17
|
+
layout_text: "Layout text"
|
18
|
+
layout_html: "Layout html"
|
19
|
+
enabled: "Enabled"
|
20
|
+
only_text: "Only text"
|
21
|
+
nisetegami:
|
22
|
+
flash:
|
23
|
+
alert: "Error"
|
24
|
+
are_you_sure: "Are you sure?"
|
25
|
+
admin:
|
26
|
+
title: "Nisetegami Admin"
|
27
|
+
templates:
|
28
|
+
wrong_email: "Wrong email address"
|
29
|
+
test_email_delivered: "Test email delivered"
|
30
|
+
destroyed: "Templates %{templates} have been destroyed"
|
31
|
+
updated: "Template %{template} has been updated"
|
32
|
+
index:
|
33
|
+
title: "Mail Templates"
|
34
|
+
delete: "Delete"
|
35
|
+
edit: "Edit"
|
36
|
+
no_templates_found: "There are no templates found"
|
37
|
+
delete_button:
|
38
|
+
label: "Delete selected"
|
39
|
+
edit:
|
40
|
+
title: "Mail Template %{title}"
|
41
|
+
edit_form_buttons:
|
42
|
+
cancel: "Cancel"
|
43
|
+
update: "Update"
|
44
|
+
filters:
|
45
|
+
title: "Filters"
|
46
|
+
enabled: "enabled"
|
47
|
+
disabled: "disabled"
|
48
|
+
filter: "Filter"
|
49
|
+
state: "State"
|
50
|
+
reset: "Reset"
|
51
|
+
test_mail:
|
52
|
+
title: "Test Mail"
|
53
|
+
variables: "Variables"
|
54
|
+
recipient: "Recipient"
|
55
|
+
send: "Send"
|
56
|
+
reset: "Reset"
|
@@ -0,0 +1,56 @@
|
|
1
|
+
en:
|
2
|
+
activerecord:
|
3
|
+
models:
|
4
|
+
nisetegami/template: "Шаблон письма"
|
5
|
+
attributes:
|
6
|
+
nisetegami/template:
|
7
|
+
name: "Название"
|
8
|
+
mailer: "Мэйлер"
|
9
|
+
action: "Экшн"
|
10
|
+
subject: "Тема"
|
11
|
+
from: "От"
|
12
|
+
reply_to: "Ответить"
|
13
|
+
cc: "Копия"
|
14
|
+
bcc: "Скрытая копия"
|
15
|
+
body_text: "Содержание (текст)"
|
16
|
+
body_html: "Содержание (html)"
|
17
|
+
layout_text: "Лэйаут (текст)"
|
18
|
+
layout_html: "Лэйаут (html)"
|
19
|
+
enabled: "Включен"
|
20
|
+
only_text: "Только текст"
|
21
|
+
nisetegami:
|
22
|
+
flash:
|
23
|
+
alert: "Ошибка"
|
24
|
+
are_you_sure: "Вы уверены?"
|
25
|
+
admin:
|
26
|
+
title: "Админка Nisetegami"
|
27
|
+
templates:
|
28
|
+
wrong_email: "Неправильный адрес email"
|
29
|
+
test_email_delivered: "Тестовое сообщение отправлено"
|
30
|
+
destroyed: "Шаблоны %{templates} удалены"
|
31
|
+
updated: "Шаблоны %{template} обновлены"
|
32
|
+
index:
|
33
|
+
title: "Шаблоны писем"
|
34
|
+
delete: "Удалить"
|
35
|
+
edit: "Редактировать"
|
36
|
+
no_templates_found: "Шаблоны не найдены"
|
37
|
+
delete_button:
|
38
|
+
label: "Удалить выбранное"
|
39
|
+
edit:
|
40
|
+
title: "Шаблон %{title}"
|
41
|
+
edit_form_buttons:
|
42
|
+
cancel: "Отмена"
|
43
|
+
update: "Обновить"
|
44
|
+
filters:
|
45
|
+
title: "Фильтры"
|
46
|
+
enabled: "включен"
|
47
|
+
disabled: "выключен"
|
48
|
+
filter: "Отфильтровать"
|
49
|
+
state: "Состояние"
|
50
|
+
reset: "Сбросить"
|
51
|
+
test_mail:
|
52
|
+
title: "Тестовое сообщение"
|
53
|
+
variables: "Переменные"
|
54
|
+
recipient: "Получатель"
|
55
|
+
send: "Отправить"
|
56
|
+
reset: "Сбросить"
|
data/config/routes.rb
ADDED
data/lib/nisetegami.rb
CHANGED
@@ -8,7 +8,9 @@ require 'nisetegami/asset_provider'
|
|
8
8
|
require 'nisetegami/exceptions'
|
9
9
|
require 'nisetegami/mapping'
|
10
10
|
require 'nisetegami/utils'
|
11
|
+
require 'nisetegami/template_presenter'
|
11
12
|
require 'nisetegami/engine'
|
13
|
+
require 'nisetegami/railtie'
|
12
14
|
|
13
15
|
module Nisetegami
|
14
16
|
|
@@ -17,6 +19,9 @@ module Nisetegami
|
|
17
19
|
mattr_reader :mapping
|
18
20
|
@@mapping = Nisetegami::Mapping.new
|
19
21
|
|
22
|
+
mattr_accessor :email_re
|
23
|
+
@@email_re = /[-a-z0-9_+\.]+@([-a-z0-9]+\.)+[a-z0-9]{2,}/
|
24
|
+
|
20
25
|
def self.configure
|
21
26
|
yield self
|
22
27
|
end
|
@@ -14,7 +14,7 @@ module Nisetegami
|
|
14
14
|
def testing(action, recipient, variables)
|
15
15
|
new.testing do |instance|
|
16
16
|
instance.action_name = action.to_s
|
17
|
-
variables.each { |k, v| instance.instance_variable_set("@#{k}", v) }
|
17
|
+
variables.each { |k, v| instance.instance_variable_set("@#{k}", v) } if variables
|
18
18
|
instance.mail to: recipient
|
19
19
|
end
|
20
20
|
end
|
@@ -38,11 +38,9 @@ module Nisetegami
|
|
38
38
|
vars = instance_variables.inject({}) do |hsh, var|
|
39
39
|
unless var =~ /@_/
|
40
40
|
template_var = instance_variable_get(var)
|
41
|
-
template_var =
|
42
|
-
|
43
|
-
|
44
|
-
template_var
|
45
|
-
end
|
41
|
+
if template_var.class != (casted = Nisetegami.cast[template_var.class])
|
42
|
+
template_var = instance_variable_set(var, casted.new(template_var))
|
43
|
+
end
|
46
44
|
hsh[var[1..-1].to_sym] = template_var
|
47
45
|
end
|
48
46
|
hsh
|
data/lib/nisetegami/engine.rb
CHANGED
data/lib/nisetegami/mapping.rb
CHANGED
@@ -32,9 +32,8 @@ module Nisetegami
|
|
32
32
|
|
33
33
|
Nisetegami::Template.create!(
|
34
34
|
subject: "Subject",
|
35
|
-
body_text: "You can use following variables: #{variables}. Format: text.",
|
36
|
-
body_html: "You can use following variables: #{variables}. Format: html.",
|
37
|
-
name: route,
|
35
|
+
body_text: "You can use the following variables: #{variables}. Format: text.",
|
36
|
+
body_html: "You can use the following variables: #{variables}. Format: html.",
|
38
37
|
mailer: mailer,
|
39
38
|
action: action,
|
40
39
|
enabled: false
|
@@ -42,6 +41,11 @@ module Nisetegami
|
|
42
41
|
end
|
43
42
|
end
|
44
43
|
|
44
|
+
def actions(mailer)
|
45
|
+
klass = mailer.constantize
|
46
|
+
klass.ancestors.include?(ActionMailer::Base) && klass.action_methods
|
47
|
+
end
|
48
|
+
|
45
49
|
private
|
46
50
|
|
47
51
|
def expand_locals(*locals)
|
@@ -62,11 +66,7 @@ module Nisetegami
|
|
62
66
|
end
|
63
67
|
|
64
68
|
def action_exists?(mailer, action)
|
65
|
-
|
66
|
-
klass.ancestors.include?(ActionMailer::Base) &&
|
67
|
-
klass.action_methods.include?(action.to_s)
|
68
|
-
rescue NameError
|
69
|
-
false
|
69
|
+
actions(mailer).include?(action.to_s)
|
70
70
|
end
|
71
71
|
|
72
72
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Nisetegami
|
4
|
+
class TemplatePresenter
|
5
|
+
def initialize(template)
|
6
|
+
@template = template
|
7
|
+
end
|
8
|
+
|
9
|
+
def mailer
|
10
|
+
I18n.t("nisetegami.mailers.#{@template[:mailer].underscore}", default: @template.mailer)
|
11
|
+
end
|
12
|
+
|
13
|
+
def action
|
14
|
+
I18n.t("nisetegami.actions.#{@template[:mailer].underscore}.#{@template.action}", default: @template.action.humanize)
|
15
|
+
end
|
16
|
+
|
17
|
+
def translate_variable(*args)
|
18
|
+
'(' + I18n.t!("nisetegami.variables.#{@template[:mailer].underscore}.#{@template.action}." << args.join('.')) + ')'
|
19
|
+
rescue I18n::MissingTranslationData
|
20
|
+
end
|
21
|
+
|
22
|
+
%w(enabled only_text).each do |attr|
|
23
|
+
define_method(attr) { @template.send(attr) ? '√' : '' }
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_param
|
27
|
+
@template.id
|
28
|
+
end
|
29
|
+
|
30
|
+
def method_missing(method, *args, &block)
|
31
|
+
@template.send(method, *args, &block)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/nisetegami/version.rb
CHANGED
@@ -1,4 +1,8 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
namespace :nisetegami do
|
2
|
+
namespace :templates do
|
3
|
+
desc "Populate nisetegami templates with sample data"
|
4
|
+
task :populate => :environment do
|
5
|
+
Nisetegami.populate!
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nisetegami
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-11-
|
13
|
+
date: 2012-11-09 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rails
|
@@ -92,22 +92,6 @@ dependencies:
|
|
92
92
|
- - ~>
|
93
93
|
- !ruby/object:Gem::Version
|
94
94
|
version: '3.2'
|
95
|
-
- !ruby/object:Gem::Dependency
|
96
|
-
name: rspec
|
97
|
-
requirement: !ruby/object:Gem::Requirement
|
98
|
-
none: false
|
99
|
-
requirements:
|
100
|
-
- - ! '>='
|
101
|
-
- !ruby/object:Gem::Version
|
102
|
-
version: '0'
|
103
|
-
type: :development
|
104
|
-
prerelease: false
|
105
|
-
version_requirements: !ruby/object:Gem::Requirement
|
106
|
-
none: false
|
107
|
-
requirements:
|
108
|
-
- - ! '>='
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: '0'
|
111
95
|
- !ruby/object:Gem::Dependency
|
112
96
|
name: rspec-rails
|
113
97
|
requirement: !ruby/object:Gem::Requirement
|
@@ -164,7 +148,27 @@ executables: []
|
|
164
148
|
extensions: []
|
165
149
|
extra_rdoc_files: []
|
166
150
|
files:
|
151
|
+
- app/assets/javascripts/nisetegami/application.js
|
152
|
+
- app/assets/javascripts/nisetegami/nisetegami.bootstrap.min.js
|
153
|
+
- app/assets/javascripts/nisetegami/templates.js.coffee
|
154
|
+
- app/assets/stylesheets/nisetegami/application.css.scss
|
155
|
+
- app/assets/stylesheets/nisetegami/nisetegami.bootstrap.min.css
|
156
|
+
- app/assets/stylesheets/nisetegami/templates.css.scss
|
157
|
+
- app/controllers/nisetegami/application_controller.rb
|
158
|
+
- app/controllers/nisetegami/templates_controller.rb
|
167
159
|
- app/models/nisetegami/template.rb
|
160
|
+
- app/views/layouts/nisetegami/application.html.erb
|
161
|
+
- app/views/nisetegami/templates/_delete_button.html.erb
|
162
|
+
- app/views/nisetegami/templates/_edit_form_buttons.html.erb
|
163
|
+
- app/views/nisetegami/templates/_field.html.erb
|
164
|
+
- app/views/nisetegami/templates/_filters.html.erb
|
165
|
+
- app/views/nisetegami/templates/_test_mail.html.erb
|
166
|
+
- app/views/nisetegami/templates/_var.html.erb
|
167
|
+
- app/views/nisetegami/templates/edit.html.erb
|
168
|
+
- app/views/nisetegami/templates/index.html.erb
|
169
|
+
- config/locales/nisetegami.en.yml
|
170
|
+
- config/locales/nisetegami.ru.yml
|
171
|
+
- config/routes.rb
|
168
172
|
- lib/generators/nisetegami/templates/migrations/001_create_nisetegami_templates.rb
|
169
173
|
- lib/generators/nisetegami/templates_generator.rb
|
170
174
|
- lib/nisetegami/action_mailer_extensions.rb
|
@@ -174,6 +178,8 @@ files:
|
|
174
178
|
- lib/nisetegami/exceptions.rb
|
175
179
|
- lib/nisetegami/liquid_template_handler.rb
|
176
180
|
- lib/nisetegami/mapping.rb
|
181
|
+
- lib/nisetegami/railtie.rb
|
182
|
+
- lib/nisetegami/template_presenter.rb
|
177
183
|
- lib/nisetegami/test/factories.rb
|
178
184
|
- lib/nisetegami/test/test_mailer.rb
|
179
185
|
- lib/nisetegami/test.rb
|