card-mod-collection 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/set/abstract/items.rb +202 -0
- data/set/abstract/paging.rb +64 -0
- data/set/abstract/paging/paging_links.rb +90 -0
- data/set/abstract/paging/paging_views.rb +111 -0
- data/set/all/extended.rb +49 -0
- data/set/all/item.rb +130 -0
- metadata +66 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: cabe6e7e22075e4414381fa6929b7c012c03049d1eb477eca3bda54eb0cf4508
|
4
|
+
data.tar.gz: 815252c283d17851de677f1692b98733524387b2f8fc07e3fa3decc24480aaa7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: dbf957e00b6dd53cef2cd622497a84fad0ad24f1bde19f77cb7c1dfc79df8a3c890d401e59ce422ff8c5dd50e926177314f74f3441d27c13182a33a8104f70c4
|
7
|
+
data.tar.gz: 8978ebdad15565e224b64de457b6c5dafb5bc7172bcaec56412bbe64cb4adf7d4593e97eff60b49b131a301cf53232210dccbf0749dbb9c16956bebce393e82a
|
@@ -0,0 +1,202 @@
|
|
1
|
+
# ~~~~~~~~~~~~ READING ITEMS ~~~~~~~~~~~~
|
2
|
+
|
3
|
+
# While each of the three main methods for returning lists of items can handle arguments,
|
4
|
+
# they are most commonly used without them.
|
5
|
+
|
6
|
+
# @return [Array] list of Card::Name objects
|
7
|
+
# @param args [Hash]
|
8
|
+
# @option args [String] :content override card content
|
9
|
+
# @option args [String, Card::Name, Symbol] :context name in whose context relative items
|
10
|
+
# will be interpreted. For example. +A in context of B is interpreted as B+A
|
11
|
+
# context defaults to pointer card's name. If value is `:raw`, then name is not
|
12
|
+
# contextualized
|
13
|
+
# @option args [String, Integer] :limit max number of cards to return
|
14
|
+
# @option args [String, Integer] :offset begin after the offset-th item
|
15
|
+
def item_names args={}
|
16
|
+
context = args[:context]
|
17
|
+
item_strings(args).map do |item|
|
18
|
+
clean_item_name item, context
|
19
|
+
end.compact
|
20
|
+
end
|
21
|
+
|
22
|
+
def first_name args={}
|
23
|
+
item_names(args).first
|
24
|
+
end
|
25
|
+
|
26
|
+
def first_card args={}
|
27
|
+
return unless (name = first_name)
|
28
|
+
fetch_item_card name, args
|
29
|
+
end
|
30
|
+
|
31
|
+
def first_code
|
32
|
+
first_card&.codename
|
33
|
+
end
|
34
|
+
|
35
|
+
def first_id
|
36
|
+
first_card&.id
|
37
|
+
end
|
38
|
+
|
39
|
+
# @return [Array] list of integers (card ids of items)
|
40
|
+
# @param args [Hash] see #item_names
|
41
|
+
def item_ids args={}
|
42
|
+
item_names(args).map { |name| Card.fetch_id name }.compact
|
43
|
+
end
|
44
|
+
|
45
|
+
# @return [Array] list of Card objects
|
46
|
+
# @param args [Hash] see #item_names for additional options
|
47
|
+
# @option args [String] :complete keyword to use in searching among items
|
48
|
+
# @option args [True/False] :known_only if true, return only known cards
|
49
|
+
# @option args [String] :type name of type to be used for unknown cards
|
50
|
+
def item_cards args={}
|
51
|
+
return item_cards_search(args) if args[:complete]
|
52
|
+
return known_item_cards(args) if args[:known_only]
|
53
|
+
all_item_cards args
|
54
|
+
end
|
55
|
+
|
56
|
+
# #item_name, #item_id, and #item_card each return a single item, rather than an array.
|
57
|
+
%i[name id card].each do |obj|
|
58
|
+
define_method "item_#{obj}" do |args={}|
|
59
|
+
send("item_#{obj}s", args.merge(limit: 1)).first
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# for override, eg by json
|
64
|
+
def item_value item_name
|
65
|
+
item_name
|
66
|
+
end
|
67
|
+
|
68
|
+
# ~~~~~~~~~~~~ ALTERING ITEMS ~~~~~~~~~~~~
|
69
|
+
|
70
|
+
# set card content based on array and save card
|
71
|
+
# @param array [Array] list of strings/names (Cardish)
|
72
|
+
def items= array
|
73
|
+
items_to_content array
|
74
|
+
save!
|
75
|
+
end
|
76
|
+
|
77
|
+
# append item to list (does not save)
|
78
|
+
# @param cardish [Cardish]
|
79
|
+
def << cardish
|
80
|
+
add_item cardish
|
81
|
+
end
|
82
|
+
|
83
|
+
# append item to list (does not save)
|
84
|
+
# @param cardish [String, Card::Name] item name
|
85
|
+
# @param allow_duplicates [True/False] permit duplicate items (default is False)
|
86
|
+
def add_item cardish, allow_duplicates=false
|
87
|
+
return if !allow_duplicates && include_item?(cardish)
|
88
|
+
|
89
|
+
items = item_strings << cardish
|
90
|
+
items_to_content items
|
91
|
+
end
|
92
|
+
|
93
|
+
# append item to list and save card
|
94
|
+
# @param name [String, Card::Name] item name
|
95
|
+
def add_item! name
|
96
|
+
add_item(name) && save!
|
97
|
+
end
|
98
|
+
|
99
|
+
# remove item from list
|
100
|
+
# @param cardish [String, Card::Name] item to drop
|
101
|
+
def drop_item cardish
|
102
|
+
drop_item_name = Card::Name[cardish]
|
103
|
+
items_to_content(item_names.reject { |item_name| item_name == drop_item_name })
|
104
|
+
end
|
105
|
+
|
106
|
+
# remove item from list and save card
|
107
|
+
# @param cardish [String, Card::Name] item to drop
|
108
|
+
def drop_item! cardish
|
109
|
+
drop_item cardish
|
110
|
+
save!
|
111
|
+
end
|
112
|
+
|
113
|
+
# insert item into list at specified location
|
114
|
+
# @param index [Integer] Array index in which to insert item (0 is first)
|
115
|
+
# @param name [String, Card::Name] item name
|
116
|
+
def insert_item index, name
|
117
|
+
new_names = item_names
|
118
|
+
new_names.delete name
|
119
|
+
new_names.insert index, name
|
120
|
+
items_to_content new_names
|
121
|
+
end
|
122
|
+
|
123
|
+
# insert item into list at specified location and save
|
124
|
+
# @param index [Integer] Array index in which to insert item (0 is first)
|
125
|
+
# @param name [String, Card::Name] item name
|
126
|
+
def insert_item! index, name
|
127
|
+
insert_item index, name
|
128
|
+
save!
|
129
|
+
end
|
130
|
+
|
131
|
+
# ~~~~~~~~~~~~ READING ITEM HELPERS ~~~~~~~~~~~~
|
132
|
+
|
133
|
+
# Warning: the following methods, while available for use, may be subject to change
|
134
|
+
|
135
|
+
# #item_cards helpers
|
136
|
+
|
137
|
+
def item_cards_search query
|
138
|
+
Card::Query.run query.reverse_merge(referred_to_by: name, limit: 0)
|
139
|
+
end
|
140
|
+
|
141
|
+
def known_item_cards args={}
|
142
|
+
item_names(args).map { |name| Card.fetch name }.compact
|
143
|
+
end
|
144
|
+
|
145
|
+
def all_item_cards args={}
|
146
|
+
names = args[:item_names] || item_names(args)
|
147
|
+
names.map { |name| fetch_item_card name, args }
|
148
|
+
end
|
149
|
+
|
150
|
+
# TODO: support type_code and type_id. (currently type)
|
151
|
+
# uses name, because its most common use is from CQL
|
152
|
+
def item_type
|
153
|
+
opt = options_rule_card
|
154
|
+
# FIXME: need better recursion prevention
|
155
|
+
return if !opt || opt == self
|
156
|
+
opt.item_type
|
157
|
+
end
|
158
|
+
|
159
|
+
def item_strings args={}
|
160
|
+
items = raw_item_strings(args[:content] || content)
|
161
|
+
return items unless args.present?
|
162
|
+
|
163
|
+
filtered_items items, args.slice(:limit, :offset)
|
164
|
+
end
|
165
|
+
|
166
|
+
def raw_item_strings content
|
167
|
+
content.to_s.split(/\n+/).map { |i| strip_item i }
|
168
|
+
end
|
169
|
+
|
170
|
+
private
|
171
|
+
|
172
|
+
def filtered_items items, limit: 0, offset: 0
|
173
|
+
limit = limit.to_i
|
174
|
+
offset = offset.to_i
|
175
|
+
return items unless limit.positive? || offset.positive?
|
176
|
+
|
177
|
+
items[offset, (limit.zero? ? items.size : limit)] || []
|
178
|
+
end
|
179
|
+
|
180
|
+
def fetch_item_card name, args={}
|
181
|
+
Card.fetch name, new: new_unknown_item_args(args)
|
182
|
+
end
|
183
|
+
|
184
|
+
def new_unknown_item_args args
|
185
|
+
itype = args[:type] || item_type
|
186
|
+
itype ? { type: itype } : {}
|
187
|
+
end
|
188
|
+
|
189
|
+
def clean_item_name item, context
|
190
|
+
item = item.to_name
|
191
|
+
return item if context == :raw
|
192
|
+
context ||= context_card.name
|
193
|
+
item.absolute_name context
|
194
|
+
rescue Card::Error::NotFound
|
195
|
+
# eg for invalid ids or codenames
|
196
|
+
# "Invalid Item: #{item}".to_name
|
197
|
+
nil
|
198
|
+
end
|
199
|
+
|
200
|
+
def strip_item item
|
201
|
+
item.gsub(/\[\[|\]\]/, "").strip
|
202
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
MAX_ANONYMOUS_SEARCH_PARAM = 1000
|
2
|
+
|
3
|
+
format do
|
4
|
+
def limit
|
5
|
+
@limit ||= contextual_param(:limit) || default_limit
|
6
|
+
end
|
7
|
+
|
8
|
+
def offset
|
9
|
+
@offset ||= contextual_param(:offset) || 0
|
10
|
+
end
|
11
|
+
|
12
|
+
def search_with_params
|
13
|
+
@search_with_params ||= card.item_names
|
14
|
+
end
|
15
|
+
|
16
|
+
def count_with_params
|
17
|
+
@count_with_params ||= card.item_names.count
|
18
|
+
end
|
19
|
+
|
20
|
+
def total_pages
|
21
|
+
return 1 if limit.zero?
|
22
|
+
((count_with_params - 1) / limit).to_i
|
23
|
+
end
|
24
|
+
|
25
|
+
def current_page
|
26
|
+
(offset / limit).to_i
|
27
|
+
end
|
28
|
+
|
29
|
+
# for override
|
30
|
+
def extra_paging_path_args
|
31
|
+
{}
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def contextual_param param
|
37
|
+
env_search_param(param) || voo_search_param(param)
|
38
|
+
end
|
39
|
+
|
40
|
+
def env_search_param param
|
41
|
+
enforcing_legal_limit param do
|
42
|
+
val = Env.params[param]
|
43
|
+
val.to_i if focal? && val.present?
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def enforcing_legal_limit param
|
48
|
+
yield.tap do |val|
|
49
|
+
enforce_legal_limit! val if param == :limit
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def enforce_legal_limit! val
|
54
|
+
return if Card::Auth.signed_in? || !val || val <= MAX_ANONYMOUS_SEARCH_PARAM
|
55
|
+
|
56
|
+
raise Card::Error::PermissionDenied,
|
57
|
+
"limit parameter exceeds maximum for anonymous users " \
|
58
|
+
"(#{MAX_ANONYMOUS_SEARCH_PARAM})"
|
59
|
+
end
|
60
|
+
|
61
|
+
def voo_search_param param
|
62
|
+
voo&.cql&.dig(param)&.to_i
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
#! no set module
|
2
|
+
|
3
|
+
# render paging links
|
4
|
+
class PagingLinks
|
5
|
+
def initialize total_pages, current_page
|
6
|
+
@total = total_pages
|
7
|
+
@current = current_page
|
8
|
+
end
|
9
|
+
|
10
|
+
# @param window [integer] number of page links shown left and right
|
11
|
+
# of the current page
|
12
|
+
# @example: current page = 5, window = 2
|
13
|
+
# |<<|1|...|3|4|[5]|6|7|...|10|>>|
|
14
|
+
# @yield [text, page, status, options] block to build single paging link
|
15
|
+
# @yieldparam status [Symbol] :active (for current page) or :disabled
|
16
|
+
# @yieldparam page [Integer] page number, first page is 0
|
17
|
+
# @return [Array<String>]
|
18
|
+
def build window=2, &block
|
19
|
+
@render_item = block
|
20
|
+
links window
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def links window
|
26
|
+
@window_start = [@current - window, 0].max
|
27
|
+
@window_end = [@current + window, @total].min
|
28
|
+
left_part + window_part + right_part
|
29
|
+
end
|
30
|
+
|
31
|
+
# the links around the current page
|
32
|
+
def window_part
|
33
|
+
(@window_start..@window_end).map do |page|
|
34
|
+
direct_page_link page
|
35
|
+
end.compact
|
36
|
+
end
|
37
|
+
|
38
|
+
def left_part
|
39
|
+
[
|
40
|
+
previous_page_link,
|
41
|
+
(direct_page_link 0 if @window_start.positive?),
|
42
|
+
(ellipse if @window_start > 1)
|
43
|
+
].compact
|
44
|
+
end
|
45
|
+
|
46
|
+
def right_part
|
47
|
+
[
|
48
|
+
(ellipse if @total > @window_end + 1),
|
49
|
+
(direct_page_link @total if @total > @window_end),
|
50
|
+
next_page_link
|
51
|
+
].compact
|
52
|
+
end
|
53
|
+
|
54
|
+
def previous_page_link
|
55
|
+
paging_item '<span aria-hidden="true">«</span>', previous_page,
|
56
|
+
"aria-label" => "Previous", status: :previous
|
57
|
+
end
|
58
|
+
|
59
|
+
def next_page_link
|
60
|
+
paging_item '<span aria-hidden="true">»</span>', next_page,
|
61
|
+
"aria-label" => "Next", status: :next
|
62
|
+
end
|
63
|
+
|
64
|
+
def direct_page_link page
|
65
|
+
return unless page >= 0 && page <= @total
|
66
|
+
paging_item page + 1, page
|
67
|
+
end
|
68
|
+
|
69
|
+
def ellipse
|
70
|
+
paging_item "<span>...</span>", nil, status: :ellipses
|
71
|
+
end
|
72
|
+
|
73
|
+
def paging_item text, page, options={}
|
74
|
+
status =
|
75
|
+
if page == @current
|
76
|
+
:current
|
77
|
+
else
|
78
|
+
options.delete :status
|
79
|
+
end
|
80
|
+
@render_item.call text, page, status, options
|
81
|
+
end
|
82
|
+
|
83
|
+
def previous_page
|
84
|
+
@current.positive? ? @current - 1 : false
|
85
|
+
end
|
86
|
+
|
87
|
+
def next_page
|
88
|
+
@current < @total ? @current + 1 : false
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
format :html do
|
2
|
+
PAGE_LI_CLASS = { ellipses: "disabled", current: "active" }.freeze
|
3
|
+
|
4
|
+
def with_paging path_args={}
|
5
|
+
with_paging_path_args path_args do
|
6
|
+
output [yield(@paging_path_args), _render_paging]
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
view :paging, cache: :never do
|
11
|
+
return "" unless paging_needed?
|
12
|
+
<<-HTML
|
13
|
+
<nav>
|
14
|
+
<ul class="pagination paging">
|
15
|
+
#{paging_links.join}
|
16
|
+
</ul>
|
17
|
+
</nav>
|
18
|
+
HTML
|
19
|
+
end
|
20
|
+
|
21
|
+
def paging_links
|
22
|
+
PagingLinks.new(total_pages, current_page).build do |text, page, status, options|
|
23
|
+
page_link_li text, page, status, options
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# First page is 0 (not 1)
|
28
|
+
def page_link_li text, page, status, options={}
|
29
|
+
wrap_with :li, class: page_link_li_class(status) do
|
30
|
+
page_link text, page, options
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def page_link_li_class status
|
35
|
+
["page-item", PAGE_LI_CLASS[status]].compact.join " "
|
36
|
+
end
|
37
|
+
|
38
|
+
def page_link text, page, options
|
39
|
+
return content_tag(:div, text.html_safe, class: "page-link") unless page
|
40
|
+
|
41
|
+
options.merge! class: "card-paging-link slotter page-link",
|
42
|
+
remote: true,
|
43
|
+
path: page_link_path_args(page)
|
44
|
+
link_to raw(text), options
|
45
|
+
end
|
46
|
+
|
47
|
+
def with_paging_path_args args
|
48
|
+
tmp = @paging_path_args
|
49
|
+
@paging_path_args = paging_path_args args
|
50
|
+
yield
|
51
|
+
ensure
|
52
|
+
@paging_path_args = tmp
|
53
|
+
end
|
54
|
+
|
55
|
+
def paging_path_args local_args={}
|
56
|
+
@paging_path_args ||= {}
|
57
|
+
@paging_path_args.reverse_merge!(limit: limit, offset: offset)
|
58
|
+
@paging_path_args.merge! extra_paging_path_args
|
59
|
+
@paging_path_args.merge local_args
|
60
|
+
end
|
61
|
+
|
62
|
+
def page_link_path_args page
|
63
|
+
paging_path_args.merge offset: page * limit
|
64
|
+
end
|
65
|
+
|
66
|
+
def paging_needed?
|
67
|
+
return false if limit < 1
|
68
|
+
return false if fewer_results_than_limit? # avoid extra count search
|
69
|
+
|
70
|
+
# count search result instead
|
71
|
+
limit < count_with_params
|
72
|
+
end
|
73
|
+
|
74
|
+
# clear we don't need paging even before running count query
|
75
|
+
def fewer_results_than_limit?
|
76
|
+
return false unless offset.zero?
|
77
|
+
|
78
|
+
limit > offset + search_with_params.length
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
format :json do
|
83
|
+
def page_link_path_args page
|
84
|
+
{
|
85
|
+
limit: limit,
|
86
|
+
offset: page * limit,
|
87
|
+
item: default_item_view, # hack. need standard voo handling
|
88
|
+
format: :json
|
89
|
+
}.merge extra_paging_path_args
|
90
|
+
end
|
91
|
+
|
92
|
+
view :paging_urls, cache: :never do
|
93
|
+
return {} unless total_pages > 1
|
94
|
+
|
95
|
+
{ paging: paging_urls_hash }
|
96
|
+
end
|
97
|
+
|
98
|
+
def paging_urls_hash
|
99
|
+
hash = {}
|
100
|
+
PagingLinks.new(total_pages, current_page).build do |_text, page, status, _options|
|
101
|
+
add_paging_url hash, page, status
|
102
|
+
end
|
103
|
+
hash
|
104
|
+
end
|
105
|
+
|
106
|
+
def add_paging_url hash, page, status
|
107
|
+
return unless page && status.in?(%i[next previous])
|
108
|
+
|
109
|
+
hash[status] = path page_link_path_args(page)
|
110
|
+
end
|
111
|
+
end
|
data/set/all/extended.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
|
2
|
+
def extended_item_cards context=nil
|
3
|
+
items = item_cards limit: "", context: (context || self).name
|
4
|
+
list = []
|
5
|
+
book = ::Set.new # avoid loops
|
6
|
+
extend_item_list items, list, book until items.empty?
|
7
|
+
list
|
8
|
+
end
|
9
|
+
|
10
|
+
def extended_item_contents context=nil
|
11
|
+
extended_item_cards(context).map(&:item_names).flatten
|
12
|
+
end
|
13
|
+
|
14
|
+
format do
|
15
|
+
delegate :extended_item_contents, to: :card
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def extend_item_list items, list, book
|
21
|
+
item = items.shift
|
22
|
+
return if already_extended? item, book
|
23
|
+
if item.collection?
|
24
|
+
# keep items in order
|
25
|
+
items.unshift(*item.item_cards)
|
26
|
+
else # no further level of items
|
27
|
+
list << item
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def already_extended? item, book
|
32
|
+
return true if book.include? item
|
33
|
+
book << item
|
34
|
+
false
|
35
|
+
end
|
36
|
+
|
37
|
+
# def extended_list context=nil
|
38
|
+
# context = (context ? context.name : name)
|
39
|
+
# args = { limit: "" }
|
40
|
+
# item_cards(args.merge(context: context)).map do |x|
|
41
|
+
# x.item_cards(args)
|
42
|
+
# end.flatten.map do |x|
|
43
|
+
# x.item_cards(args)
|
44
|
+
# end.flatten.map do |y|
|
45
|
+
# y.item_names(args)
|
46
|
+
# end.flatten
|
47
|
+
# # this could go on and on. more elegant to recurse until you don't have
|
48
|
+
# # a collection
|
49
|
+
# end
|
data/set/all/item.rb
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
def item_names _args={}
|
2
|
+
format._render_raw.split(/[,\n]/)
|
3
|
+
end
|
4
|
+
|
5
|
+
def item_cards _args={} # FIXME: this is inconsistent with item_names
|
6
|
+
[self]
|
7
|
+
end
|
8
|
+
|
9
|
+
def item_type
|
10
|
+
nil
|
11
|
+
end
|
12
|
+
|
13
|
+
def item_keys args={}
|
14
|
+
item_names(args).map do |item|
|
15
|
+
item.to_name.key
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def item_count args={}
|
20
|
+
item_names(args).size
|
21
|
+
end
|
22
|
+
|
23
|
+
def items_to_content array
|
24
|
+
items = array.map { |i| standardize_item i }.reject(&:blank?)
|
25
|
+
self.content = items.to_pointer_content
|
26
|
+
end
|
27
|
+
|
28
|
+
def standardize_item item
|
29
|
+
Card::Name[item]
|
30
|
+
end
|
31
|
+
|
32
|
+
def include_item? item
|
33
|
+
item_names.include? Card::Name[item]
|
34
|
+
end
|
35
|
+
|
36
|
+
def add_item item
|
37
|
+
return if include_item? item
|
38
|
+
items_to_content(items_strings << item)
|
39
|
+
end
|
40
|
+
|
41
|
+
def drop_item item
|
42
|
+
item = Card::Name[item]
|
43
|
+
return unless include_item? item
|
44
|
+
items_to_content(item_names.reject { |i| i == item })
|
45
|
+
end
|
46
|
+
|
47
|
+
def insert_item index, name
|
48
|
+
new_names = item_names
|
49
|
+
new_names.delete name
|
50
|
+
new_names.insert index, name
|
51
|
+
items_to_content new_names
|
52
|
+
end
|
53
|
+
|
54
|
+
def replace_item old, new
|
55
|
+
return unless include_item? old
|
56
|
+
drop_item old
|
57
|
+
add_item new
|
58
|
+
end
|
59
|
+
|
60
|
+
# I think the following should work as add_item...
|
61
|
+
#
|
62
|
+
def add_id id
|
63
|
+
add_item "~#{id}"
|
64
|
+
end
|
65
|
+
|
66
|
+
def drop_id id
|
67
|
+
drop_item "~#{id}"
|
68
|
+
end
|
69
|
+
|
70
|
+
def insert_id index, id
|
71
|
+
insert_item index, "~#{id}"
|
72
|
+
end
|
73
|
+
|
74
|
+
format do
|
75
|
+
def item_links _args={}
|
76
|
+
raw(render_core).split(/[,\n]/)
|
77
|
+
end
|
78
|
+
|
79
|
+
def nest_item cardish, options={}, &block
|
80
|
+
options = item_view_options options
|
81
|
+
options[:nest_name] = Card::Name[cardish].s
|
82
|
+
nest cardish, options, &block
|
83
|
+
end
|
84
|
+
|
85
|
+
def implicit_item_view
|
86
|
+
view = voo_items_view || default_item_view
|
87
|
+
Card::View.normalize view
|
88
|
+
end
|
89
|
+
|
90
|
+
def voo_items_view
|
91
|
+
return unless voo && (items = voo.items)
|
92
|
+
items[:view]
|
93
|
+
end
|
94
|
+
|
95
|
+
def default_item_view
|
96
|
+
:name
|
97
|
+
end
|
98
|
+
|
99
|
+
def item_view_options new_options={}
|
100
|
+
options = (voo.items || {}).clone
|
101
|
+
options = options.merge new_options
|
102
|
+
options[:view] ||= implicit_item_view
|
103
|
+
determine_item_view_options_type options
|
104
|
+
options
|
105
|
+
end
|
106
|
+
|
107
|
+
def determine_item_view_options_type options
|
108
|
+
return if options[:type]
|
109
|
+
type_from_rule = card.item_type
|
110
|
+
options[:type] = type_from_rule if type_from_rule
|
111
|
+
end
|
112
|
+
|
113
|
+
def listing listing_cards, item_args={}
|
114
|
+
listing_cards.map do |item_card|
|
115
|
+
nest_item item_card, item_args do |rendered, item_view|
|
116
|
+
wrap_item rendered, item_view
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def wrap_item item, _args={}
|
122
|
+
item # no wrap in base
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
format :html do
|
127
|
+
def wrap_item rendered, item_view
|
128
|
+
%(<div class="item-#{item_view}">#{rendered}</div>)
|
129
|
+
end
|
130
|
+
end
|
metadata
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: card-mod-collection
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.11.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ethan McCutchen
|
8
|
+
- Philipp Kühl
|
9
|
+
- Gerry Gleason
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2020-12-24 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: card
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
requirements:
|
19
|
+
- - '='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.101.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - '='
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
version: 1.101.0
|
29
|
+
description: ''
|
30
|
+
email:
|
31
|
+
- info@decko.org
|
32
|
+
executables: []
|
33
|
+
extensions: []
|
34
|
+
extra_rdoc_files: []
|
35
|
+
files:
|
36
|
+
- set/abstract/items.rb
|
37
|
+
- set/abstract/paging.rb
|
38
|
+
- set/abstract/paging/paging_links.rb
|
39
|
+
- set/abstract/paging/paging_views.rb
|
40
|
+
- set/all/extended.rb
|
41
|
+
- set/all/item.rb
|
42
|
+
homepage: http://decko.org
|
43
|
+
licenses:
|
44
|
+
- GPL-3.0
|
45
|
+
metadata:
|
46
|
+
card-mod: collection
|
47
|
+
post_install_message:
|
48
|
+
rdoc_options: []
|
49
|
+
require_paths:
|
50
|
+
- lib
|
51
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '2.5'
|
56
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
requirements: []
|
62
|
+
rubygems_version: 3.0.3
|
63
|
+
signing_key:
|
64
|
+
specification_version: 4
|
65
|
+
summary: collection (list and search)
|
66
|
+
test_files: []
|