-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathplugin.rb
More file actions
187 lines (171 loc) · 5.81 KB
/
plugin.rb
File metadata and controls
187 lines (171 loc) · 5.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# frozen_string_literal: true
# name: custom-fields
# about: Discourse plugin showing how to add custom fields to Discourse topics
# version: 1.0
# authors: Joe Stanton
# contact email: intunedeals@gmail.com
# url: https://github.com/JStantonWordPress/CustomFields
enabled_site_setting :topic_custom_field_enabled
register_asset 'stylesheets/common.scss'
##
# type: introduction
# title: Add a custom field to a topic
# description: To get started, load the [discourse-topic-custom-fields](https://github.com/pavilionedu/discourse-topic-custom-fields)
# plugin in your local development environment. Once you've got it
# working, follow the steps below and in the client "initializer"
# to understand how it works. For more about the context behind
# each step, follow the links in the 'references' section.
##
after_initialize do
Price = "Price"
URL = "URL"
FIELD_TYPE = "string"
##
# type: step
# number: 1
# title: Register the field
# description: Where we tell discourse what kind of field we're adding. You
# can register a string, integer, boolean or json field.
# references: lib/plugins/instance.rb,
# app/models/concerns/has_custom_fields.rb
##
register_topic_custom_field_type(Price, FIELD_TYPE.to_sym)
register_topic_custom_field_type(URL, FIELD_TYPE.to_sym)
##
# type: step
# number: 2
# title: Add getter and setter methods
# description: Adding getter and setter methods is optional, but advisable.
# It means you can handle data validation or normalisation, and
# it lets you easily change where you're storing the data.
##
##
# type: step
# number: 2.1
# title: Getter method
# references: lib/plugins/instance.rb,
# app/models/topic.rb,
# app/models/concerns/has_custom_fields.rb
##
add_to_class(:topic, Price.to_sym) do
if !custom_fields[Price].nil?
custom_fields[Price]
else
nil
end
end
add_to_class(:topic, URL.to_sym) do
if !custom_fields[URL].nil?
custom_fields[URL]
else
nil
end
end
##
# type: step
# number: 2.2
# title: Setter method
# references: lib/plugins/instance.rb,
# app/models/topic.rb,
# app/models/concerns/has_custom_fields.rb
##
add_to_class(:topic, "#{Price}=") do |value|
custom_fields[Price] = value
end
add_to_class(:topic, "#{URL}=") do |value|
custom_fields[URL] = value
end
##
# type: step
# number: 3
# title: Update the field when the topic is created or updated
# description: Topic creation is contingent on post creation. This means that
# many of the topic update classes are associated with the post
# update classes.
##
##
# type: step
# number: 3.1
# title: Update on topic creation
# description: Here we're using an event callback to update the field after
# the first post in the topic, and the topic itself, is created.
# references: lib/plugins/instance.rb,
# lib/post_creator.rb
##
on(:topic_created) do |topic, opts, user|
topic.send("#{Price}=".to_sym, opts[Price.to_sym])
topic.save!
end
on(:topic_created) do |topic, opts, user|
topic.send("#{URL}=".to_sym, opts[URL.to_sym])
topic.save!
end
##
# type: step
# number: 3.2
# title: Update on topic edit
# description: Update the field when it's updated in the composer when
# editing the first post in the topic, or in the topic title
# edit view.
# references: lib/plugins/instance.rb,
# lib/post_revisor.rb
##
PostRevisor.track_topic_field(Price.to_sym) do |tc, value|
tc.record_change(Price, tc.topic.send(Price), value)
tc.topic.send("#{Price}=".to_sym, value.present? ? value : nil)
end
PostRevisor.track_topic_field(URL.to_sym) do |tc, value|
tc.record_change(URL, tc.topic.send(URL), value)
tc.topic.send("#{URL}=".to_sym, value.present? ? value : nil)
end
##
# type: step
# number: 4
# title: Serialize the field
# description: Send our field to the client, along with the other topic
# fields.
##
##
# type: step
# number: 4.1
# title: Serialize to the topic
# description: Send your field to the topic.
# references: lib/plugins/instance.rb,
# app/serializers/topic_view_serializer.rb
##
add_to_serializer(:topic_view, Price.to_sym) do
object.topic.send(Price)
end
add_to_serializer(:topic_view, URL.to_sym) do
object.topic.send(URL)
end
##
# type: step
# number: 4.2
# title: Preload the field
# description: Discourse preloads custom fields on listable models (i.e.
# categories or topics) before serializing them. This is to
# avoid running a potentially large number of SQL queries
# ("N+1 Queries") at the point of serialization, which would
# cause performance to be affected.
# references: lib/plugins/instance.rb,
# app/models/topic_list.rb,
# app/models/concerns/has_custom_fields.rb
##
add_preloaded_topic_list_custom_field(Price)
add_preloaded_topic_list_custom_field(URL)
##
# type: step
# number: 4.3
# title: Serialize to the topic list
# description: Send your preloaded field to the topic list.
# references: lib/plugins/instance.rb,
# app/serializers/topic_list_item_serializer.rb
##
add_to_serializer(:topic_list_item, Price.to_sym) do
object.send(Price)
end
add_to_serializer(:topic_list_item, URL.to_sym) do
object.send(URL)
end
end