interpret 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +488 -0
- data/app/controllers/interpret/search_controller.rb +3 -1
- data/app/controllers/interpret/tools_controller.rb +2 -1
- data/app/controllers/interpret/translations_controller.rb +16 -7
- data/app/models/interpret/expiration_observer.rb +29 -0
- data/app/models/interpret/translation.rb +9 -20
- data/app/views/interpret/tools/index.html.erb +16 -23
- data/app/views/interpret/translations/_listing.html.erb +1 -1
- data/app/views/interpret/translations/live_edit.html.erb +11 -0
- data/app/views/layouts/interpret.html.erb +6 -1
- data/app/views/layouts/interpret_base.html.erb +1 -1
- data/config/routes.rb +4 -0
- data/interpret.gemspec +0 -1
- data/lib/generators/interpret/setup_generator.rb +2 -1
- data/lib/interpret/controller_filter.rb +22 -0
- data/lib/interpret/engine.rb +17 -6
- data/lib/interpret/helpers.rb +39 -0
- data/lib/interpret/version.rb +1 -1
- data/lib/interpret.rb +4 -1
- data/lib/tasks/interpret.rake +4 -2
- data/public/javascripts/facebox-1.3/closelabel.png +0 -0
- data/public/javascripts/facebox-1.3/facebox.css +80 -0
- data/public/javascripts/facebox-1.3/facebox.js +309 -0
- data/public/javascripts/facebox-1.3/loading.gif +0 -0
- data/public/stylesheets/interpret_live_edit_style.css +38 -0
- data/public/stylesheets/interpret_style.css +18 -0
- data/spec/models/translation_spec.rb +33 -22
- data/spec/observers/expiration_observer_spec.rb +17 -0
- data/spec/spec_helper.rb +0 -1
- data/test_app/Gemfile +4 -2
- data/test_app/app/controllers/application_controller.rb +17 -1
- data/test_app/app/controllers/pages_controller.rb +0 -1
- data/test_app/app/models/my_sweeper.rb +5 -0
- data/test_app/app/views/layouts/application.html.erb +115 -5
- data/test_app/app/views/layouts/backoffice.html.erb +27 -0
- data/test_app/app/views/pages/archives.html.erb +3 -0
- data/test_app/app/views/pages/contact.html.erb +3 -0
- data/test_app/app/views/pages/index.html.erb +56 -0
- data/test_app/app/views/pages/links.html.erb +10 -0
- data/test_app/app/views/pages/resources.html.erb +5 -0
- data/test_app/config/application.rb +2 -2
- data/test_app/config/environments/production.rb +0 -5
- data/test_app/config/initializers/interpret.rb +3 -3
- data/test_app/config/locales/en.yml +55 -0
- data/test_app/config/locales/es.yml +3 -47
- data/test_app/config/routes.rb +8 -1
- data/test_app/public/images/a1.gif +0 -0
- data/test_app/public/images/a10.jpg +0 -0
- data/test_app/public/images/a16.gif +0 -0
- data/test_app/public/images/a18.gif +0 -0
- data/test_app/public/images/a22.gif +0 -0
- data/test_app/public/images/a26.gif +0 -0
- data/test_app/public/images/a33.gif +0 -0
- data/test_app/public/images/a36.gif +0 -0
- data/test_app/public/images/a38.gif +0 -0
- data/test_app/public/images/a41.gif +0 -0
- data/test_app/public/images/a47.gif +0 -0
- data/test_app/public/images/a50.gif +0 -0
- data/test_app/public/images/a8.gif +0 -0
- data/test_app/public/images/abg.gif +0 -0
- data/test_app/public/images/pic1.jpg +0 -0
- data/test_app/public/images/pic2.jpg +0 -0
- data/test_app/public/images/spacer.gif +0 -0
- data/test_app/public/images/upbg.gif +0 -0
- data/test_app/public/javascripts/facebox-1.3/closelabel.png +0 -0
- data/test_app/public/javascripts/facebox-1.3/facebox.css +80 -0
- data/test_app/public/javascripts/facebox-1.3/facebox.js +309 -0
- data/test_app/public/javascripts/facebox-1.3/loading.gif +0 -0
- data/test_app/public/stylesheets/default.css +361 -0
- data/test_app/public/stylesheets/interpret_live_edit_style.css +38 -0
- data/test_app/public/stylesheets/interpret_style.css +18 -0
- data/test_app/public/stylesheets/private.css +0 -0
- metadata +96 -29
- data/app/sweepers/interpret/base_sweeper.rb +0 -18
- data/app/sweepers/interpret/translation_sweeper.rb +0 -11
- data/public/javascripts/jquery.purr.js +0 -180
- data/test_app/app/sweepers/page_sweeper.rb +0 -12
- data/test_app/app/views/pages/contact.html.haml +0 -8
- data/test_app/app/views/pages/index.html.haml +0 -10
- data/test_app/config/locales/ca.yml +0 -6
- data/test_app/public/javascripts/jquery.purr.js +0 -180
@@ -0,0 +1,309 @@
|
|
1
|
+
/*
|
2
|
+
* Facebox (for jQuery)
|
3
|
+
* version: 1.2 (05/05/2008)
|
4
|
+
* @requires jQuery v1.2 or later
|
5
|
+
*
|
6
|
+
* Examples at http://famspam.com/facebox/
|
7
|
+
*
|
8
|
+
* Licensed under the MIT:
|
9
|
+
* http://www.opensource.org/licenses/mit-license.php
|
10
|
+
*
|
11
|
+
* Copyright 2007, 2008 Chris Wanstrath [ chris@ozmm.org ]
|
12
|
+
*
|
13
|
+
* Usage:
|
14
|
+
*
|
15
|
+
* jQuery(document).ready(function() {
|
16
|
+
* jQuery('a[rel*=facebox]').facebox()
|
17
|
+
* })
|
18
|
+
*
|
19
|
+
* <a href="#terms" rel="facebox">Terms</a>
|
20
|
+
* Loads the #terms div in the box
|
21
|
+
*
|
22
|
+
* <a href="terms.html" rel="facebox">Terms</a>
|
23
|
+
* Loads the terms.html page in the box
|
24
|
+
*
|
25
|
+
* <a href="terms.png" rel="facebox">Terms</a>
|
26
|
+
* Loads the terms.png image in the box
|
27
|
+
*
|
28
|
+
*
|
29
|
+
* You can also use it programmatically:
|
30
|
+
*
|
31
|
+
* jQuery.facebox('some html')
|
32
|
+
* jQuery.facebox('some html', 'my-groovy-style')
|
33
|
+
*
|
34
|
+
* The above will open a facebox with "some html" as the content.
|
35
|
+
*
|
36
|
+
* jQuery.facebox(function($) {
|
37
|
+
* $.get('blah.html', function(data) { $.facebox(data) })
|
38
|
+
* })
|
39
|
+
*
|
40
|
+
* The above will show a loading screen before the passed function is called,
|
41
|
+
* allowing for a better ajaxy experience.
|
42
|
+
*
|
43
|
+
* The facebox function can also display an ajax page, an image, or the contents of a div:
|
44
|
+
*
|
45
|
+
* jQuery.facebox({ ajax: 'remote.html' })
|
46
|
+
* jQuery.facebox({ ajax: 'remote.html' }, 'my-groovy-style')
|
47
|
+
* jQuery.facebox({ image: 'stairs.jpg' })
|
48
|
+
* jQuery.facebox({ image: 'stairs.jpg' }, 'my-groovy-style')
|
49
|
+
* jQuery.facebox({ div: '#box' })
|
50
|
+
* jQuery.facebox({ div: '#box' }, 'my-groovy-style')
|
51
|
+
*
|
52
|
+
* Want to close the facebox? Trigger the 'close.facebox' document event:
|
53
|
+
*
|
54
|
+
* jQuery(document).trigger('close.facebox')
|
55
|
+
*
|
56
|
+
* Facebox also has a bunch of other hooks:
|
57
|
+
*
|
58
|
+
* loading.facebox
|
59
|
+
* beforeReveal.facebox
|
60
|
+
* reveal.facebox (aliased as 'afterReveal.facebox')
|
61
|
+
* init.facebox
|
62
|
+
* afterClose.facebox
|
63
|
+
*
|
64
|
+
* Simply bind a function to any of these hooks:
|
65
|
+
*
|
66
|
+
* $(document).bind('reveal.facebox', function() { ...stuff to do after the facebox and contents are revealed... })
|
67
|
+
*
|
68
|
+
*/
|
69
|
+
(function($) {
|
70
|
+
$.facebox = function(data, klass) {
|
71
|
+
$.facebox.loading()
|
72
|
+
|
73
|
+
if (data.ajax) fillFaceboxFromAjax(data.ajax, klass)
|
74
|
+
else if (data.image) fillFaceboxFromImage(data.image, klass)
|
75
|
+
else if (data.div) fillFaceboxFromHref(data.div, klass)
|
76
|
+
else if ($.isFunction(data)) data.call($)
|
77
|
+
else $.facebox.reveal(data, klass)
|
78
|
+
}
|
79
|
+
|
80
|
+
/*
|
81
|
+
* Public, $.facebox methods
|
82
|
+
*/
|
83
|
+
|
84
|
+
$.extend($.facebox, {
|
85
|
+
settings: {
|
86
|
+
opacity : 0.2,
|
87
|
+
overlay : true,
|
88
|
+
loadingImage : '/javascripts/facebox-1.3/loading.gif',
|
89
|
+
closeImage : '/javascripts/facebox-1.3/closelabel.png',
|
90
|
+
imageTypes : [ 'png', 'jpg', 'jpeg', 'gif' ],
|
91
|
+
faceboxHtml : '\
|
92
|
+
<div id="facebox" style="display:none;"> \
|
93
|
+
<div class="popup"> \
|
94
|
+
<div class="content"> \
|
95
|
+
</div> \
|
96
|
+
<a href="#" class="close"><img src="/javascripts/facebox-1.3/closelabel.png" title="close" class="close_image" /></a> \
|
97
|
+
</div> \
|
98
|
+
</div>'
|
99
|
+
},
|
100
|
+
|
101
|
+
loading: function() {
|
102
|
+
init()
|
103
|
+
if ($('#facebox .loading').length == 1) return true
|
104
|
+
showOverlay()
|
105
|
+
|
106
|
+
$('#facebox .content').empty()
|
107
|
+
$('#facebox .body').children().hide().end().
|
108
|
+
append('<div class="loading"><img src="'+$.facebox.settings.loadingImage+'"/></div>')
|
109
|
+
|
110
|
+
$('#facebox').css({
|
111
|
+
top: getPageScroll()[1] + (getPageHeight() / 10),
|
112
|
+
left: $(window).width() / 2 - 205
|
113
|
+
}).show()
|
114
|
+
|
115
|
+
$(document).bind('keydown.facebox', function(e) {
|
116
|
+
if (e.keyCode == 27) $.facebox.close()
|
117
|
+
return true
|
118
|
+
})
|
119
|
+
$(document).trigger('loading.facebox')
|
120
|
+
},
|
121
|
+
|
122
|
+
reveal: function(data, klass) {
|
123
|
+
$(document).trigger('beforeReveal.facebox')
|
124
|
+
if (klass) $('#facebox .content').addClass(klass)
|
125
|
+
$('#facebox .content').append(data)
|
126
|
+
$('#facebox .loading').remove()
|
127
|
+
$('#facebox .body').children().fadeIn('normal')
|
128
|
+
$('#facebox').css('left', $(window).width() / 2 - ($('#facebox .popup').width() / 2))
|
129
|
+
$(document).trigger('reveal.facebox').trigger('afterReveal.facebox')
|
130
|
+
},
|
131
|
+
|
132
|
+
close: function() {
|
133
|
+
$(document).trigger('close.facebox')
|
134
|
+
return false
|
135
|
+
}
|
136
|
+
})
|
137
|
+
|
138
|
+
/*
|
139
|
+
* Public, $.fn methods
|
140
|
+
*/
|
141
|
+
|
142
|
+
$.fn.facebox = function(settings) {
|
143
|
+
if ($(this).length == 0) return
|
144
|
+
|
145
|
+
init(settings)
|
146
|
+
|
147
|
+
function clickHandler() {
|
148
|
+
$.facebox.loading(true)
|
149
|
+
|
150
|
+
// support for rel="facebox.inline_popup" syntax, to add a class
|
151
|
+
// also supports deprecated "facebox[.inline_popup]" syntax
|
152
|
+
var klass = this.rel.match(/facebox\[?\.(\w+)\]?/)
|
153
|
+
if (klass) klass = klass[1]
|
154
|
+
|
155
|
+
fillFaceboxFromHref(this.href, klass)
|
156
|
+
return false
|
157
|
+
}
|
158
|
+
|
159
|
+
return this.bind('click.facebox', clickHandler)
|
160
|
+
}
|
161
|
+
|
162
|
+
/*
|
163
|
+
* Private methods
|
164
|
+
*/
|
165
|
+
|
166
|
+
// called one time to setup facebox on this page
|
167
|
+
function init(settings) {
|
168
|
+
if ($.facebox.settings.inited) return true
|
169
|
+
else $.facebox.settings.inited = true
|
170
|
+
|
171
|
+
$(document).trigger('init.facebox')
|
172
|
+
makeCompatible()
|
173
|
+
|
174
|
+
var imageTypes = $.facebox.settings.imageTypes.join('|')
|
175
|
+
$.facebox.settings.imageTypesRegexp = new RegExp('\.(' + imageTypes + ')$', 'i')
|
176
|
+
|
177
|
+
if (settings) $.extend($.facebox.settings, settings)
|
178
|
+
$('body').append($.facebox.settings.faceboxHtml)
|
179
|
+
|
180
|
+
var preload = [ new Image(), new Image() ]
|
181
|
+
preload[0].src = $.facebox.settings.closeImage
|
182
|
+
preload[1].src = $.facebox.settings.loadingImage
|
183
|
+
|
184
|
+
$('#facebox').find('.b:first, .bl').each(function() {
|
185
|
+
preload.push(new Image())
|
186
|
+
preload.slice(-1).src = $(this).css('background-image').replace(/url\((.+)\)/, '$1')
|
187
|
+
})
|
188
|
+
|
189
|
+
$('#facebox .close').click($.facebox.close)
|
190
|
+
$('#facebox .close_image').attr('src', $.facebox.settings.closeImage)
|
191
|
+
}
|
192
|
+
|
193
|
+
// getPageScroll() by quirksmode.com
|
194
|
+
function getPageScroll() {
|
195
|
+
var xScroll, yScroll;
|
196
|
+
if (self.pageYOffset) {
|
197
|
+
yScroll = self.pageYOffset;
|
198
|
+
xScroll = self.pageXOffset;
|
199
|
+
} else if (document.documentElement && document.documentElement.scrollTop) { // Explorer 6 Strict
|
200
|
+
yScroll = document.documentElement.scrollTop;
|
201
|
+
xScroll = document.documentElement.scrollLeft;
|
202
|
+
} else if (document.body) {// all other Explorers
|
203
|
+
yScroll = document.body.scrollTop;
|
204
|
+
xScroll = document.body.scrollLeft;
|
205
|
+
}
|
206
|
+
return new Array(xScroll,yScroll)
|
207
|
+
}
|
208
|
+
|
209
|
+
// Adapted from getPageSize() by quirksmode.com
|
210
|
+
function getPageHeight() {
|
211
|
+
var windowHeight
|
212
|
+
if (self.innerHeight) { // all except Explorer
|
213
|
+
windowHeight = self.innerHeight;
|
214
|
+
} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
|
215
|
+
windowHeight = document.documentElement.clientHeight;
|
216
|
+
} else if (document.body) { // other Explorers
|
217
|
+
windowHeight = document.body.clientHeight;
|
218
|
+
}
|
219
|
+
return windowHeight
|
220
|
+
}
|
221
|
+
|
222
|
+
// Backwards compatibility
|
223
|
+
function makeCompatible() {
|
224
|
+
var $s = $.facebox.settings
|
225
|
+
|
226
|
+
$s.loadingImage = $s.loading_image || $s.loadingImage
|
227
|
+
$s.closeImage = $s.close_image || $s.closeImage
|
228
|
+
$s.imageTypes = $s.image_types || $s.imageTypes
|
229
|
+
$s.faceboxHtml = $s.facebox_html || $s.faceboxHtml
|
230
|
+
}
|
231
|
+
|
232
|
+
// Figures out what you want to display and displays it
|
233
|
+
// formats are:
|
234
|
+
// div: #id
|
235
|
+
// image: blah.extension
|
236
|
+
// ajax: anything else
|
237
|
+
function fillFaceboxFromHref(href, klass) {
|
238
|
+
// div
|
239
|
+
if (href.match(/#/)) {
|
240
|
+
var url = window.location.href.split('#')[0]
|
241
|
+
var target = href.replace(url,'')
|
242
|
+
if (target == '#') return
|
243
|
+
$.facebox.reveal($(target).html(), klass)
|
244
|
+
|
245
|
+
// image
|
246
|
+
} else if (href.match($.facebox.settings.imageTypesRegexp)) {
|
247
|
+
fillFaceboxFromImage(href, klass)
|
248
|
+
// ajax
|
249
|
+
} else {
|
250
|
+
fillFaceboxFromAjax(href, klass)
|
251
|
+
}
|
252
|
+
}
|
253
|
+
|
254
|
+
function fillFaceboxFromImage(href, klass) {
|
255
|
+
var image = new Image()
|
256
|
+
image.onload = function() {
|
257
|
+
$.facebox.reveal('<div class="image"><img src="' + image.src + '" /></div>', klass)
|
258
|
+
}
|
259
|
+
image.src = href
|
260
|
+
}
|
261
|
+
|
262
|
+
function fillFaceboxFromAjax(href, klass) {
|
263
|
+
$.get(href, function(data) { $.facebox.reveal(data, klass) })
|
264
|
+
}
|
265
|
+
|
266
|
+
function skipOverlay() {
|
267
|
+
return $.facebox.settings.overlay == false || $.facebox.settings.opacity === null
|
268
|
+
}
|
269
|
+
|
270
|
+
function showOverlay() {
|
271
|
+
if (skipOverlay()) return
|
272
|
+
|
273
|
+
if ($('#facebox_overlay').length == 0)
|
274
|
+
$("body").append('<div id="facebox_overlay" class="facebox_hide"></div>')
|
275
|
+
|
276
|
+
$('#facebox_overlay').hide().addClass("facebox_overlayBG")
|
277
|
+
.css('opacity', $.facebox.settings.opacity)
|
278
|
+
.click(function() { $(document).trigger('close.facebox') })
|
279
|
+
.fadeIn(200)
|
280
|
+
return false
|
281
|
+
}
|
282
|
+
|
283
|
+
function hideOverlay() {
|
284
|
+
if (skipOverlay()) return
|
285
|
+
|
286
|
+
$('#facebox_overlay').fadeOut(200, function(){
|
287
|
+
$("#facebox_overlay").removeClass("facebox_overlayBG")
|
288
|
+
$("#facebox_overlay").addClass("facebox_hide")
|
289
|
+
$("#facebox_overlay").remove()
|
290
|
+
})
|
291
|
+
|
292
|
+
return false
|
293
|
+
}
|
294
|
+
|
295
|
+
/*
|
296
|
+
* Bindings
|
297
|
+
*/
|
298
|
+
|
299
|
+
$(document).bind('close.facebox', function() {
|
300
|
+
$(document).unbind('keydown.facebox')
|
301
|
+
$('#facebox').fadeOut(function() {
|
302
|
+
$('#facebox .content').removeClass().addClass('content')
|
303
|
+
$('#facebox .loading').remove()
|
304
|
+
$(document).trigger('afterClose.facebox')
|
305
|
+
})
|
306
|
+
hideOverlay()
|
307
|
+
})
|
308
|
+
|
309
|
+
})(jQuery);
|
Binary file
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#interpret_live_edit {
|
2
|
+
padding-top: 15px;
|
3
|
+
padding-right: 16px;
|
4
|
+
width: 700px;
|
5
|
+
min-height: 300px;
|
6
|
+
text-align: center;
|
7
|
+
}
|
8
|
+
|
9
|
+
#interpret_live_edit textarea {
|
10
|
+
width: 100%;
|
11
|
+
height: 31em;
|
12
|
+
}
|
13
|
+
|
14
|
+
#interpret_live_edit input[type=submit] {
|
15
|
+
background-color: #555;
|
16
|
+
color: #FFF;
|
17
|
+
border: none;
|
18
|
+
font-size: 1em;
|
19
|
+
margin-top: .5em;
|
20
|
+
padding: .6em 1.5em;
|
21
|
+
cursor: hand;
|
22
|
+
cursor: pointer;
|
23
|
+
border-radius: 5px;
|
24
|
+
}
|
25
|
+
|
26
|
+
#interpret_live_edit input[type=submit]:hover {
|
27
|
+
background-color: #777;
|
28
|
+
}
|
29
|
+
|
30
|
+
.interpret_editable {
|
31
|
+
background-color: #F8FD7D;
|
32
|
+
cursor: hand;
|
33
|
+
cursor: pointer;
|
34
|
+
}
|
35
|
+
.interpret_editable:hover {
|
36
|
+
background-color: #FCF305;
|
37
|
+
}
|
38
|
+
|
@@ -521,3 +521,21 @@ html body * dd.clear
|
|
521
521
|
#interpret_container #tree_sidebar a:hover {
|
522
522
|
text-decoration: underline;
|
523
523
|
}
|
524
|
+
|
525
|
+
#interpret_container .interpret_flash {
|
526
|
+
width: 95%;
|
527
|
+
min-height: 0.8em;
|
528
|
+
padding: 1em;
|
529
|
+
margin-bottom: 0.5em;
|
530
|
+
text-align: center;
|
531
|
+
}
|
532
|
+
|
533
|
+
#interpret_container .interpret_flash.notice {
|
534
|
+
background-color: #BBFFBB;
|
535
|
+
border: 1px solid #55FF55;
|
536
|
+
}
|
537
|
+
#interpret_container .interpret_flash.alert {
|
538
|
+
background-color: #FFBBBB;
|
539
|
+
border: 1px solid #FF5555;
|
540
|
+
}
|
541
|
+
|
@@ -88,7 +88,7 @@ es:
|
|
88
88
|
if dict[x].kind_of?(Hash)
|
89
89
|
res += parse_hash(dict[x], locale, "#{prefix}#{x}.")
|
90
90
|
else
|
91
|
-
res << Interpret::Translation.
|
91
|
+
res << Interpret::Translation.create!(:locale => locale, :key => "#{prefix}#{x}", :value => dict[x])
|
92
92
|
end
|
93
93
|
end
|
94
94
|
res
|
@@ -102,6 +102,7 @@ es:
|
|
102
102
|
end
|
103
103
|
|
104
104
|
before do
|
105
|
+
Interpret::Translation.delete_all
|
105
106
|
I18n.stub!(:default_locale).and_return('en')
|
106
107
|
end
|
107
108
|
|
@@ -132,7 +133,7 @@ es:
|
|
132
133
|
end
|
133
134
|
|
134
135
|
describe ".update" do
|
135
|
-
before
|
136
|
+
before do
|
136
137
|
# Supose the database has the default contents, look at the top of this
|
137
138
|
# file for en_yml simulated locale file
|
138
139
|
file2db(en_yml)
|
@@ -144,15 +145,21 @@ es:
|
|
144
145
|
YAML.should_receive(:load_file).twice.and_return(YAML.load(new_en_yml), YAML.load(new_es_yml))
|
145
146
|
end
|
146
147
|
|
147
|
-
context "when
|
148
|
-
|
149
|
-
Interpret
|
150
|
-
Interpret::Translation.locale('en').find_by_key("folder1.content").should be_nil
|
148
|
+
context "when Interpret.soft is false" do
|
149
|
+
before do
|
150
|
+
Interpret.soft = false
|
151
151
|
end
|
152
152
|
|
153
|
-
|
154
|
-
|
155
|
-
|
153
|
+
context "when a key exists in database but not in yml files [for I18n.default_locale]" do
|
154
|
+
it "should remove that key from database for I18n.default_locale" do
|
155
|
+
Interpret::Translation.update
|
156
|
+
Interpret::Translation.locale('en').find_by_key("folder1.content").should be_nil
|
157
|
+
end
|
158
|
+
|
159
|
+
it "should remove that key if it exists for any other language in database" do
|
160
|
+
Interpret::Translation.update
|
161
|
+
Interpret::Translation.locale('es').find_by_key("folder1.content").should be_nil
|
162
|
+
end
|
156
163
|
end
|
157
164
|
end
|
158
165
|
|
@@ -190,22 +197,26 @@ es:
|
|
190
197
|
end
|
191
198
|
|
192
199
|
describe ".dump" do
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
file2db(es_yml)
|
200
|
+
context "when Interpret.soft is false" do
|
201
|
+
it "should dump all contents from yml files into database" do
|
202
|
+
Interpret.soft = false
|
197
203
|
|
198
|
-
|
199
|
-
|
200
|
-
|
204
|
+
# Initial database state
|
205
|
+
file2db(en_yml)
|
206
|
+
file2db(es_yml)
|
201
207
|
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
Interpret::Translation.export(en_trans).should == YAML.load(new_en_yml)
|
208
|
+
Dir.stub!(:"[]").and_return(['/path/to/en.yml', '/path/to/es.yml'])
|
209
|
+
YAML.should_receive(:load_file).twice.and_return(YAML.load(new_en_yml), YAML.load(new_es_yml))
|
210
|
+
Interpret::Translation.dump
|
206
211
|
|
207
|
-
|
208
|
-
|
212
|
+
# We use export to check for the existing database contents, which is
|
213
|
+
# also tested in this spec file
|
214
|
+
en_trans = Interpret::Translation.locale('en').all
|
215
|
+
Interpret::Translation.export(en_trans).should == YAML.load(new_en_yml)
|
216
|
+
|
217
|
+
es_trans = Interpret::Translation.locale('es').all
|
218
|
+
Interpret::Translation.export(es_trans).should == YAML.load(new_es_yml)
|
219
|
+
end
|
209
220
|
end
|
210
221
|
end
|
211
222
|
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Interpret::ExpirationObserver do
|
5
|
+
|
6
|
+
before do
|
7
|
+
Interpret::Translation.delete_all
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should call run_expiration on observer" do
|
11
|
+
backend = mock("A backend")
|
12
|
+
backend.should_receive(:"reload!").once
|
13
|
+
Interpret.backend = backend
|
14
|
+
Interpret::Translation.create! :locale => "en", :key => "en.hello", :value => "Hello world"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
data/spec/spec_helper.rb
CHANGED
data/test_app/Gemfile
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
source 'http://rubygems.org'
|
2
2
|
|
3
|
-
gem 'rails', '~> 3.0.
|
4
|
-
gem 'interpret', :path => ".."
|
3
|
+
gem 'rails', '~> 3.0.5'
|
5
4
|
gem 'haml-rails'
|
6
5
|
gem 'capistrano'
|
7
6
|
|
8
7
|
group :development, :test do
|
9
8
|
gem 'sqlite3-ruby', :require => 'sqlite3'
|
9
|
+
gem 'ruby-debug'
|
10
10
|
end
|
11
|
+
|
12
|
+
gem 'interpret', :path => ".."
|
@@ -2,9 +2,10 @@ class ApplicationController < ActionController::Base
|
|
2
2
|
protect_from_forgery
|
3
3
|
before_filter :set_current_user
|
4
4
|
helper_method :current_user
|
5
|
+
before_filter :set_locale
|
5
6
|
|
6
7
|
def current_user
|
7
|
-
session[:user_id] ? User.find(session[:user_id]) : User.first
|
8
|
+
session[:user_id] ? User.find(session[:user_id]) : User.where(:admin => true).first
|
8
9
|
end
|
9
10
|
|
10
11
|
def set_current_user
|
@@ -12,4 +13,19 @@ class ApplicationController < ActionController::Base
|
|
12
13
|
session[:user_id] = params[:admin] == "true" ? User.where(:admin => true).first : User.where(:admin => false).first
|
13
14
|
end
|
14
15
|
end
|
16
|
+
|
17
|
+
def toggle_edition_mode
|
18
|
+
Interpret.live_edit = !Interpret.live_edit
|
19
|
+
|
20
|
+
redirect_to request.env["HTTP_REFERER"]
|
21
|
+
end
|
22
|
+
|
23
|
+
def set_locale
|
24
|
+
I18n.locale = params[:locale] || I18n.default_locale
|
25
|
+
end
|
26
|
+
|
27
|
+
def default_url_options(options = {})
|
28
|
+
options.merge({:locale => I18n.locale})
|
29
|
+
end
|
30
|
+
|
15
31
|
end
|
@@ -1,15 +1,125 @@
|
|
1
1
|
<!DOCTYPE html>
|
2
2
|
<html>
|
3
3
|
<head>
|
4
|
-
<title>
|
5
|
-
<%= stylesheet_link_tag
|
4
|
+
<title>Interpret Demo</title>
|
5
|
+
<%= stylesheet_link_tag "default" %>
|
6
6
|
<%= javascript_include_tag "https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js" %>
|
7
|
-
<%= javascript_include_tag :all %>
|
8
7
|
<%= csrf_meta_tag %>
|
9
8
|
</head>
|
10
9
|
<body>
|
11
|
-
|
12
|
-
|
10
|
+
<div id="demo_sidebar">
|
11
|
+
<p>
|
12
|
+
This is a DEMO site to provide an example usage of <a href="https://github.com/rogercampos/interpret">Interpret</a>.
|
13
|
+
</p>
|
14
|
+
|
15
|
+
<p>
|
16
|
+
<ul>
|
17
|
+
<li>
|
18
|
+
<%= link_to "Login to interpret as ADMIN", interpret_root_path(:admin => "true") %>
|
19
|
+
</li>
|
20
|
+
<li>
|
21
|
+
<%= link_to "Login to interpret as USER", interpret_root_path(:admin => "false") %>
|
22
|
+
</li>
|
23
|
+
</ul>
|
24
|
+
</p>
|
25
|
+
<br/>
|
26
|
+
|
27
|
+
<p>
|
28
|
+
<% if current_user %>
|
29
|
+
You are currently logged in as <%= current_user.admin? ? "an ADMIN" : "an USER" %>
|
30
|
+
<% else %>
|
31
|
+
You are not logged in
|
32
|
+
<% end %>
|
33
|
+
</p>
|
34
|
+
<p>
|
35
|
+
<% if current_user && current_user.admin? %>
|
36
|
+
<%= button_to Interpret.live_edit ? "Disable edition mode" : "Enable edition mode", toggle_edition_mode_path %>
|
37
|
+
<% else %>
|
38
|
+
Log in as an ADMIN to use the live edition features!
|
39
|
+
<% end %>
|
40
|
+
</p>
|
41
|
+
|
42
|
+
<br/>
|
43
|
+
<p>You can reestore the original contents with the option "Dump", inside the backoffice > Tools section.</p>
|
44
|
+
<p>
|
45
|
+
Thanks to <a href="http://nodethirtythree.com">NodeThirtyThree</a> to provide this template in order to demostrate a real website.
|
46
|
+
</p>
|
47
|
+
</div>
|
48
|
+
|
49
|
+
<div id="outer">
|
50
|
+
|
51
|
+
<div id="upbg"></div>
|
52
|
+
|
53
|
+
<div id="inner">
|
54
|
+
|
55
|
+
<div id="header">
|
56
|
+
<h1><%= t "main_header_html" %></h1>
|
57
|
+
<h2><%= t "main_h2" %></h2>
|
58
|
+
</div>
|
59
|
+
|
60
|
+
<div id="splash"></div>
|
61
|
+
|
62
|
+
<div id="menu">
|
63
|
+
<ul>
|
64
|
+
<li class="first"><a href="/">Home</a></li>
|
65
|
+
<li><%= link_to "Archives", archives_path %></li>
|
66
|
+
<li><%= link_to "Links", links_path %></li>
|
67
|
+
<li><%= link_to "Resources", resources_path %></li>
|
68
|
+
<li><%= link_to "Contact", contact_path %></li>
|
69
|
+
</ul>
|
70
|
+
|
71
|
+
<div id="lang_menu">
|
72
|
+
Language:
|
73
|
+
<%= link_to "English", :locale => :en %>
|
74
|
+
|
|
75
|
+
<%= link_to "Spanish", :locale => :es %>
|
76
|
+
</div>
|
77
|
+
</div>
|
78
|
+
|
79
|
+
|
80
|
+
<div id="primarycontent">
|
81
|
+
<%= yield %>
|
82
|
+
</div>
|
83
|
+
|
84
|
+
<div id="secondarycontent">
|
85
|
+
|
86
|
+
<!-- secondary content start -->
|
87
|
+
|
88
|
+
<h3><%= t "about_me" %></h3>
|
89
|
+
<div class="content">
|
90
|
+
<img src="/images/pic2.jpg" class="picB" alt="" />
|
91
|
+
<p><%= t "about_me_text_html" %></p>
|
92
|
+
</div>
|
93
|
+
|
94
|
+
<h3><%= t "topics" %></h3>
|
95
|
+
<div class="content">
|
96
|
+
<ul class="linklist">
|
97
|
+
<li class="first"><%= t "t1_html", :scope => "topics_list" %></li>
|
98
|
+
<li><%= t "t2_html", :scope => "topics_list" %></li>
|
99
|
+
<li><%= t "t3_html", :scope => "topics_list" %></li>
|
100
|
+
<li><%= t "t4_html", :scope => "topics_list" %></li>
|
101
|
+
<li><%= t "t5_html", :scope => "topics_list" %></li>
|
102
|
+
<li><%= t "t6_html", :scope => "topics_list" %></li>
|
103
|
+
<li><%= t "t7_html", :scope => "topics_list" %></li>
|
104
|
+
<li><%= t "t8_html", :scope => "topics_list" %></li>
|
105
|
+
</ul>
|
106
|
+
</div>
|
107
|
+
|
108
|
+
<!-- secondary content end -->
|
109
|
+
|
110
|
+
</div>
|
111
|
+
|
112
|
+
<div id="footer">
|
113
|
+
|
114
|
+
© My Website. All rights reserved. Design by <a href="http://www.nodethirtythree.com/">NodeThirtyThree</a>.
|
115
|
+
|
116
|
+
</div>
|
117
|
+
|
118
|
+
</div>
|
119
|
+
|
120
|
+
</div>
|
121
|
+
|
122
|
+
<%= interpret_live_edition %>
|
13
123
|
</body>
|
14
124
|
</html>
|
15
125
|
|