copycat 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (29) hide show
  1. data/README.md +12 -2
  2. data/app/assets/stylesheets/copycat_engine.css +417 -38
  3. data/app/controllers/copycat_translations_controller.rb +22 -9
  4. data/app/views/copycat_translations/edit.html.erb +2 -1
  5. data/app/views/copycat_translations/help.html.erb +25 -0
  6. data/app/views/copycat_translations/{upload.html.erb → import_export.html.erb} +8 -3
  7. data/app/views/copycat_translations/index.html.erb +27 -17
  8. data/app/views/layouts/copycat.html.erb +15 -4
  9. data/config/routes.rb +6 -3
  10. data/lib/copycat/version.rb +1 -1
  11. data/lib/copycat.rb +7 -13
  12. data/spec/dummy/config/initializers/copycat.rb +2 -2
  13. data/spec/dummy/db/development.sqlite3 +0 -0
  14. data/spec/dummy/db/migrate/{20120320143433_create_copycat_translations.copycat_engine.rb → 20120320194234_create_copycat_translations.copycat_engine.rb} +0 -0
  15. data/spec/dummy/db/schema.rb +1 -1
  16. data/spec/dummy/db/test.sqlite3 +0 -0
  17. data/spec/dummy/log/development.log +5429 -0
  18. data/spec/dummy/log/test.log +10221 -0
  19. data/spec/dummy/tmp/cache/assets/C19/060/sprockets%2F125436f53217b7f564aa5016d1168709 +0 -0
  20. data/spec/dummy/tmp/cache/assets/CB3/6E0/sprockets%2F0f4c96b04436bf7ae900561753947d4c +0 -0
  21. data/spec/dummy/tmp/cache/assets/DA4/EE0/sprockets%2Fcd39e3d56788faea331e0f5bac67329b +0 -0
  22. data/spec/dummy/tmp/pids/server.pid +1 -0
  23. data/spec/factories/copycat_translations.rb +1 -1
  24. data/spec/integration/copycat_spec.rb +197 -54
  25. data/spec/integration/dummy_spec.rb +63 -0
  26. data/spec/spec_helper.rb +1 -0
  27. metadata +18 -9
  28. data/app/views/copycat_translations/_copycat_header.html.erb +0 -9
  29. data/app/views/copycat_translations/readme.html.erb +0 -27
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Copycat #
2
2
 
3
- Copycat is a Rails engine that allows editing live website copy.
3
+ Copycat is a Rails engine that allows users to edit live website copy.
4
4
 
5
5
  ## How to use ##
6
6
 
@@ -13,6 +13,8 @@ rake copycat:install
13
13
  rake db:migrate
14
14
  ```
15
15
 
16
+ Since Copycat data is stored locally on an indexed table with no foreign keys, page loads are very fast and changes appear instantly.
17
+
16
18
  In a view, use the Rails i18N.translate() method where you would like to display some editable copy:
17
19
 
18
20
 
@@ -20,7 +22,7 @@ In a view, use the Rails i18N.translate() method where you would like to display
20
22
  <h1><%= t('site.index.header') %></h1>
21
23
  ```
22
24
 
23
- Visit the page in your browser, and a Copycat translation will be created for the key. Then visit '/copycat_translations' in your browser and you can edit the value of that token.
25
+ Visit the page in your browser, and a Copycat translation will be created for the key. Then visit '/copycat_translations' in your browser, log in with the username and password generated in `config/initializers/copycat.rb`, and you can edit the value of that token.
24
26
 
25
27
  ## Rails i18N API ##
26
28
 
@@ -28,7 +30,15 @@ You can read about the Rails internationalization framework [here](http://guides
28
30
 
29
31
  ## Deploying ##
30
32
 
33
+ To transfer changes from staging to production:
34
+
35
+ * Download copy as YAML on staging
36
+ * Login to Copycat on production
37
+ * Upload YAML to production
38
+
39
+ Since this process requires no code commits, non-developers can also 'deploy' copy changes.
31
40
 
41
+ You can also commit Copycat's YAML export, which is compatible with i18n, to your git repository.
32
42
 
33
43
  ## Developing ##
34
44
 
@@ -1,64 +1,443 @@
1
- body.copycat {
2
- margin: 0;
1
+ /*
2
+ * Skeleton V1.1
3
+ * Copyright 2011, Dave Gamache
4
+ * www.getskeleton.com
5
+ * Free to use under the MIT license.
6
+ * http://www.opensource.org/licenses/mit-license.php
7
+ * 8/17/2011
8
+ */
9
+
10
+
11
+ /* Table of Content
12
+ ==================================================
13
+ #Reset & Basics
14
+ #Basic Styles
15
+ #Site Styles
16
+ #Typography
17
+ #Links
18
+ #Lists
19
+ #Images
20
+ #Buttons
21
+ #Tabs
22
+ #Forms
23
+ #Misc */
24
+
25
+
26
+ /* #Reset & Basics (Inspired by E. Meyers)
27
+ ================================================== */
28
+ html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {
29
+ margin: 0;
30
+ padding: 0;
31
+ border: 0;
32
+ font-size: 100%;
33
+ font: inherit;
34
+ vertical-align: baseline; }
35
+ article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {
36
+ display: block; }
37
+ body {
38
+ line-height: 1; }
39
+ ol, ul {
40
+ list-style: none; }
41
+ blockquote, q {
42
+ quotes: none; }
43
+ blockquote:before, blockquote:after,
44
+ q:before, q:after {
45
+ content: '';
46
+ content: none; }
47
+ table {
48
+ border-collapse: collapse;
49
+ border-spacing: 0; }
50
+
51
+
52
+ /* #Basic Styles
53
+ ================================================== */
54
+ body {
55
+ background: #fff;
56
+ font: 14px/21px "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif;
57
+ color: #444;
58
+ -webkit-font-smoothing: antialiased; /* Fix for webkit rendering */
59
+ -webkit-text-size-adjust: 100%;
60
+ }
61
+
62
+
63
+ /* #Typography
64
+ ================================================== */
65
+ h1, h2, h3, h4, h5, h6 {
66
+ color: #181818;
67
+ font-family: "Georgia", "Times New Roman", Helvetica, Arial, sans-serif;
68
+ font-weight: normal; }
69
+ h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { font-weight: inherit; }
70
+ h1 { font-size: 46px; line-height: 50px; margin-bottom: 14px;}
71
+ h2 { font-size: 35px; line-height: 40px; margin-bottom: 10px; }
72
+ h3 { font-size: 28px; line-height: 34px; margin-bottom: 8px; }
73
+ h4 { font-size: 21px; line-height: 30px; margin-bottom: 4px; }
74
+ h5 { font-size: 17px; line-height: 24px; }
75
+ h6 { font-size: 14px; line-height: 21px; }
76
+ .subheader { color: #777; }
77
+
78
+ p { margin: 0 0 20px 0; }
79
+ p img { margin: 0; }
80
+ p.lead { font-size: 21px; line-height: 27px; color: #777; }
81
+
82
+ em { font-style: italic; }
83
+ strong { font-weight: bold; color: #333; }
84
+ small { font-size: 80%; }
85
+
86
+ /* Blockquotes */
87
+ blockquote, blockquote p { font-size: 17px; line-height: 24px; color: #777; font-style: italic; }
88
+ blockquote { margin: 0 0 20px; padding: 9px 20px 0 19px; border-left: 1px solid #ddd; }
89
+ blockquote cite { display: block; font-size: 12px; color: #555; }
90
+ blockquote cite:before { content: "\2014 \0020"; }
91
+ blockquote cite a, blockquote cite a:visited, blockquote cite a:visited { color: #555; }
92
+
93
+ hr { border: solid #ddd; border-width: 1px 0 0; clear: both; margin: 10px 0 30px; height: 0; }
94
+
95
+
96
+ /* #Links
97
+ ================================================== */
98
+ a, a:visited { color: #333; text-decoration: underline; outline: 0; }
99
+ a:hover, a:focus { color: #000; }
100
+ p a, p a:visited { line-height: inherit; }
101
+
102
+
103
+ /* #Lists
104
+ ================================================== */
105
+ ul, ol { margin-bottom: 20px; }
106
+ ul { list-style: none outside; }
107
+ ol { list-style: decimal; }
108
+ ol, ul.square, ul.circle, ul.disc { margin-left: 30px; }
109
+ ul.square { list-style: square outside; }
110
+ ul.circle { list-style: circle outside; }
111
+ ul.disc { list-style: disc outside; }
112
+ ul ul, ul ol,
113
+ ol ol, ol ul { margin: 4px 0 5px 30px; font-size: 90%; }
114
+ ul ul li, ul ol li,
115
+ ol ol li, ol ul li { margin-bottom: 6px; }
116
+ li { line-height: 18px; margin-bottom: 12px; }
117
+ ul.large li { line-height: 21px; }
118
+ li p { line-height: 21px; }
119
+
120
+ /* #Images
121
+ ================================================== */
122
+
123
+ img.scale-with-grid {
124
+ max-width: 100%;
125
+ height: auto; }
126
+
127
+
128
+ /* #Buttons
129
+ ================================================== */
130
+
131
+ .button,
132
+ button,
133
+ input[type="submit"],
134
+ input[type="reset"],
135
+ input[type="button"] {
136
+ background: #eee; /* Old browsers */
137
+ background: #eee -moz-linear-gradient(top, rgba(255,255,255,.2) 0%, rgba(0,0,0,.2) 100%); /* FF3.6+ */
138
+ background: #eee -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,.2)), color-stop(100%,rgba(0,0,0,.2))); /* Chrome,Safari4+ */
139
+ background: #eee -webkit-linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* Chrome10+,Safari5.1+ */
140
+ background: #eee -o-linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* Opera11.10+ */
141
+ background: #eee -ms-linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* IE10+ */
142
+ background: #eee linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* W3C */
143
+ border: 1px solid #aaa;
144
+ border-top: 1px solid #ccc;
145
+ border-left: 1px solid #ccc;
146
+ padding: 4px 12px;
147
+ -moz-border-radius: 3px;
148
+ -webkit-border-radius: 3px;
149
+ border-radius: 3px;
150
+ color: #444;
151
+ display: inline-block;
152
+ font-size: 11px;
153
+ font-weight: bold;
154
+ text-decoration: none;
155
+ text-shadow: 0 1px rgba(255, 255, 255, .75);
156
+ cursor: pointer;
157
+ margin-bottom: 20px;
158
+ line-height: normal;
159
+ padding: 8px 10px;
160
+ font-family: "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif; }
161
+
162
+ .button:hover,
163
+ button:hover,
164
+ input[type="submit"]:hover,
165
+ input[type="reset"]:hover,
166
+ input[type="button"]:hover {
167
+ color: #222;
168
+ background: #ddd; /* Old browsers */
169
+ background: #ddd -moz-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%); /* FF3.6+ */
170
+ background: #ddd -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,.3)), color-stop(100%,rgba(0,0,0,.3))); /* Chrome,Safari4+ */
171
+ background: #ddd -webkit-linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* Chrome10+,Safari5.1+ */
172
+ background: #ddd -o-linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* Opera11.10+ */
173
+ background: #ddd -ms-linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* IE10+ */
174
+ background: #ddd linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* W3C */
175
+ border: 1px solid #888;
176
+ border-top: 1px solid #aaa;
177
+ border-left: 1px solid #aaa; }
178
+
179
+ .button:active,
180
+ button:active,
181
+ input[type="submit"]:active,
182
+ input[type="reset"]:active,
183
+ input[type="button"]:active {
184
+ border: 1px solid #666;
185
+ background: #ccc; /* Old browsers */
186
+ background: #ccc -moz-linear-gradient(top, rgba(255,255,255,.35) 0%, rgba(10,10,10,.4) 100%); /* FF3.6+ */
187
+ background: #ccc -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,.35)), color-stop(100%,rgba(10,10,10,.4))); /* Chrome,Safari4+ */
188
+ background: #ccc -webkit-linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* Chrome10+,Safari5.1+ */
189
+ background: #ccc -o-linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* Opera11.10+ */
190
+ background: #ccc -ms-linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* IE10+ */
191
+ background: #ccc linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* W3C */ }
192
+
193
+ .button.full-width,
194
+ button.full-width,
195
+ input[type="submit"].full-width,
196
+ input[type="reset"].full-width,
197
+ input[type="button"].full-width {
198
+ width: 100%;
199
+ padding-left: 0 !important;
200
+ padding-right: 0 !important;
201
+ text-align: center; }
202
+
203
+ /* Fix for odd Mozilla border & padding issues */
204
+ button::-moz-focus-inner,
205
+ input::-moz-focus-inner {
206
+ border: 0;
207
+ padding: 0;
208
+ }
209
+
210
+
211
+ /* #Tabs (activate in tabs.js)
212
+ ================================================== */
213
+ ul.tabs {
214
+ display: block;
215
+ margin: 0 0 20px 0;
216
+ padding: 0;
217
+ border-bottom: solid 1px #ddd; }
218
+ ul.tabs li {
219
+ display: block;
220
+ width: auto;
221
+ height: 30px;
222
+ padding: 0;
223
+ float: left;
224
+ margin-bottom: 0; }
225
+ ul.tabs li a {
226
+ display: block;
227
+ text-decoration: none;
228
+ width: auto;
229
+ height: 29px;
230
+ padding: 0px 20px;
231
+ line-height: 30px;
232
+ border: solid 1px #ddd;
233
+ border-width: 1px 1px 0 0;
234
+ margin: 0;
235
+ background: #f5f5f5;
236
+ font-size: 13px; }
237
+ ul.tabs li a.active {
238
+ background: #fff;
239
+ height: 30px;
240
+ position: relative;
241
+ top: -4px;
242
+ padding-top: 4px;
243
+ border-left-width: 1px;
244
+ margin: 0 0 0 -1px;
245
+ color: #111;
246
+ -moz-border-radius-topleft: 2px;
247
+ -webkit-border-top-left-radius: 2px;
248
+ border-top-left-radius: 2px;
249
+ -moz-border-radius-topright: 2px;
250
+ -webkit-border-top-right-radius: 2px;
251
+ border-top-right-radius: 2px; }
252
+ ul.tabs li:first-child a.active {
253
+ margin-left: 0; }
254
+ ul.tabs li:first-child a {
255
+ border-width: 1px 1px 0 1px;
256
+ -moz-border-radius-topleft: 2px;
257
+ -webkit-border-top-left-radius: 2px;
258
+ border-top-left-radius: 2px; }
259
+ ul.tabs li:last-child a {
260
+ -moz-border-radius-topright: 2px;
261
+ -webkit-border-top-right-radius: 2px;
262
+ border-top-right-radius: 2px; }
263
+
264
+ ul.tabs-content { margin: 0; display: block; }
265
+ ul.tabs-content > li { display:none; }
266
+ ul.tabs-content > li.active { display: block; }
267
+
268
+ /* Clearfixing tabs for beautiful stacking */
269
+ ul.tabs:before,
270
+ ul.tabs:after {
271
+ content: '\0020';
272
+ display: block;
273
+ overflow: hidden;
274
+ visibility: hidden;
275
+ width: 0;
276
+ height: 0; }
277
+ ul.tabs:after {
278
+ clear: both; }
279
+ ul.tabs {
280
+ zoom: 1; }
281
+
282
+
283
+ /* #Forms
284
+ ================================================== */
285
+
286
+ form {
287
+ margin-bottom: 20px; }
288
+ fieldset {
289
+ margin-bottom: 20px; }
290
+ input[type="text"],
291
+ input[type="password"],
292
+ input[type="email"],
293
+ textarea,
294
+ select {
295
+ border: 1px solid #ccc;
296
+ padding: 6px 4px;
297
+ outline: none;
298
+ -moz-border-radius: 2px;
299
+ -webkit-border-radius: 2px;
300
+ border-radius: 2px;
301
+ font: 13px "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif;
302
+ color: #777;
303
+ margin: 0;
304
+ width: 210px;
305
+ max-width: 100%;
306
+ display: block;
307
+ margin-bottom: 20px;
308
+ background: #fff; }
309
+ select {
310
+ padding: 0; }
311
+ input[type="text"]:focus,
312
+ input[type="password"]:focus,
313
+ input[type="email"]:focus,
314
+ textarea:focus {
315
+ border: 1px solid #aaa;
316
+ color: #444;
317
+ -moz-box-shadow: 0 0 3px rgba(0,0,0,.2);
318
+ -webkit-box-shadow: 0 0 3px rgba(0,0,0,.2);
319
+ box-shadow: 0 0 3px rgba(0,0,0,.2); }
320
+ textarea {
321
+ min-height: 60px; }
322
+ label,
323
+ legend {
324
+ display: block;
325
+ font-weight: bold;
326
+ font-size: 13px; }
327
+ select {
328
+ width: 220px; }
329
+ input[type="checkbox"] {
330
+ display: inline; }
331
+ label span,
332
+ legend span {
333
+ font-weight: normal;
334
+ font-size: 13px;
335
+ color: #444; }
336
+
337
+ /* #Misc
338
+ ================================================== */
339
+ .remove-bottom { margin-bottom: 0 !important; }
340
+ .half-bottom { margin-bottom: 10px !important; }
341
+ .add-bottom { margin-bottom: 20px !important; }
342
+
343
+ /* end of getskeleton */
344
+
345
+ h2 {
346
+ font-size: 1.8em;
3
347
  }
4
- div#copycat {
5
- width: 75%;
6
- margin-left: 10.5%;
7
- padding-left: 2%;
8
- margin-right: 10.5%;
9
- padding-right: 2%;
10
- }
11
- #copycat ul {
12
- padding-left: 0;
13
- padding-top: 2em;
14
- }
15
- #copycat li, #copycat li h2 {
16
- display: inline;
17
- padding-right: 4em;
18
- }
19
- #copycat table, #copycat form, #copycat div.copycat-alert, #copycat div.copycat-notice, div#readme, div#upload {
20
- padding-top: 2em;
21
- }
22
- #copycat table {
348
+
349
+ table {
23
350
  width: 100%;
24
351
  border-bottom: 1px #CCC dotted;
352
+ padding-top: 2em;
25
353
  padding-bottom: 1em;
26
354
  }
27
- #copycat table th {
355
+
356
+ table th {
28
357
  text-align: left;
29
358
  padding-bottom: 1em;
30
359
  }
31
- #copycat table tr td {
360
+
361
+ table tr td {
32
362
  padding-top: 1em;
33
363
  padding-bottom: 1em;
34
364
  border-top: 1px #CCC dotted;
35
365
  }
36
- #copycat table tr td.key {
366
+
367
+ table tr td.key {
37
368
  width: 20%;
38
369
  margin-right: 5%;
39
370
  vertical-align: top;
40
371
  }
41
- #copycat table tr td.value {
372
+
373
+ table tr td.value {
42
374
  width: 75%;
43
375
  }
44
- #copycat div.copycat-alert {
45
- color: red;
46
- font-weight: bold;
376
+
377
+ input[type="text"],
378
+ textarea,
379
+ select {
380
+ display: inline;
381
+ margin: .2em;
47
382
  }
48
- #copycat div.copycat-notice {
49
- color: green;
50
- font-weight: bold;
383
+
384
+ select {
385
+ width: 4em;
51
386
  }
52
- #copycat div.copycat-edit-form {
53
- width: 50%;
387
+
388
+ div.edit {
389
+ width: 99%;
54
390
  }
55
- #copycat div.copycat-edit-form textarea {
56
- font-size: 0.8em;
391
+
392
+ div.edit textarea {
57
393
  width: 99%;
58
394
  margin-top: 1em;
59
395
  }
60
- #copycat div.copycat-edit-form input {
61
- margin-top: 0.5em;
62
- font-size: 1em;
396
+
397
+ div.edit a {
398
+ display: block;
399
+ margin: -2em 0 0 .5em;
400
+ }
401
+
402
+ body {
403
+ background-color: #FFFDF9;
404
+ }
405
+
406
+ #page {
407
+ background-color: #FFFDF7;
408
+ width: 800px;
409
+ margin: 0 auto;
410
+ padding: .5em;
411
+ }
412
+ #header {
413
+ width: 100%;
414
+ height: 4em;
415
+ }
416
+
417
+ #header h1 {
418
+ margin-left: 1em;
419
+ float: left;
420
+ font-size: 2.5em;
421
+ line-height: 1em;
422
+ }
423
+
424
+ #header ul {
63
425
  float: right;
426
+ padding-top: 2%;
427
+ list-style-type: none;
428
+ }
429
+
430
+ #header li {
431
+ float: left;
432
+ }
433
+
434
+ #header li a {
435
+ padding: 0 .5em 0 .5em;
436
+ }
437
+
438
+ #notice {
439
+ height: 2em;
440
+ background-color: #FFFFBB;
441
+ text-align: center;
64
442
  }
443
+
@@ -5,11 +5,20 @@ class CopycatTranslationsController < ApplicationController
5
5
  layout 'copycat'
6
6
 
7
7
  def index
8
- @copycat_translations = CopycatTranslation.all
9
- respond_to do |format|
10
- format.html
11
- format.yaml { send_data CopycatTranslation.export_yaml, :filename => "copycat_translations_#{Time.now.strftime("%Y_%m_%d_%H_%M_%S")}.yml" }
8
+ params[:locale] = I18n.default_locale unless params.has_key?(:locale)
9
+ query = CopycatTranslation
10
+ query = query.where(locale: params[:locale]) unless params[:locale].blank?
11
+
12
+ if params.has_key?(:search)
13
+ if (search = params[:search]).blank?
14
+ @copycat_translations = query.all
15
+ else
16
+ @copycat_translations = query.where("key LIKE ? OR value LIKE ?", "%#{search}%", "%#{search}%")
17
+ end
18
+ else
19
+ @copycat_translations = []
12
20
  end
21
+ @locale_names = CopycatTranslation.find(:all, select: 'distinct locale').map(&:locale)
13
22
  end
14
23
 
15
24
  def edit
@@ -20,7 +29,6 @@ class CopycatTranslationsController < ApplicationController
20
29
  cct = CopycatTranslation.find_by_id(params["id"])
21
30
  cct.value = params["copycat_translation"]["value"]
22
31
  if cct.save
23
- @copycat_translations = CopycatTranslation.all
24
32
  redirect_to copycat_translations_path
25
33
  else
26
34
  @copycat_translation = cct
@@ -28,18 +36,23 @@ class CopycatTranslationsController < ApplicationController
28
36
  end
29
37
  end
30
38
 
31
- def readme
39
+ def help
32
40
  end
33
41
 
34
- def upload
42
+ def import_export
35
43
  end
36
44
 
37
- def import_yaml
45
+ def download
46
+ filename = "copycat_translations_#{Time.now.strftime("%Y_%m_%d_%H_%M_%S")}.yml"
47
+ send_data CopycatTranslation.export_yaml, :filename => filename
48
+ end
49
+
50
+ def upload
38
51
  begin
39
52
  CopycatTranslation.import_yaml(params["file"].tempfile)
40
53
  rescue StandardError => e
41
54
  flash[:notice] = "There was an error processing your upload!"
42
- render :action => 'upload', :status => 400
55
+ render :action => 'import_export', :status => 400
43
56
  else
44
57
  redirect_to copycat_translations_path, :notice => "YAML file uploaded successfully!"
45
58
  end
@@ -1,4 +1,4 @@
1
- <div class="copycat-edit-form">
1
+ <div class="edit">
2
2
  <%= form_for @copycat_translation, :url => { :action => "update" }, :html => {:class => "copycat_translation"} do |f| %>
3
3
  <span class="copycat-edit-form-key"><%= @copycat_translation.key %></span>
4
4
  <br>
@@ -6,4 +6,5 @@
6
6
  <br>
7
7
  <%= f.submit "Update" %>
8
8
  <% end %>
9
+ <%= link_to "Cancel", copycat_translations_path %>
9
10
  </div>
@@ -0,0 +1,25 @@
1
+ <div>
2
+
3
+ <div>
4
+ <p>Copycat is a Ruby on Rails engine that allows you to edit live website copy.</p>
5
+ </div>
6
+
7
+ <div>
8
+ <h2> How to use </h2>
9
+ <p>Search for the copy text you want to edit. If Copycat is currently controlling that content, it will appear when you search. If not, ask a developer to add it to Copycat. You can filter by locale to control what copy is displayed in different languages.</p>
10
+ <p>Once copy appears, click the left hand side links to edit. Values with keys ending in "_html" will be parsed as literal html, so you can insert tags. All other values are parsed as plain text.</p>
11
+ </div>
12
+
13
+ <div>
14
+ <h2> Exporting and Importing </h2>
15
+ <p> Copycat text is data--not code. By default, it is stored in your server's database, and not the codebase that powers your website. Therefore, you may have to download/upload Copycat data to transfer your copy edits between servers, or to safeguard them between database wipes. Copycat exports (and is able to re-import) all of its data in a plaintext format called "YAML."</p>
16
+ <h4> Exporting </h4>
17
+ <p>You can get a YAML file of all your copy by clicking "Download" on the Import/Export page.</p>
18
+ <h4> Importing </h4>
19
+ <p>You can upload copy to Copycat by uploading a properly formatted YAML file on the Import/Export page. Uploading copy won't delete any entries from Copycat, but it may update them or create new ones. Use this feature to mass-update your copy from between servers -- e.g., make changes to copy on a test server, and then when you're satisfied, download the YAML file and upload it to your production site. Downloading your copy as YAML and then immediately re-uploading it will leave your copy unchanged.</p>
20
+ <h4> Commiting copy to code </h4>
21
+ <p>If your copy has reached a stable state and you don't need to update it live anymore, you can download your copy as YAML and include it as part of the Ruby on Rails application underneath your main website. You can then remove Copycat from the application entirely, and the website will still run exactly as before--it interfaces with Ruby on Rails's built-in translation mechanisms in a very unobtrusive way.
22
+ </div>
23
+
24
+ </div>
25
+
@@ -1,11 +1,16 @@
1
- <div id="upload">
1
+ <h2>Import</h2>
2
+ <div>
2
3
  <p>
3
4
  Upload a YAML (.yml) file following <a href="http://guides.rubyonrails.org/i18n.html">I18n conventions</a>.
4
5
  </p>
5
- <%= form_tag 'import_yaml', :multipart => true, :'accept-charset' => 'UTF-8' do -%>
6
+ <%= form_tag 'upload', :multipart => true, :'accept-charset' => 'UTF-8' do -%>
6
7
  <%= file_field_tag "file" %>
7
8
  <%= submit_tag "Upload" %>
8
9
  <% end %>
9
- <div class="copycat-alert"> <%= notice %> </div>
10
10
  </div>
11
+ <h2>Export</h2>
12
+ <div>
13
+ <%= link_to "Download as YAML", download_copycat_translations_path %>
14
+ </div>
15
+
11
16
 
@@ -1,17 +1,27 @@
1
- <div class="copycat-notice"> <%= notice %> </div>
2
- <table>
3
- <tr>
4
- <th> Key </th>
5
- <th> Value </th>
6
- </tr>
7
- <% @copycat_translations.each do |t| %>
8
- <tr>
9
- <td class="key">
10
- <%= link_to "#{t.locale}.#{t.key}", edit_copycat_translation_path(t) %>
11
- </td>
12
- <td class="value">
13
- <%= t.value %>
14
- </td>
15
- </tr>
16
- <% end %>
17
- </table>
1
+ <div id="search">
2
+ <%= form_tag copycat_translations_path, :method => :get do -%>
3
+ <% locale_options = options_for_select([nil] + @locale_names.map{|l| [l,l]}, params[:locale]) %>
4
+ <%= select_tag 'locale', locale_options %>
5
+ <%= text_field_tag :search, params[:search], :placeholder => 'Search for keys or values', :size => 40 %>
6
+ <%= submit_tag 'Search' %>
7
+ <% end %>
8
+ </div>
9
+
10
+ <% if @copycat_translations.any? %>
11
+ <table>
12
+ <tr>
13
+ <th> Key </th>
14
+ <th> Value </th>
15
+ </tr>
16
+ <% @copycat_translations.each do |t| %>
17
+ <tr>
18
+ <td class="key">
19
+ <%= link_to "#{t.key}", edit_copycat_translation_path(t) %>
20
+ </td>
21
+ <td class="value">
22
+ <%= t.value %>
23
+ </td>
24
+ </tr>
25
+ <% end %>
26
+ </table>
27
+ <% end %>