blacklight-spotlight 3.0.0.alpha.10 → 3.0.0.rc1
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.
- checksums.yaml +4 -4
- data/app/assets/javascripts/spotlight/admin/crop.es6 +6 -0
- data/app/assets/javascripts/spotlight/admin/sir-trevor/block_controls.js +21 -12
- data/app/assets/stylesheets/spotlight/_featured_browse_categories_block.scss +4 -4
- data/app/assets/stylesheets/spotlight/_item_text_block.scss +6 -0
- data/app/assets/stylesheets/spotlight/_report_a_problem.scss +5 -2
- data/app/controllers/spotlight/resources/csv_upload_controller.rb +1 -1
- data/app/jobs/spotlight/add_uploads_from_csv.rb +30 -5
- data/app/mailers/spotlight/indexing_complete_mailer.rb +3 -2
- data/app/models/spotlight/contact.rb +1 -1
- data/app/models/spotlight/custom_field.rb +3 -3
- data/app/models/spotlight/featured_image.rb +1 -1
- data/app/models/spotlight/page_configurations.rb +1 -0
- data/app/models/spotlight/page_content.rb +2 -0
- data/app/models/spotlight/resources/csv_upload.rb +2 -1
- data/app/models/spotlight/resources/iiif_manifest.rb +2 -0
- data/app/services/spotlight/solr_document_builder.rb +1 -0
- data/app/values/custom_field_name.rb +1 -0
- data/app/views/spotlight/indexing_complete_mailer/documents_indexed.html.erb +9 -0
- data/app/views/spotlight/pages/_form.html.erb +1 -1
- data/app/views/spotlight/shared/_honeypot_field.html.erb +4 -0
- data/app/views/spotlight/shared/_report_a_problem.html.erb +7 -10
- data/config/i18n-tasks.yml +2 -0
- data/config/locales/spotlight.ar.yml +22 -18
- data/config/locales/spotlight.en.yml +13 -6
- data/lib/generators/spotlight/install_generator.rb +22 -1
- data/lib/generators/spotlight/templates/config/initializers/sir_trevor_rails.rb +10 -0
- data/lib/generators/spotlight/templates/config/initializers/spotlight_initializer.rb +2 -0
- data/lib/spotlight/engine.rb +3 -0
- data/lib/spotlight/upload_field_config.rb +1 -0
- data/lib/spotlight/version.rb +1 -1
- data/spec/controllers/spotlight/browse_controller_spec.rb +1 -1
- data/spec/controllers/spotlight/resources/csv_upload_controller_spec.rb +4 -4
- data/spec/examples.txt +1410 -125
- data/spec/features/add_contacts_spec.rb +1 -1
- data/spec/features/browse_category_admin_spec.rb +2 -2
- data/spec/features/create_exhibit_spec.rb +5 -4
- data/spec/features/dashboard_spec.rb +5 -5
- data/spec/features/exhibits/administration_spec.rb +3 -3
- data/spec/features/exhibits/language_create_edit_spec.rb +3 -3
- data/spec/features/javascript/block_controls_spec.rb +2 -0
- data/spec/features/report_a_problem_spec.rb +5 -4
- data/spec/helpers/spotlight/pages_helper_spec.rb +2 -2
- data/spec/jobs/spotlight/add_uploads_from_csv_spec.rb +13 -1
- data/spec/mailers/spotlight/indexing_complete_mailer_spec.rb +11 -1
- data/spec/models/solr_document_spec.rb +2 -3
- data/spec/models/spotlight/access_controls_enforcement_search_builder_spec.rb +1 -0
- data/spec/models/spotlight/featured_image_spec.rb +0 -1
- data/spec/models/spotlight/role_spec.rb +2 -2
- data/spec/services/spotlight/exhibit_import_export_service_spec.rb +14 -2
- data/spec/services/spotlight/iiif_resource_resolver_spec.rb +1 -1
- data/spec/test_app_templates/Gemfile.extra +0 -3
- data/spec/views/spotlight/metadata_configurations/_metadata_field.html.erb_spec.rb +3 -3
- data/spec/views/spotlight/search_configurations/_sort.html.erb_spec.rb +7 -8
- data/vendor/assets/javascripts/leaflet-iiif.js +46 -21
- metadata +54 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8a3577af6f5ec30554f2e91955c7613e6501ef8e95f2822f6a92022626c03230
|
4
|
+
data.tar.gz: e45881b0867cba47bb74a93a7a008a843154383939c8db3abbb0c244e0a6ff57
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7164e6ebcca3edd4db9d2b95ed7fafb2ec55188de3e16bdf92963b893e6b717dae262a7a2ab5f3fbfbe2e2f8de7a602083e2586b338fdbf5f1f2f96c4f5cb402
|
7
|
+
data.tar.gz: aaf1d73d51efd42699f32e1c9315ee43c4ab5e9bdb85e737eddbd94b4d9cf565e93deb58751074fecc5aaf8461cd82eb68db52fa5189db88df38035125e7ee60
|
@@ -40,6 +40,12 @@ export default class Crop {
|
|
40
40
|
this.renderCropperMap();
|
41
41
|
|
42
42
|
if (this.imageLayer) {
|
43
|
+
// Force a broken layer's container to be an element before removing.
|
44
|
+
// Code in leaflet-iiif land calls delete on the image layer's container when removing,
|
45
|
+
// which errors if there is an issue fetching the info.json and stops further necessary steps to execute.
|
46
|
+
if(!this.imageLayer._container) {
|
47
|
+
this.imageLayer._container = $('<div></div>');
|
48
|
+
}
|
43
49
|
this.cropperMap.removeLayer(this.imageLayer);
|
44
50
|
}
|
45
51
|
|
@@ -40,19 +40,28 @@
|
|
40
40
|
}
|
41
41
|
}
|
42
42
|
|
43
|
-
|
44
|
-
var group = groups[
|
45
|
-
var groupEl = $("<div class='st-controls-group'><div class='st-group-col-form-label'>" +
|
43
|
+
function generateBlock(groups, key) {
|
44
|
+
var group = groups[key];
|
45
|
+
var groupEl = $("<div class='st-controls-group'><div class='st-group-col-form-label'>" + key + "</div></div>");
|
46
46
|
var buttons = group.reduce(function(memo, btn) {
|
47
47
|
return memo += btn;
|
48
48
|
}, "");
|
49
49
|
groupEl.append(buttons);
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
50
|
+
return groupEl[0].outerHTML;
|
51
|
+
}
|
52
|
+
|
53
|
+
var standardWidgets = generateBlock(groups, i18n.t("blocks:group:undefined"));
|
54
|
+
|
55
|
+
var exhibitWidgets = Object.keys(groups).map(function(key) {
|
56
|
+
if (key !== i18n.t("blocks:group:undefined")) {
|
57
|
+
return generateBlock(groups, key);
|
54
58
|
}
|
55
|
-
}
|
59
|
+
}).filter(function (element) {
|
60
|
+
return element != null;
|
61
|
+
});
|
62
|
+
|
63
|
+
var blocks = [standardWidgets].concat(exhibitWidgets).join("<hr />");
|
64
|
+
return blocks;
|
56
65
|
}
|
57
66
|
|
58
67
|
function render(Blocks, availableTypes) {
|
@@ -65,7 +74,7 @@
|
|
65
74
|
elButtons.appendChild(el);
|
66
75
|
return elButtons;
|
67
76
|
}
|
68
|
-
|
77
|
+
|
69
78
|
global.Spotlight.BlockControls = function() { };
|
70
79
|
global.Spotlight.BlockControls.create = function(editor) {
|
71
80
|
// REFACTOR - should probably not know about blockManager
|
@@ -83,10 +92,10 @@
|
|
83
92
|
SirTrevor = null;
|
84
93
|
el = null;
|
85
94
|
}
|
86
|
-
|
95
|
+
|
87
96
|
function insert(e) {
|
88
97
|
e.stopPropagation();
|
89
|
-
|
98
|
+
|
90
99
|
var parent = this.parentNode;
|
91
100
|
if (!parent || hide() === parent) { return; }
|
92
101
|
$('.st-block__inner', parent).after(el);
|
@@ -101,7 +110,7 @@
|
|
101
110
|
|
102
111
|
$(editor.wrapper).delegate(".st-block-replacer", "click", insert);
|
103
112
|
$(editor.wrapper).delegate(".st-block-controls__button", "click", insert);
|
104
|
-
|
113
|
+
|
105
114
|
return {
|
106
115
|
el: el,
|
107
116
|
hide: hide,
|
@@ -77,7 +77,7 @@ $aspect-ratio-factor-medium-image: 1; // 1:1 width: height
|
|
77
77
|
width: $no-sidebar-desktop-large-image-width;
|
78
78
|
height: $no-sidebar-desktop-large-image-width * $aspect-ratio-factor-large-image;
|
79
79
|
}
|
80
|
-
@media (min-width: breakpoint-min("
|
80
|
+
@media (min-width: breakpoint-min("lg")) {
|
81
81
|
width: $no-sidebar-large-desktop-large-image-width;
|
82
82
|
height: $no-sidebar-large-desktop-large-image-width * $aspect-ratio-factor-large-image;
|
83
83
|
}
|
@@ -111,11 +111,11 @@ $aspect-ratio-factor-medium-image: 1; // 1:1 width: height
|
|
111
111
|
width: $with-sidebar-tablet-large-image-width;
|
112
112
|
height: $with-sidebar-tablet-large-image-width * $aspect-ratio-factor-large-image;
|
113
113
|
}
|
114
|
-
@media (min-width: breakpoint-min("md")) and (max-width: breakpoint-max("
|
114
|
+
@media (min-width: breakpoint-min("md")) and (max-width: breakpoint-max("lg")) {
|
115
115
|
width: $with-sidebar-desktop-large-image-width;
|
116
116
|
height: $with-sidebar-desktop-large-image-width * $aspect-ratio-factor-large-image;
|
117
117
|
}
|
118
|
-
@media (min-width: breakpoint-min("
|
118
|
+
@media (min-width: breakpoint-min("lg")) {
|
119
119
|
width: $with-sidebar-large-desktop-large-image-width;
|
120
120
|
height: $with-sidebar-large-desktop-large-image-width * $aspect-ratio-factor-large-image;
|
121
121
|
}
|
@@ -129,7 +129,7 @@ $aspect-ratio-factor-medium-image: 1; // 1:1 width: height
|
|
129
129
|
width: $with-sidebar-xs-image-width;
|
130
130
|
height: $with-sidebar-xs-image-width * $aspect-ratio-factor-medium-image;
|
131
131
|
}
|
132
|
-
@media (min-width: breakpoint-min("
|
132
|
+
@media (min-width: breakpoint-min("lg")) {
|
133
133
|
width: $with-sidebar-large-desktop-medium-image-width;
|
134
134
|
height: $with-sidebar-large-desktop-medium-image-width * $aspect-ratio-factor-medium-image;
|
135
135
|
}
|
@@ -16,7 +16,7 @@ module Spotlight
|
|
16
16
|
|
17
17
|
def create
|
18
18
|
csv = CSV.parse(csv_io_param, headers: true, return_headers: false).map(&:to_hash)
|
19
|
-
Spotlight::
|
19
|
+
Spotlight::AddUploadsFromCsv.perform_later(csv, current_exhibit, current_user)
|
20
20
|
flash[:notice] = t('spotlight.resources.upload.csv.success', file_name: csv_io_name)
|
21
21
|
redirect_to spotlight.admin_exhibit_catalog_path(current_exhibit)
|
22
22
|
end
|
@@ -3,15 +3,41 @@
|
|
3
3
|
module Spotlight
|
4
4
|
##
|
5
5
|
# Process a CSV upload into new Spotlight::Resource::Upload objects
|
6
|
-
class
|
6
|
+
class AddUploadsFromCsv < ActiveJob::Base
|
7
|
+
attr_reader :count
|
8
|
+
attr_reader :errors
|
9
|
+
|
7
10
|
queue_as :default
|
8
11
|
|
9
12
|
after_perform do |job|
|
10
13
|
csv_data, exhibit, user = job.arguments
|
11
|
-
Spotlight::IndexingCompleteMailer.documents_indexed(
|
14
|
+
Spotlight::IndexingCompleteMailer.documents_indexed(
|
15
|
+
csv_data,
|
16
|
+
exhibit,
|
17
|
+
user,
|
18
|
+
indexed_count: job.count,
|
19
|
+
errors: job.errors
|
20
|
+
).deliver_now
|
12
21
|
end
|
13
22
|
|
14
23
|
def perform(csv_data, exhibit, _user)
|
24
|
+
@count = 0
|
25
|
+
@errors = {}
|
26
|
+
|
27
|
+
resources(csv_data, exhibit).each_with_index do |resource, index|
|
28
|
+
if resource.save_and_index
|
29
|
+
@count += 1
|
30
|
+
else
|
31
|
+
@errors[index + 1] = resource.errors.full_messages + resource.upload&.errors&.full_messages
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def resources(csv_data, exhibit)
|
39
|
+
return to_enum(:resources, csv_data, exhibit) unless block_given?
|
40
|
+
|
15
41
|
encoded_csv(csv_data).each do |row|
|
16
42
|
url = row.delete('url')
|
17
43
|
next unless url.present?
|
@@ -21,12 +47,11 @@ module Spotlight
|
|
21
47
|
exhibit: exhibit
|
22
48
|
)
|
23
49
|
resource.build_upload(remote_image_url: url) unless url == '~'
|
24
|
-
|
50
|
+
|
51
|
+
yield resource
|
25
52
|
end
|
26
53
|
end
|
27
54
|
|
28
|
-
private
|
29
|
-
|
30
55
|
def encoded_csv(csv)
|
31
56
|
csv.map do |row|
|
32
57
|
row.map do |label, column|
|
@@ -5,9 +5,10 @@ module Spotlight
|
|
5
5
|
# Notify the curator that we're finished processing a
|
6
6
|
# batch upload
|
7
7
|
class IndexingCompleteMailer < ActionMailer::Base
|
8
|
-
def documents_indexed(csv_data, exhibit, user)
|
9
|
-
@number = csv_data.length
|
8
|
+
def documents_indexed(csv_data, exhibit, user, indexed_count: nil, errors: [])
|
9
|
+
@number = indexed_count || csv_data.length
|
10
10
|
@exhibit = exhibit
|
11
|
+
@errors = errors
|
11
12
|
mail(to: user.email, subject: 'Document indexing complete')
|
12
13
|
end
|
13
14
|
end
|
@@ -18,10 +18,10 @@ module Spotlight
|
|
18
18
|
self.field_type ||= 'text'
|
19
19
|
end
|
20
20
|
|
21
|
-
|
21
|
+
before_update :update_field_name, if: -> { field_type_changed? || readonly_field_changed? }
|
22
22
|
|
23
|
-
|
24
|
-
|
23
|
+
after_update_commit :update_blacklight_configuration_after_field_name_change, if: -> { saved_change_to_field? || saved_change_to_slug? }
|
24
|
+
after_update_commit :update_sidecar_data_after_field_name_change, if: -> { saved_change_to_field? || saved_change_to_slug? }
|
25
25
|
|
26
26
|
def label=(label)
|
27
27
|
configuration['label'] = label
|
@@ -3,9 +3,10 @@
|
|
3
3
|
module Spotlight
|
4
4
|
module Resources
|
5
5
|
##
|
6
|
-
# Shim object for CSV Uploads. see {Spotlight::
|
6
|
+
# Shim object for CSV Uploads. see {Spotlight::AddUploadsFromCsv}
|
7
7
|
class CsvUpload
|
8
8
|
attr_reader :url
|
9
|
+
|
9
10
|
include ActiveModel::Model
|
10
11
|
extend ActiveModel::Translation
|
11
12
|
end
|
@@ -6,6 +6,7 @@ module Spotlight
|
|
6
6
|
# A PORO to construct a solr hash for a given IiifManifest
|
7
7
|
class IiifManifest
|
8
8
|
attr_reader :collection
|
9
|
+
|
9
10
|
def initialize(attrs = {})
|
10
11
|
@url = attrs[:url]
|
11
12
|
@manifest = attrs[:manifest]
|
@@ -36,6 +37,7 @@ module Spotlight
|
|
36
37
|
private
|
37
38
|
|
38
39
|
attr_reader :url, :manifest, :exhibit, :solr_hash
|
40
|
+
|
39
41
|
delegate :blacklight_config, to: :exhibit
|
40
42
|
|
41
43
|
def add_document_id
|
@@ -1,3 +1,12 @@
|
|
1
1
|
<p><%= t :".title" %></p>
|
2
2
|
|
3
3
|
<p><%= t :".body", count: @number, title: @exhibit.title %></p>
|
4
|
+
|
5
|
+
<% if @errors.length > 0 %>
|
6
|
+
<p><%= t :".errors", default: :'spotlight.catalog.reindex_progress_panel.error' %></p>
|
7
|
+
<ul>
|
8
|
+
<% @errors.each do |index, message| %>
|
9
|
+
<li><%= t :'.error', index: index, message: message.to_sentence %>
|
10
|
+
<% end %>
|
11
|
+
</ul>
|
12
|
+
<% end %>
|
@@ -40,7 +40,7 @@
|
|
40
40
|
</div>
|
41
41
|
<div class="form-group">
|
42
42
|
<%= f.label :content, class: 'sr-only' %>
|
43
|
-
<%= f.text_area_without_bootstrap :content, value: { data: f.object.content.as_json }.to_json, class: content_editor_class(f.object), data: { 'block-types':
|
43
|
+
<%= f.text_area_without_bootstrap :content, value: { data: f.object.content.as_json }.to_json, class: content_editor_class(f.object), data: { 'block-types': SirTrevorRails::Block.custom_block_types } %>
|
44
44
|
</div>
|
45
45
|
</div>
|
46
46
|
|
@@ -2,20 +2,17 @@
|
|
2
2
|
<div class="row justify-content-center">
|
3
3
|
<% contact_form ||= Spotlight::ContactForm.new current_url: request.original_url %>
|
4
4
|
<%= bootstrap_form_for contact_form, url: spotlight.exhibit_contact_form_path(current_exhibit, contact_form), layout: :horizontal, label_col: 'col-sm-3', control_col: 'col-sm-9', html: { class: 'col-md-offset-2 col-md-8 my-3 '} do |f| %>
|
5
|
-
|
6
5
|
<h2><%= t(:'.title') %></h2>
|
6
|
+
<div class="alert alert-primary"><%= t('.reporting_from', url: contact_form.current_url) %></div>
|
7
|
+
<%= f.text_area :message, rows: 4 %>
|
7
8
|
<%= f.text_field :name %>
|
8
|
-
|
9
|
-
<% honeypot_field_name = Spotlight::Engine.config.spambot_honeypot_email_field %>
|
10
|
-
<%= f.email_field honeypot_field_name, label: t(:'.honeypot_field_explanation') %>
|
11
|
-
</span>
|
9
|
+
<%= render '/spotlight/shared/honeypot_field', f: f %>
|
12
10
|
<%= f.email_field :email %>
|
13
|
-
<%= f.text_area :message, rows: 7 %>
|
14
11
|
<%= f.hidden_field :current_url %>
|
15
|
-
<div class="form-actions">
|
16
|
-
<div class="
|
17
|
-
|
18
|
-
|
12
|
+
<div class="form-actions row">
|
13
|
+
<div class="col offset-sm-3">
|
14
|
+
<%= f.submit nil, class: 'btn btn-primary' %>
|
15
|
+
<%= link_to t(:'helpers.action.cancel'), '#', class: 'btn-sizing', data: { 'behavior' => 'cancel-link' } %>
|
19
16
|
</div>
|
20
17
|
</div>
|
21
18
|
<% end %>
|
data/config/i18n-tasks.yml
CHANGED
@@ -34,6 +34,7 @@ ignore_unused:
|
|
34
34
|
- activerecord.attributes.spotlight/page.{display_sidebar\?,display_title} # app/views/spotlight/home_pages/_page_options.html.erb
|
35
35
|
- activerecord.attributes.spotlight/language.locale # app/views/spotlight/exhibits/_languages.html.erb
|
36
36
|
- activerecord.attributes.spotlight/contact.avatar # app/views/spotlight/contacts/_form.html.erb
|
37
|
+
- activerecord.attributes.spotlight/exhibit.contact_emails # app/views/spotlight/exhibits/_form.html.erb
|
37
38
|
- activerecord.attributes.spotlight/exhibit.published # app/views/spotlight/sites/_exhibit.html.erb
|
38
39
|
- activerecord.attributes.spotlight/masthead.display # app/views/spotlight/appearances/edit.html.erb
|
39
40
|
- activerecord.attributes.spotlight/custom_field.is_multiple # app/views/spotlight/custom_fields/_form.html.erb
|
@@ -66,6 +67,7 @@ ignore_unused:
|
|
66
67
|
- helpers.submit.{submit,update} # Generically used set defaults
|
67
68
|
- helpers.submit.contact.create # app/views/spotlight/contacts/_form.html.erb
|
68
69
|
- helpers.action.exhibit.contact.submit # helpers.action.exhibit.contact.submit
|
70
|
+
- helpers.label.contact_form.{email,name} # app/views/spotlight/shared/_report_a_problem.html.erb
|
69
71
|
|
70
72
|
# TODO Look into these as its unclear
|
71
73
|
- activerecord.models.spotlight.page
|
@@ -16,25 +16,28 @@ ar:
|
|
16
16
|
browse:
|
17
17
|
search:
|
18
18
|
item_count:
|
19
|
-
|
19
|
+
zero: "%{count} عنصر"
|
20
|
+
one: "%{count} عنصر"
|
21
|
+
two: "%{count} عنصرين"
|
20
22
|
few: "%{count} عناصر"
|
21
|
-
many: "%{count}
|
22
|
-
other: "%{count}
|
23
|
-
|
24
|
-
zero: لا يوجد
|
23
|
+
many: "%{count} عنصراً"
|
24
|
+
other: "%{count} عنصراً"
|
25
|
+
|
25
26
|
search_box:
|
26
27
|
label: ابحث في فئة التصفح الحالية
|
27
28
|
placeholder: بحث...
|
28
29
|
reset: مسح استعلام البحث
|
29
30
|
submit: ابحث في فئة التصفح
|
30
31
|
success:
|
31
|
-
expand_html: يمكنك ايضاً <a href
|
32
|
-
result_number_html: طابق استعلام البحث <strong> %{search_size} من %{parent_search_count} عنصر</strong> في هذه الفئة.
|
32
|
+
expand_html: "يمكنك ايضاً <a href=\"%{expand_search_url}\">البحث في كل مواد المعرض عن \"%{browse_query}\"</a>."
|
33
|
+
result_number_html: "طابق استعلام البحث <strong> %{search_size} من %{parent_search_count} عنصر</strong> في هذه الفئة."
|
33
34
|
zero_results:
|
34
|
-
expand_html: تستطيع أن <a href
|
35
|
+
expand_html: "تستطيع أن <a href=\"%{clear_search_url}\"> تمسح استعلام البحث </a> أو محاولة <a href=\"%{expand_search_url}\"> البحث في كل المواد المعروضة لاستعلام البحث ل\"%{browse_query}\"</a>"
|
35
36
|
result_number: لم يتطابق بحثك مع أي عنصر في هذه الفئة.
|
36
37
|
header_links:
|
37
38
|
contact: ملاحظات واقتراحات
|
39
|
+
login: تسجيل الدخول
|
40
|
+
logout: تسجيل الخروج
|
38
41
|
shared:
|
39
42
|
report_a_problem:
|
40
43
|
honeypot_field_explanation: تجاهل هذا المربع النصي، فهو يُستخدم فقط لكشف المحتالين. إذا كتبت أي شيء في هذا المربع النصي، فلن يتم إرسال رسالتك.
|
@@ -43,17 +46,18 @@ ar:
|
|
43
46
|
blocks:
|
44
47
|
browse_block:
|
45
48
|
items:
|
46
|
-
|
49
|
+
zero: "%{count} عنصر"
|
50
|
+
one: "%{count} عنصر"
|
51
|
+
two: "%{count} عنصرين"
|
47
52
|
few: "%{count} عناصر"
|
48
|
-
many: "%{count}
|
49
|
-
other: "%{count}
|
50
|
-
|
51
|
-
zero: لا يوجد
|
53
|
+
many: "%{count} عنصراً"
|
54
|
+
other: "%{count} عنصراً"
|
55
|
+
|
52
56
|
link_to_search_block:
|
53
57
|
items:
|
54
|
-
|
58
|
+
zero: "%{count} عنصر"
|
59
|
+
one: "%{count} عنصر"
|
60
|
+
two: "%{count} عنصرين"
|
55
61
|
few: "%{count} عناصر"
|
56
|
-
many: "%{count}
|
57
|
-
other: "%{count}
|
58
|
-
two: عنصرين
|
59
|
-
zero: لا يوجد
|
62
|
+
many: "%{count} عنصراً"
|
63
|
+
other: "%{count} عنصراً"
|