olelo 0.9.4 → 0.9.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. data/.gitignore +0 -1
  2. data/.travis.yml +8 -0
  3. data/README.creole +31 -11
  4. data/Rakefile +46 -21
  5. data/config/aspects.rb +19 -15
  6. data/lib/olelo/application.rb +2 -3
  7. data/lib/olelo/extensions.rb +3 -0
  8. data/lib/olelo/helper.rb +7 -5
  9. data/lib/olelo/locale.rb +1 -1
  10. data/lib/olelo/locale.yml +298 -204
  11. data/lib/olelo/page.rb +9 -1
  12. data/lib/olelo/plugin.rb +1 -1
  13. data/lib/olelo/repository.rb +1 -1
  14. data/lib/olelo/util.rb +3 -0
  15. data/lib/olelo/version.rb +1 -1
  16. data/olelo.gemspec +1 -1
  17. data/plugins/aspects/changelog.rb +7 -4
  18. data/plugins/aspects/locale.yml +69 -47
  19. data/plugins/blog/locale.yml +13 -9
  20. data/plugins/editor/locale.yml +16 -11
  21. data/plugins/filters/creole.rb +3 -6
  22. data/plugins/filters/fix_image_links.rb +20 -0
  23. data/plugins/filters/locale.yml +18 -13
  24. data/plugins/filters/s5/main.rb +2 -0
  25. data/plugins/login/locale.yml +6 -4
  26. data/plugins/repositories/gitrb_repository.rb +1 -1
  27. data/plugins/repositories/locale.yml +14 -10
  28. data/plugins/repositories/rugged_repository.rb +2 -3
  29. data/plugins/security/locale.yml +19 -13
  30. data/plugins/tags/math.rb +2 -1
  31. data/plugins/treeview/script.js +2 -2
  32. data/plugins/treeview/script/init.js +4 -0
  33. data/plugins/utils/xml.rb +14 -0
  34. data/static/script.js +296 -256
  35. data/static/script/02-history.js +1943 -0
  36. data/static/script/03-history.adapter.jquery.js +77 -0
  37. data/static/script/{03-jquery.ui.core.js → 04-jquery.ui.core.js} +0 -0
  38. data/static/script/{04-jquery.ui.widget.js → 05-jquery.ui.widget.js} +0 -0
  39. data/static/script/{05-jquery.ui.position.js → 06-jquery.ui.position.js} +0 -0
  40. data/static/script/{06-jquery.ui.menu.js → 07-jquery.ui.menu.js} +0 -0
  41. data/static/script/{07-jquery.ui.autocomplete.js → 08-jquery.ui.autocomplete.js} +0 -0
  42. data/static/script/{02-olelo.storage.js → 09-olelo.storage.js} +0 -0
  43. data/static/script/{08-olelo.i18n.js → 10-olelo.i18n.js} +0 -0
  44. data/static/script/{09-olelo.unsaved.js → 11-olelo.unsaved.js} +6 -2
  45. data/static/script/{10-olelo.historytable.js → 12-olelo.historytable.js} +0 -0
  46. data/static/script/13-olelo.pagination.js +30 -0
  47. data/static/script/{13-olelo.tabwidget.js → 14-olelo.tabwidget.js} +0 -0
  48. data/static/script/{14-olelo.timeago.js → 15-olelo.timeago.js} +14 -1
  49. data/static/script/{15-olelo.underliner.js → 16-olelo.underliner.js} +0 -0
  50. data/static/script/{16-olelo.ui.combobox.js → 17-olelo.ui.combobox.js} +0 -0
  51. data/static/script/init.js +10 -10
  52. data/static/themes/atlantis/screen.scss +11 -10
  53. data/static/themes/atlantis/style.css +1 -1
  54. data/test/config_test.rb +9 -0
  55. data/test/factory_test.rb +1 -1
  56. data/test/hash_extensions_test.rb +1 -1
  57. data/test/helper.rb +0 -1
  58. data/test/hooks_test.rb +1 -2
  59. data/test/object_extensions_test.rb +1 -2
  60. data/test/run.rb +12 -0
  61. data/test/string_extensions_test.rb +1 -1
  62. data/test/templates_test.rb +1 -3
  63. data/test/util_test.rb +1 -6
  64. data/views/compare.slim +4 -5
  65. data/views/edit.slim +2 -2
  66. data/views/history.slim +1 -1
  67. data/views/layout.slim +1 -2
  68. data/views/not_found.slim +2 -2
  69. data/views/show.slim +3 -4
  70. metadata +47 -44
  71. data/plugins/filters/fix_img_tag.rb +0 -16
  72. data/static/script/11-olelo.pagination.js +0 -18
@@ -23,15 +23,19 @@ module Olelo
23
23
  # Pattern for valid paths
24
24
  # @api public
25
25
  PATH_PATTERN = '[^\s](?:.*[^\s]+)?'.freeze
26
+
26
27
  PATH_REGEXP = /^#{PATH_PATTERN}$/
28
+ private_constant :PATH_REGEXP
27
29
 
28
30
  # Mime type for empty page
29
31
  # @api public
30
32
  EMPTY_MIME = MimeMagic.new('inode/x-empty')
33
+ private_constant :EMPTY_MIME
31
34
 
32
35
  # Mime type for directory
33
36
  # @api public
34
37
  DIRECTORY_MIME = MimeMagic.new('inode/directory')
38
+ private_constant :DIRECTORY_MIME
35
39
 
36
40
  attr_reader :path, :tree_version
37
41
 
@@ -80,6 +84,10 @@ module Olelo
80
84
  path.empty?
81
85
  end
82
86
 
87
+ def editable?
88
+ mime.text? || mime == EMPTY_MIME || mime == DIRECTORY_MIME
89
+ end
90
+
83
91
  def next_version
84
92
  init_versions
85
93
  @next_version
@@ -95,7 +103,7 @@ module Olelo
95
103
  @version
96
104
  end
97
105
 
98
- def history(skip = nil, limit = nil)
106
+ def history(skip, limit)
99
107
  raise 'Page is new' if new?
100
108
  repository.get_history(path, skip, limit)
101
109
  end
@@ -66,7 +66,7 @@ module Olelo
66
66
  Olelo.logger.warn "Plugin #{path} could not be loaded due to: #{ex.message} (Missing gem?)"
67
67
  else
68
68
  Olelo.logger.error "Plugin #{path} could not be loaded due to: #{ex.message}"
69
- Olelo.logger.error ex
69
+ Olelo.logger.debug ex
70
70
  end
71
71
  @loaded.delete(path)
72
72
  false
@@ -159,7 +159,7 @@ module Olelo
159
159
  # @param [Integer] Maximum number of versions to load
160
160
  # @return [Array<Version>]
161
161
  # @api public
162
- def get_history(path, skip = nil, limit = nil)
162
+ def get_history(path, skip, limit)
163
163
  raise NotImplementedError
164
164
  end
165
165
 
@@ -93,6 +93,7 @@ module Olelo
93
93
  # Hash used by {#escape_javascript}
94
94
  # @api private
95
95
  JAVASCRIPT_ESCAPE = { '&' => '\u0026', '>' => '\u003E', '<' => '\u003C' }
96
+ private_constant :JAVASCRIPT_ESCAPE
96
97
 
97
98
  # Escape javascript code for embedding in html
98
99
  #
@@ -200,6 +201,8 @@ module Olelo
200
201
  (0x10000..0x10FFFF)
201
202
  ]
202
203
 
204
+ private_constant :VALID_XML_CHARS
205
+
203
206
  # Check if string contains only characters which are valid in XML
204
207
  #
205
208
  # @see http://www.w3.org/TR/REC-xml/#charsets XML charset
@@ -1,3 +1,3 @@
1
1
  module Olelo
2
- VERSION = '0.9.4'
2
+ VERSION = '0.9.5'
3
3
  end
@@ -21,7 +21,7 @@ Gem::Specification.new do |s|
21
21
 
22
22
  s.add_runtime_dependency('multi_json', ['~> 1.3.6'])
23
23
  s.add_runtime_dependency('slim', ['~> 1.3.3'])
24
- s.add_runtime_dependency('creole', ['~> 0.4.2'])
24
+ s.add_runtime_dependency('creole', ['~> 0.5.0'])
25
25
  s.add_runtime_dependency('nokogiri', ['~> 1.5.5'])
26
26
  s.add_runtime_dependency('mimemagic', ['~> 0.2.0'])
27
27
  s.add_runtime_dependency('rack', ['~> 1.4.1'])
@@ -9,19 +9,22 @@ Aspect.create(:changelog, cacheable: true, hidden: true) do
9
9
  url = context.request.base_url
10
10
  context.header['Content-Type'] = "application/#{format == 'rss' ? 'rss' : 'atom'}+xml; charset=utf-8"
11
11
 
12
+ per_page = 30
13
+ page_nr = [context.params[:page].to_i, 1].max
14
+ history = page.history((page_nr - 1) * per_page, per_page)
15
+
12
16
  content = RSS::Maker.make(format == 'rss' ? '2.0' : 'atom') do |feed|
13
17
  feed.channel.generator = 'Ōlelo'
14
18
  feed.channel.title = Config['title']
15
- feed.channel.link = url + '/' + page.path
19
+ feed.channel.id = feed.channel.link = url + '/' + page.path
16
20
  feed.channel.description = Config['title'] + ' Changelog'
17
- feed.channel.id = url + page.path
18
21
  feed.channel.updated = Time.now
19
22
  feed.channel.author = Config['title']
20
23
  feed.items.do_sort = true
21
- page.history.each do |version|
24
+ history.each do |version|
22
25
  i = feed.items.new_item
23
26
  i.title = version.comment
24
- i.link = url + '/changes'/version
27
+ i.link = "#{url}/changes/#{version}"
25
28
  i.date = version.date
26
29
  i.dc_creator = version.author.name
27
30
  end
@@ -1,65 +1,87 @@
1
- en:
2
- attribute_aspect: 'Default Aspect'
3
- download: 'Download'
1
+ cs_CZ:
4
2
  aspect_documentbrowser: 'Document Browser'
5
- aspect_download: 'Raw Download'
6
- aspect_pageinfo: 'Page Information'
7
- aspect_highlight: 'Highlighted Source'
8
- aspect_imageinfo: 'Image Information'
9
- aspect_image: 'Raw Image'
10
- aspect_source: 'Page Source'
11
- aspect_subpages: 'Subpages'
12
- aspect_text: 'Text Download'
13
- aspect_gallery: 'Image Gallery'
14
- aspect_s5: 'S5 Presentation'
3
+ aspect_download: 'Stažení (neupraveno)'
4
+ aspect_gallery: 'Galerie'
5
+ aspect_highlight: 'Zvýrazněný zdroj'
6
+ aspect_image: 'Stažení obrázku'
7
+ aspect_imageinfo: 'Informace o obrázku'
15
8
  aspect_latex: 'LaTeX'
16
- aspect_not_available: 'Aspect #{aspect} is not available for page #{page} with type #{type}.'
17
- entry: 'Entry'
18
- exif: 'EXIF Information'
19
- geometry: 'Geometry'
20
- information: 'Information'
21
- type: 'Type'
22
- value: 'Value'
9
+ aspect_not_available: 'Vzhled %{aspect} není k dispozici pro stránku %{page} s typem %{type}.'
10
+ aspect_pageinfo: 'Informace o stránce'
11
+ aspect_source: 'Zdroj stránky'
12
+ aspect_subpages: 'Podstránky'
13
+ aspect_text: 'Stažení textu'
14
+ attribute_aspect: 'Přednastavený vzhled'
15
+ download: 'Stáhnout'
16
+ entry: 'Položka'
17
+ exif: 'Informace EXIF'
18
+ geometry: 'Geometrie'
19
+ information: 'Informace'
20
+ type: 'Typ'
21
+ value: 'Hodnota'
23
22
  de:
24
- attribute_aspect: 'Standard-Ansicht'
25
- download: 'Herunterladen'
26
23
  aspect_documentbrowser: 'Dokumentenbrowser'
27
24
  aspect_download: 'Herunterladen'
28
- aspect_pageinfo: 'Seiten-Information'
25
+ aspect_gallery: 'Bildergalerie'
29
26
  aspect_highlight: 'Quellcode mit Syntaxhighlighting'
30
- aspect_imageinfo: 'Bild-Information'
31
27
  aspect_image: 'Bild'
28
+ aspect_imageinfo: 'Bild-Information'
29
+ aspect_latex: 'LaTeX'
30
+ aspect_not_available: 'Aspekt %{aspect} für die Seite %{page} mit dem Typ %{type} ist nicht verfügbar.'
31
+ aspect_pageinfo: 'Seiten-Information'
32
+ aspect_s5: 'S5 Präsentation'
32
33
  aspect_source: 'Quellcode'
33
34
  aspect_subpages: 'Unterseiten'
34
35
  aspect_text: 'Quellcode herunterladen'
35
- aspect_gallery: 'Bildergalerie'
36
- aspect_s5: 'S5 Präsentation'
37
- aspect_latex: 'LaTeX'
38
- aspect_not_available: 'Aspekt #{aspect} für die Seite #{page} mit dem Typ #{type} ist nicht verfügbar.'
36
+ attribute_aspect: 'Standard-Ansicht'
37
+ download: 'Herunterladen'
39
38
  entry: 'Eintrag'
40
39
  exif: 'EXIF-Information'
41
40
  geometry: 'Geometrie'
42
41
  information: 'Information'
43
42
  type: 'Typ'
44
43
  value: 'Wert'
45
- cs_CZ:
46
- attribute_aspect: 'Přednastavený vzhled'
47
- download: 'Stáhnout'
44
+ en:
48
45
  aspect_documentbrowser: 'Document Browser'
49
- aspect_download: 'Stažení (neupraveno)'
50
- aspect_pageinfo: 'Informace o stránce'
51
- aspect_highlight: 'Zvýrazněný zdroj'
52
- aspect_imageinfo: 'Informace o obrázku'
53
- aspect_image: 'Stažení obrázku'
54
- aspect_source: 'Zdroj stránky'
55
- aspect_subpages: 'Podstránky'
56
- aspect_text: 'Stažení textu'
57
- aspect_gallery: 'Galerie'
46
+ aspect_download: 'Raw Download'
47
+ aspect_gallery: 'Image Gallery'
48
+ aspect_highlight: 'Highlighted Source'
49
+ aspect_image: 'Raw Image'
50
+ aspect_imageinfo: 'Image Information'
58
51
  aspect_latex: 'LaTeX'
59
- aspect_not_available: 'Vzhled #{aspect} není k dispozici pro stránku #{page} s typem #{type}.'
60
- entry: 'Položka'
61
- exif: 'Informace EXIF'
62
- geometry: 'Geometrie'
63
- information: 'Informace'
64
- type: 'Typ'
65
- value: 'Hodnota'
52
+ aspect_not_available: 'Aspect %{aspect} is not available for page %{page} with type %{type}.'
53
+ aspect_pageinfo: 'Page Information'
54
+ aspect_s5: 'S5 Presentation'
55
+ aspect_source: 'Page Source'
56
+ aspect_subpages: 'Subpages'
57
+ aspect_text: 'Text Download'
58
+ attribute_aspect: 'Default Aspect'
59
+ download: 'Download'
60
+ entry: 'Entry'
61
+ exif: 'EXIF Information'
62
+ geometry: 'Geometry'
63
+ information: 'Information'
64
+ type: 'Type'
65
+ value: 'Value'
66
+ fr:
67
+ aspect_documentbrowser: "Explorateur de fichier"
68
+ aspect_download: "Téléchargement brut"
69
+ aspect_gallery: "Galerie d'images"
70
+ aspect_highlight: "Source mise en valeur"
71
+ aspect_image: "Image brute"
72
+ aspect_imageinfo: "Information sur l'image"
73
+ aspect_latex: "LaTeX"
74
+ aspect_not_available: "L'aspect %{aspect} n'est pas disponible pour la page %{page} avec le type %{type}."
75
+ aspect_pageinfo: "Page d'information"
76
+ aspect_s5: "Presentation S5 "
77
+ aspect_source: "Source de la page"
78
+ aspect_subpages: "Sous-pages"
79
+ aspect_text: "Téléchargement en texte"
80
+ attribute_aspect: "Aspect par défaut"
81
+ download: "Télécharger"
82
+ entry: "Entrée"
83
+ exif: "Information EXIF"
84
+ geometry: "Geometrie"
85
+ information: "Information"
86
+ type: "Type"
87
+ value: "Valeur"
@@ -1,12 +1,16 @@
1
- en:
2
- full_article: 'Full Article'
3
- written_by: 'written by #{author}'
4
- no_articles: 'No articles found'
5
- de:
6
- full_article: 'Ganzer Artikel'
7
- written_by: 'verfasst von #{author}'
8
- no_articles: 'Keine Artikel gefunden'
9
1
  cs_CZ:
10
2
  full_article: 'Plný článek'
11
- written_by: 'Napsal: #{author}'
12
3
  no_articles: 'Žádné články nenalezeny'
4
+ written_by: 'Napsal: %{author}'
5
+ de:
6
+ full_article: 'Ganzer Artikel'
7
+ no_articles: 'Keine Artikel gefunden'
8
+ written_by: 'verfasst von %{author}'
9
+ en:
10
+ full_article: 'Full Article'
11
+ no_articles: 'No articles found'
12
+ written_by: 'written by %{author}'
13
+ fr:
14
+ full_article: "Article complet"
15
+ no_articles: "Aucun article trouvé"
16
+ written_by: "écrit par %{author}"
@@ -1,15 +1,20 @@
1
- en:
2
- enter_captcha: 'Please enter the captcha.'
3
- captcha_invalid: Invalid captcha
4
- captcha_valid: Valid captcha
5
- preview: Preview
6
- de:
7
- enter_captcha: 'Bitte geben Sie ein Captcha ein.'
8
- captcha_invalid: 'Ungültiges Captcha'
9
- captcha_valid: 'Gültiges Captcha'
10
- preview: Vorschau
11
1
  cs_CZ:
12
- enter_captcha: 'Vložte laskavě captcha kód.'
13
2
  captcha_invalid: 'Neplatný captcha kód'
14
3
  captcha_valid: 'Platný captcha kód'
4
+ enter_captcha: 'Vložte laskavě captcha kód.'
15
5
  preview: 'Náhled'
6
+ de:
7
+ captcha_invalid: 'Ungültiges Captcha'
8
+ captcha_valid: 'Gültiges Captcha'
9
+ enter_captcha: 'Bitte geben Sie ein Captcha ein.'
10
+ preview: Vorschau
11
+ en:
12
+ captcha_invalid: Invalid captcha
13
+ captcha_valid: Valid captcha
14
+ enter_captcha: 'Please enter the captcha.'
15
+ preview: Preview
16
+ fr:
17
+ captcha_invalid: "Captcha invalide"
18
+ captcha_valid: "Captcha valide"
19
+ enter_captcha: "Veuillez entrer le captcha."
20
+ preview: "Prévisualisez"
@@ -18,16 +18,13 @@ class OleloCreole < ::Creole::Parser
18
18
  end
19
19
  image_path = escape_html(image_path)
20
20
  path = escape_html(path)
21
- nolink = args.delete('nolink')
22
21
  box = args.delete('box')
23
22
  alt = escape_html(args[0] ? args[0] : path)
24
- if nolink
25
- %{<img src="#{image_path}" alt="#{alt}"/>}
26
- elsif box
23
+ if box
27
24
  caption = args[0] ? %{<span class="caption">#{escape_html args[0]}</span>} : ''
28
- %{<span class="img"><a href="#{path}"><img src="#{image_path}" alt="#{alt}"/>#{caption}</a></span>}
25
+ %{<span class="img"><img src="#{image_path}" alt="#{alt}"/>#{caption}</span>}
29
26
  else
30
- %{<a href="#{path}" class="img"><img src="#{image_path}" alt="#{alt}"/></a>}
27
+ %{<img src="#{image_path}" alt="#{alt}"/>}
31
28
  end
32
29
  end
33
30
  end
@@ -0,0 +1,20 @@
1
+ description 'Add query parameter "aspect" to images'
2
+ dependencies 'utils/xml'
3
+
4
+ Filter.create :fix_image_links do |context, content|
5
+ doc = XML::Fragment(content)
6
+ linked_images = doc.css('a img')
7
+ doc.css('img').each do |image|
8
+ path = image['src']
9
+ unless path =~ %r{^w+://} || path.starts_with?(build_path('_')) ||
10
+ (path.starts_with?('/') && !path.starts_with?(build_path('')))
11
+ unless path.include?('aspect=')
12
+ image['src'] = path + (path.include?('?') ? '&' : '?') + 'aspect=image'
13
+ end
14
+ unless linked_images.include?(image)
15
+ image.swap("<a href=\"#{escape_html path.sub(/\?.*/, '')}\">#{image.to_xhtml}</a>")
16
+ end
17
+ end
18
+ end
19
+ doc.to_xhtml
20
+ end
@@ -1,15 +1,20 @@
1
- en:
2
- attribute_toc: 'Generate Table of Contents'
3
- attribute_no_editsection: 'Disable Section Editing'
4
- edit_section: 'Edit section "#{section}"'
5
- section_edited: 'Section "#{section}" edited'
6
- de:
7
- attribute_toc: 'Inhaltsverzeichnis erzeugen'
8
- attribute_no_editsection: 'Bearbeiten von Bereichen deaktivieren'
9
- edit_section: 'Bearbeite Bereich "#{section}"'
10
- section_edited: 'Bereich "#{section}" bearbeitet'
11
1
  cs_CZ:
12
- attribute_toc: 'Vytvořit obsah'
13
2
  attribute_no_editsection: 'Zablokovat editaci sekcí'
14
- edit_section: 'Edituj sekci "#{section}"'
15
- section_edited: 'Sekce "#{section}" editována'
3
+ attribute_toc: 'Vytvořit obsah'
4
+ edit_section: 'Edituj sekci "%{section}"'
5
+ section_edited: 'Sekce "%{section}" editována'
6
+ de:
7
+ attribute_no_editsection: 'Bearbeiten von Bereichen deaktivieren'
8
+ attribute_toc: 'Inhaltsverzeichnis erzeugen'
9
+ edit_section: 'Bearbeite Bereich "%{section}"'
10
+ section_edited: 'Bereich "%{section}" bearbeitet'
11
+ en:
12
+ attribute_no_editsection: 'Disable Section Editing'
13
+ attribute_toc: 'Generate Table of Contents'
14
+ edit_section: 'Edit section "%{section}"'
15
+ section_edited: 'Section "%{section}" edited'
16
+ fr:
17
+ attribute_no_editsection: "Désactiver l'édition"
18
+ attribute_toc: "Générer Table des Matières"
19
+ edit_section: "Éditer la section \"%{section}\""
20
+ section_edited: "Section \"%{section}\" éditée"
@@ -2,6 +2,8 @@ description 'XSLT filter which transforms a html page to a S5 presentation'
2
2
  dependencies 'filters/xslt', 'utils/assets'
3
3
  export_assets 'ui/**/*', 'ui/default/*'
4
4
 
5
+ raise 'Diascope not found' unless File.exists?(File.join(File.dirname(__FILE__), 'ui'))
6
+
5
7
  Page.attributes do
6
8
  group :s5 do
7
9
  string :presdate
@@ -1,6 +1,8 @@
1
- en:
2
- persistent_login: 'Persistent login'
3
- de:
4
- persistent_login: 'Dauerhaft anmelden'
5
1
  cs_CZ:
6
2
  persistent_login: 'Trvalé přihlášení'
3
+ de:
4
+ persistent_login: 'Dauerhaft anmelden'
5
+ en:
6
+ persistent_login: 'Persistent login'
7
+ fr:
8
+ persistent_login: 'Connexion persistente'
@@ -37,7 +37,7 @@ class GitrbRepository < Repository
37
37
  # @override
38
38
  def get_history(path, skip, limit)
39
39
  @git.log(max_count: limit, skip: skip,
40
- path: [path, path + ATTRIBUTE_EXT, path + CONTENT_EXT]).map do |c|
40
+ path: [path, path + ATTRIBUTE_EXT, path + CONTENT_EXT]).map do |c|
41
41
  commit_to_version(c)
42
42
  end
43
43
  end
@@ -1,12 +1,16 @@
1
- en:
2
- search_results: 'Search results for #{pattern}'
3
- match: 'One match'
4
- match_plural: '#{count} matches'
5
- de:
6
- search_results: 'Suchergebnisse für #{pattern}'
7
- match: 'Ein Treffer'
8
- match_plural: '#{count} Treffer'
9
1
  cs_CZ:
10
- search_results: 'Výsledky hledání pro #{pattern}'
11
2
  match: 'Jeden výsledek'
12
- match_plural: '#{count} výsledků'
3
+ match_plural: '%{count} výsledků'
4
+ search_results: 'Výsledky hledání pro %{pattern}'
5
+ de:
6
+ match: 'Ein Treffer'
7
+ match_plural: '%{count} Treffer'
8
+ search_results: 'Suchergebnisse für %{pattern}'
9
+ en:
10
+ match: 'One match'
11
+ match_plural: '%{count} matches'
12
+ search_results: 'Search results for %{pattern}'
13
+ fr:
14
+ match: "Une correspondance"
15
+ match_plural: "%{count} correspondaces"
16
+ search_results: "Chercher les résultats pour %{pattern}"