card-mod-format 0.11.0
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 +7 -0
- data/lib/card/format/css_format.rb +17 -0
- data/lib/card/format/csv_format.rb +19 -0
- data/lib/card/format/data_format.rb +6 -0
- data/lib/card/format/file_format.rb +8 -0
- data/lib/card/format/html_format.rb +45 -0
- data/lib/card/format/js_format.rb +17 -0
- data/lib/card/format/json_format.rb +24 -0
- data/lib/card/format/rss_format.rb +9 -0
- data/lib/card/format/text_format.rb +16 -0
- data/lib/card/format/xml_format.rb +13 -0
- data/lib/card/path.rb +127 -0
- data/set/all/active_card.rb +6 -0
- data/set/all/base.rb +137 -0
- data/set/all/css.rb +37 -0
- data/set/all/csv.rb +93 -0
- data/set/all/error.rb +79 -0
- data/set/all/export.rb +68 -0
- data/set/all/file.rb +9 -0
- data/set/all/frame.rb +53 -0
- data/set/all/haml.rb +75 -0
- data/set/all/head.rb +148 -0
- data/set/all/header.rb +62 -0
- data/set/all/header/header_wrap.haml +4 -0
- data/set/all/html_content.rb +168 -0
- data/set/all/html_content/labeled.haml +4 -0
- data/set/all/html_error.rb +193 -0
- data/set/all/html_error/debug_server_error.haml +1015 -0
- data/set/all/html_error/not_found.haml +7 -0
- data/set/all/html_error/server_error.haml +5 -0
- data/set/all/html_show.rb +53 -0
- data/set/all/html_title.rb +47 -0
- data/set/all/html_wrapper.rb +159 -0
- data/set/all/js.rb +10 -0
- data/set/all/json.rb +166 -0
- data/set/all/links.rb +149 -0
- data/set/all/menu.rb +129 -0
- data/set/all/meta_tags.haml +4 -0
- data/set/all/path.rb +78 -0
- data/set/all/rich_html.rb +4 -0
- data/set/all/rss.rb +76 -0
- data/set/all/text.rb +7 -0
- data/set/self/home.rb +9 -0
- data/set/type/html.rb +27 -0
- data/set/type/json.rb +41 -0
- data/set/type/number.rb +22 -0
- data/set/type/phrase.rb +5 -0
- data/set/type/plain_text.rb +9 -0
- data/set/type/toggle.rb +38 -0
- data/set/type/uri.rb +15 -0
- metadata +123 -0
data/set/all/links.rb
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
RESOURCE_TYPE_REGEXP = /^([a-zA-Z][\-+\.a-zA-Z\d]*):/
|
2
|
+
|
3
|
+
# The #link_to methods support smart formatting of links in multiple formats.
|
4
|
+
format do
|
5
|
+
# Creates a "link", the meaning of which depends upon the format. In this base
|
6
|
+
# format, the link looks like [text][absolute path]
|
7
|
+
#
|
8
|
+
# @param text [String] optional string associated with link
|
9
|
+
# @param opts [Hash] optional Hash. In simple formats, :path is usually the only key
|
10
|
+
def link_to text=nil, opts={}
|
11
|
+
path = path((opts.delete(:path) || {}))
|
12
|
+
if text && path != text
|
13
|
+
"#{text}[#{path}]"
|
14
|
+
else
|
15
|
+
path
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# link to a different view of the current card
|
20
|
+
# @param view [Symbol,String]
|
21
|
+
# @param text [String]
|
22
|
+
# @param opts [Hash]
|
23
|
+
def link_to_view view, text=nil, opts={}
|
24
|
+
add_to_path opts, view: view unless view == :home
|
25
|
+
link_to text, opts
|
26
|
+
end
|
27
|
+
|
28
|
+
# link to a card other than the current card.
|
29
|
+
# @param cardish [Integer, Symbol, String, Card] a card identifier
|
30
|
+
# @param text [String]
|
31
|
+
# @param opts [Hash]
|
32
|
+
def link_to_card cardish, text=nil, opts={}
|
33
|
+
add_to_path opts, mark: Card::Name[cardish]
|
34
|
+
link_to text, opts
|
35
|
+
end
|
36
|
+
|
37
|
+
# a "resource" is essentially a reference to something that
|
38
|
+
# decko doesn't recognize to be a card. Can be a remote url,
|
39
|
+
# a local url (that decko hasn't parsed) or a local path.
|
40
|
+
# @param resource [String]
|
41
|
+
# @param text [String]
|
42
|
+
# @param opts [Hash]
|
43
|
+
def link_to_resource resource, text=nil, opts={}
|
44
|
+
resource = clean_resource resource, resource_type(resource)
|
45
|
+
link_to text, opts.merge(path: resource)
|
46
|
+
end
|
47
|
+
|
48
|
+
# smart_link_to is wrapper method for #link_to, #link_to_card, #link_to_view, and
|
49
|
+
# #link_to_resource. If the opts argument contains :view, :related, :card, or
|
50
|
+
# :resource, it will use the respective method to render a link.
|
51
|
+
#
|
52
|
+
# This is usually most useful when writing views that generate many different
|
53
|
+
# kinds of links.
|
54
|
+
def smart_link_to text, opts={}
|
55
|
+
if (linktype = %i[view card resource].find { |key| opts[key] })
|
56
|
+
send "link_to_#{linktype}", opts.delete(linktype), text, opts
|
57
|
+
else
|
58
|
+
send :link_to, text, opts
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def resource_type resource
|
65
|
+
case resource
|
66
|
+
when /^https?\:/ then "external-link"
|
67
|
+
when %r{^/} then "internal-link"
|
68
|
+
when /^mailto\:/ then "email-link"
|
69
|
+
when RESOURCE_TYPE_REGEXP then Regexp.last_match(1) + "-link"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def clean_resource resource, resource_type
|
74
|
+
if resource_type == "internal-link"
|
75
|
+
contextualize_path resource[1..-1]
|
76
|
+
else
|
77
|
+
resource
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def add_to_path opts, new_hash
|
82
|
+
opts[:path] = (opts[:path] || {}).merge new_hash
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
public
|
87
|
+
|
88
|
+
format :html do
|
89
|
+
# in HTML, #link_to renders an anchor tag <a>
|
90
|
+
# it treats opts other than "path" as html opts for that tag,
|
91
|
+
# and it adds special handling of "remote" and "method" opts
|
92
|
+
# (changes them into data attributes)
|
93
|
+
def link_to text=nil, opts={}
|
94
|
+
opts[:href] ||= path opts.delete(:path)
|
95
|
+
text = raw(text || opts[:href])
|
96
|
+
interpret_data_opts_to_link_to opts
|
97
|
+
wrap_with :a, text, opts
|
98
|
+
end
|
99
|
+
|
100
|
+
# in HTML, #link_to_card adds special css classes indicated whether a
|
101
|
+
# card is "known" (real or virtual) or "wanted" (unknown)
|
102
|
+
# TODO: upgrade from (known/wanted)-card to (real/virtual/unknown)-card
|
103
|
+
def link_to_card cardish, text=nil, opts={}
|
104
|
+
name = Card::Name[cardish]
|
105
|
+
slotterify opts if opts[:slotter]
|
106
|
+
add_known_or_wanted_class opts, name
|
107
|
+
super name, (text || name), opts
|
108
|
+
end
|
109
|
+
|
110
|
+
# in HTML, #link_to_view defaults to a remote link with rel="nofollow".
|
111
|
+
def link_to_view view, text=nil, opts={}
|
112
|
+
slotterify opts
|
113
|
+
super view, (text || view), opts
|
114
|
+
end
|
115
|
+
|
116
|
+
# in HTML, #link_to_resource automatically adds a target to external resources
|
117
|
+
# so they will open in another tab. It also adds css classes indicating whether
|
118
|
+
# the resource is internal or external
|
119
|
+
def link_to_resource resource, text=nil, opts={}
|
120
|
+
add_resource_opts opts, resource_type(resource)
|
121
|
+
super
|
122
|
+
end
|
123
|
+
|
124
|
+
private
|
125
|
+
|
126
|
+
def slotterify opts
|
127
|
+
opts.delete(:slotter)
|
128
|
+
opts.reverse_merge! remote: true, rel: "nofollow"
|
129
|
+
add_class opts, "slotter"
|
130
|
+
end
|
131
|
+
|
132
|
+
def add_known_or_wanted_class opts, name
|
133
|
+
known = opts.delete :known
|
134
|
+
known = Card.known?(name) if known.nil?
|
135
|
+
add_class opts, (known ? "known-card" : "wanted-card")
|
136
|
+
end
|
137
|
+
|
138
|
+
def interpret_data_opts_to_link_to opts
|
139
|
+
%i[remote method].each do |key|
|
140
|
+
next unless (val = opts.delete key)
|
141
|
+
opts["data-#{key}"] = val
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def add_resource_opts opts, resource_type
|
146
|
+
opts[:target] ||= "_blank" if resource_type == "external-link"
|
147
|
+
add_class opts, resource_type
|
148
|
+
end
|
149
|
+
end
|
data/set/all/menu.rb
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
format :html do
|
2
|
+
view :menu, denial: :blank, unknown: true do
|
3
|
+
return "" if card.unknown?
|
4
|
+
|
5
|
+
wrap_with :div, class: "card-menu #{menu_link_classes}" do
|
6
|
+
[render_help_link,
|
7
|
+
menu_link,
|
8
|
+
(voo.show?(:bridge_link) ? bridge_link(false) : nil)]
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def menu_link
|
13
|
+
case voo.edit
|
14
|
+
when :inline
|
15
|
+
edit_inline_link
|
16
|
+
when :full
|
17
|
+
edit_in_bridge_link
|
18
|
+
else # :standard
|
19
|
+
edit_link
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def edit_view
|
24
|
+
case voo.edit
|
25
|
+
when :inline
|
26
|
+
:edit_inline
|
27
|
+
when :full
|
28
|
+
:edit
|
29
|
+
else # :standard
|
30
|
+
edit_link
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
view :edit_link, unknown: true, denial: :blank do
|
35
|
+
edit_link edit_link_view
|
36
|
+
end
|
37
|
+
|
38
|
+
def edit_link_view
|
39
|
+
:edit
|
40
|
+
end
|
41
|
+
|
42
|
+
view :full_page_link do
|
43
|
+
full_page_link
|
44
|
+
end
|
45
|
+
|
46
|
+
view :bridge_link, unknown: true do
|
47
|
+
bridge_link
|
48
|
+
end
|
49
|
+
|
50
|
+
def bridge_link in_modal=true
|
51
|
+
opts = { class: "bridge-link" }
|
52
|
+
if in_modal
|
53
|
+
# add_class opts, "close"
|
54
|
+
opts["data-slotter-mode"] = "modal-replace"
|
55
|
+
end
|
56
|
+
link_to_view :bridge, material_icon(:more_horiz), opts
|
57
|
+
end
|
58
|
+
|
59
|
+
# no caching because help_text view doesn't cache, and we can't have a
|
60
|
+
# stub in the data-content attribute or it will get html escaped.
|
61
|
+
view :help_link, cache: :never, unknown: true do
|
62
|
+
help_link render_help_text, help_title
|
63
|
+
end
|
64
|
+
|
65
|
+
def help_link text=nil, title=nil
|
66
|
+
opts = help_popover_opts text, title
|
67
|
+
add_class opts, "_card-menu-popover"
|
68
|
+
link_to help_icon, opts
|
69
|
+
end
|
70
|
+
|
71
|
+
def help_popover_opts text=nil, title=nil
|
72
|
+
text ||= render_help_text
|
73
|
+
opts = { "data-placement": :left, class: "help-link" }
|
74
|
+
popover_opts text, title, opts
|
75
|
+
end
|
76
|
+
|
77
|
+
def help_icon
|
78
|
+
material_icon("help")
|
79
|
+
end
|
80
|
+
|
81
|
+
def help_title
|
82
|
+
"#{name_parts_links} (#{render_type}) #{full_page_link unless card.simple?}"
|
83
|
+
end
|
84
|
+
|
85
|
+
def name_parts_links
|
86
|
+
card.name.parts.map do |part|
|
87
|
+
link_to_card part
|
88
|
+
end.join Card::Name.joint
|
89
|
+
end
|
90
|
+
|
91
|
+
def full_page_link
|
92
|
+
link_to_card full_page_card, full_page_icon, class: classy("full-page-link")
|
93
|
+
end
|
94
|
+
|
95
|
+
def full_page_card
|
96
|
+
card
|
97
|
+
end
|
98
|
+
|
99
|
+
def edit_in_bridge_link opts={}
|
100
|
+
edit_link :bridge, opts
|
101
|
+
end
|
102
|
+
|
103
|
+
def edit_link view=:edit, opts={}
|
104
|
+
link_to_view view, opts.delete(:link_text) || menu_icon,
|
105
|
+
edit_link_opts(opts.reverse_merge(modal: :lg))
|
106
|
+
end
|
107
|
+
|
108
|
+
# @param modal [Symbol] modal size
|
109
|
+
def edit_link_opts modal: nil
|
110
|
+
opts = { class: classy("edit-link") }
|
111
|
+
if modal
|
112
|
+
opts[:"data-slotter-mode"] = "modal"
|
113
|
+
opts[:"data-modal-class"] = "modal-#{modal}"
|
114
|
+
end
|
115
|
+
opts
|
116
|
+
end
|
117
|
+
|
118
|
+
def menu_link_classes
|
119
|
+
"nodblclick" + (show_view?(:hover_link) ? " _show-on-hover" : "")
|
120
|
+
end
|
121
|
+
|
122
|
+
def menu_icon
|
123
|
+
material_icon "edit"
|
124
|
+
end
|
125
|
+
|
126
|
+
def full_page_icon
|
127
|
+
icon_tag :open_in_new
|
128
|
+
end
|
129
|
+
end
|
data/set/all/path.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
format do
|
2
|
+
# Decko uses the term "path" a bit unusually.
|
3
|
+
#
|
4
|
+
# In most formats, #path returns a full url. In HTML, it provides everything after
|
5
|
+
# the domain/port.
|
6
|
+
#
|
7
|
+
# If you're feeling saucy, you might point out that typically "paths" don't
|
8
|
+
# include queries and fragment identifiers, much less protocols, domains, and ports.
|
9
|
+
# 10 pedantry points to you! But "path" is easy to type and the method is smart about
|
10
|
+
# format needs, so using it will lead you down the right ... something or other.
|
11
|
+
|
12
|
+
# Format#path is for generating standard card routes, eg, assuming the card
|
13
|
+
# associated with the current format is named "current", it will generate paths like
|
14
|
+
# these:
|
15
|
+
|
16
|
+
# path view: :bar -> "current?view=bar"
|
17
|
+
# path mark: [mycardid] -> "mycardname"
|
18
|
+
# path format: :csv) -> "current.csv"
|
19
|
+
# path action: :update -> "update/current"
|
20
|
+
|
21
|
+
# #path produces paths that follow one of three main patterns:
|
22
|
+
|
23
|
+
# 1. mark[.format][?query] # standard GET request
|
24
|
+
# 2. action/mark[?query] # GET variant of standard actions
|
25
|
+
# 3. new/mark # shortcut for "new" view of cardtype
|
26
|
+
|
27
|
+
# @param opts [Hash, String] a String is treated as a complete path and
|
28
|
+
# bypasses all processing
|
29
|
+
# @option opts [String, Card::Name, Integer, Symbol, Card] :mark
|
30
|
+
# @option opts [Symbol] :action card action (:create, :update, :delete)
|
31
|
+
# @option opts [Symbol] :format
|
32
|
+
# @option opts [Hash] :card
|
33
|
+
# @option opts [TrueClass] :no_mark
|
34
|
+
|
35
|
+
def path opts={}
|
36
|
+
return opts unless opts.is_a? Hash
|
37
|
+
path = Card::Path.new(card, opts)&.render
|
38
|
+
contextualize_path path
|
39
|
+
end
|
40
|
+
|
41
|
+
# in base format (and therefore most other formats), even internal paths
|
42
|
+
# are rendered as absolute urls.
|
43
|
+
def contextualize_path relative_path
|
44
|
+
card_url relative_path
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
format :json do
|
49
|
+
def add_unknown_name_to_opts name, opts
|
50
|
+
# noop
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
format :css do
|
55
|
+
def contextualize_path relative_path
|
56
|
+
if Card.config.file_storage == :local
|
57
|
+
# absolute paths lead to invalid assets path in css for cukes
|
58
|
+
card_path relative_path
|
59
|
+
else
|
60
|
+
# ...but relative paths are problematic when machine output and
|
61
|
+
# hard-coded assets (like fonts) are on different servers
|
62
|
+
card_url relative_path
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
format :html do
|
68
|
+
# in HTML, decko paths rendered as relative to the site's root.
|
69
|
+
def contextualize_path relative_path
|
70
|
+
card_path relative_path
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
format :email_html do
|
75
|
+
def contextualize_path relative_path
|
76
|
+
card_url relative_path
|
77
|
+
end
|
78
|
+
end
|
data/set/all/rss.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
format :rss do
|
2
|
+
attr_accessor :xml
|
3
|
+
|
4
|
+
def initialize card, args
|
5
|
+
super
|
6
|
+
@xml = @parent ? @parent.xml : ::Builder::XmlMarkup.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def show view, args
|
10
|
+
view ||= :feed
|
11
|
+
render! view, args
|
12
|
+
end
|
13
|
+
|
14
|
+
# FIXME: integrate this with common XML features when it is added
|
15
|
+
view :feed, cache: :never do
|
16
|
+
return "RSS feeds disabled" unless Cardio.config.rss_enabled
|
17
|
+
begin
|
18
|
+
@xml.instruct! :xml, version: "1.0", standalone: "yes"
|
19
|
+
@xml.rss version: "2.0",
|
20
|
+
"xmlns:content" => "http://purl.org/rss/1.0/modules/content/" do
|
21
|
+
@xml.channel do
|
22
|
+
@xml.title render_feed_title
|
23
|
+
@xml.description render_feed_description
|
24
|
+
@xml.link render_url
|
25
|
+
render_feed_body
|
26
|
+
end
|
27
|
+
end
|
28
|
+
rescue => e
|
29
|
+
@xml.error "\n\nERROR rendering RSS: #{e.inspect}\n\n #{e.backtrace}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def raw_feed_items
|
34
|
+
[card]
|
35
|
+
end
|
36
|
+
|
37
|
+
view :feed_body, cache: :never do
|
38
|
+
raw_feed_items.each do |item|
|
39
|
+
@xml.item do
|
40
|
+
subformat(item).render! :feed_item
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
view :feed_title do
|
46
|
+
Card::Rule.global_setting(:title) + " : " + card.name.gsub(/^\*/, "")
|
47
|
+
end
|
48
|
+
|
49
|
+
view :feed_item do
|
50
|
+
@xml.title card.name
|
51
|
+
add_name_context
|
52
|
+
@xml.description render_feed_item_description
|
53
|
+
@xml.pubDate pub_date
|
54
|
+
@xml.link render_url
|
55
|
+
@xml.guid render_url
|
56
|
+
end
|
57
|
+
|
58
|
+
def pub_date
|
59
|
+
(card.updated_at || Time.zone.now).to_s(:rfc822)
|
60
|
+
# updated_at fails on virtual
|
61
|
+
# cards, because not all to_s's take args (just actual dates)
|
62
|
+
end
|
63
|
+
|
64
|
+
view :feed_item_description do
|
65
|
+
render_open_content
|
66
|
+
end
|
67
|
+
|
68
|
+
view(:feed_description) { "" }
|
69
|
+
view(:comment_box) { "" }
|
70
|
+
view(:menu) { "" }
|
71
|
+
|
72
|
+
view :open, :titled, mod: All::Base::Format
|
73
|
+
view :content, :core, mod: All::Base::Format
|
74
|
+
view :open_content, :core, mod: All::Base::Format
|
75
|
+
view :closed, :link, mod: All::Base::Format
|
76
|
+
end
|