1 --[[ Example for Documentation System [`doc`].
2 Reminder: This mod is the core of the Help modpack. It is thus rather low-level.
3 Use this to add your very own categories and entries, and to use some utility
6 This example demonstrates how to add categories and how to add entries into them.
7 It also demonstrates the versatility of the very important `build_formspec`
8 function used in category definitions. ]]
10 -- Let's start with a very simple text-based category.
11 -- This category only contains simple text.
12 doc
.add_category("example1", {
13 -- This name is for humans and mandatory
14 name
= "Example: Text",
15 -- This category uses a preset formspec builder for simple text
16 build_formspec
= doc
.entry_builders
.text
17 --[[ Reminder: build_formspec determines how the entry data will be presented
21 doc
.add_category("sexample", {
22 name
= "Example: Empty",
27 -- Entries for the aforementioned category. We add 2 entries.
28 doc
.add_entry("example1", "text", {
29 -- This is for the entry title in the user interface, it's mandatory.
30 name
= "Text example",
31 -- For this category, the entry data is simply the text to be displayed
32 data
= "Lorem Minetest dolor sit amet. Bla bla bla bla Minetest bla bla bla bla Mese bla. Bla bla bla bla bla, celeron55 bla bla, bla.",
35 -- We will use this entry in doc_identifier.lua
36 doc
.add_entry("example1", "entity", {
37 name
= "Entity entry",
38 data
= "This is the entry for the entity (added in doc_identifier.lua). The example entity is just a simple cube which floats in the air. Punch it to destroy it.",
41 -------------------------------------------------------------------------------
43 --[[ Category with hidden entry.
44 This is a category like the one before, but this time, we add a hidden entry.
46 doc
.add_category("example_hide", {
47 name
= "Example: Hidden entry",
48 build_formspec
= doc
.entry_builders
.text
51 -- This entry will start hidden. The user will not see it until it gets
52 -- revealed by using doc.mark_entry_as_revealed. Note that you should
53 -- NOT hide entries if there is no way for the player to reveal them.
54 doc
.add_entry("example_hide", "hidden", {
55 name
= "Hidden Entry",
57 data
= "This entry is hidden.",
60 -- This chat command demonstrates how to use `doc.mark_entry_as_revealed`.
61 minetest
.register_chatcommand("doc_example_reveal", {
63 description
= "Reveal the hidden entry of the doc_example mod",
65 func
= function(playername
, params
)
66 -- This reveals the previously created entry
67 doc
.mark_entry_as_revealed(playername
, "example_hide", "hidden")
69 minetest
.chat_send_player(playername
, "The hidden doc_example entry has been revealed! Look into the category “Example Hidden” to see it.")
72 --[[ In actual games, you would probably want to invent more engaging ways to
73 reveal entries. ;-) ]]
75 -------------------------------------------------------------------------------
76 --[[ A simple category with 3 entries: Cities.
77 Now we're getting somewhere! This time, we define a custom build_formspec
78 function to display entry data dynamically. ]]
79 doc
.add_category("example2", {
80 name
= "Example: Cities",
81 description
= "Example category: Quick information about the cities of the world",
82 --[[ This is a manual formspec builder: This will parse the entry data and
83 turns it into nice formspec widgets.
84 Reminder: We MUST return a valid formspec string! ]]
85 build_formspec
= function(data
)
86 return "label[0,1;Description: "..minetest
.formspec_escape(data
.description
).."]" ..
87 "label[0,2;Population: "..data
.population
.."]"
90 --[[ ADVANCED: Sorting example ]]
91 --[[ The entry data includes population as a number. This means we could (if we
92 want to) define a custom sorting function. This affects the order of the entries.
93 It makes sure that in the list of entries, the city with the highest population
94 comes first. Custom sorting is entirely optional but it might make it easier
95 for the user to navigate. But note that the default alphabetical sorting is
96 often good as well. ]]
98 sorting_data
= function(entry1
, entry2
)
99 return entry1
.data
.population
> entry2
.data
.population
103 doc
.add_entry("example2", "london", {
105 -- Reminder: This data is put into the previous build_formspec function
107 description
= "London is the capital of the United Kingdom.",
108 population
= 8538689,
111 doc
.add_entry("example2", "shanghai", {
114 description
= "Shanghai lies in China and is one of the biggest cities in the world.",
115 population
= 23019148,
118 doc
.add_entry("example2", "tripoli", {
121 description
= "Tripoli is the capital of Lybia.",
122 population
= 1780000,
126 -------------------------------------------------------------------------------
127 --[[ Formspec category: This category shows how you can add widgets in entries
128 and even interact with them ]]
129 doc
.add_category("example3", {
130 name
="Example: Formspec",
131 description
="Example category for manual free-form formspec entries",
132 --[[ This is a built-in formspec builder. In this case, the entry data
133 is expected to contains the full formspec definition for any entry.
134 This is useful if you want to build every entry by hand. The downside
135 is that it doesn't allow for dynamic entries. ]]
136 build_formspec
= doc
.entry_builders
.formspec
,
138 --[[ Sorting example ]]
139 --[[ This demonstrates the custom sorting type. In the entry list, the
140 entries will appear in the exact order as specified. ]]
142 sorting_data
= { "simple_bad", "simple_good", "multi", "testbutton" },
145 -- Just an entry with a label (BAD example)
146 doc
.add_entry("example3", "simple_bad", {
148 -- Please note the coordinates are shoddily chosen here, the don't respect
149 -- the Documention System formspec boundaries at all, so this is just a guess.
150 data
= "label[5,5;Just a bad, bad label.]"
153 -- Just an entry with a label (good example)
154 doc
.add_entry("example3", "simple_good", {
156 --[[ This is the proper way to add widgets (this is also how you should do it in build_formspec):
157 Defining the coordinates relative to the Documentation System's boundaries. In this case,
158 the label will be at the top right. ]]
159 data
= "label["..doc
.FORMSPEC
.ENTRY_START_X
..","..doc
.FORMSPEC
.ENTRY_START_Y
..";Just a good label.]"
162 -- Now let's get crazy with MULTIPLE formspec entries. How awesome is that?
163 doc
.add_entry("example3", "multi", {
165 -- Label, just like before
166 data
= "label["..doc
.FORMSPEC
.ENTRY_START_X
..","..doc
.FORMSPEC
.ENTRY_START_Y
..";Just another label.]" ..
167 -- Note the different Y offsets
168 "button["..doc
.FORMSPEC
.ENTRY_START_X
..","..(doc
.FORMSPEC
.ENTRY_START_Y
+ 1)..";5,1;example_useless;Useless button]" ..
169 "button["..doc
.FORMSPEC
.ENTRY_START_X
..","..(doc
.FORMSPEC
.ENTRY_START_Y
+ 2)..";5,1;example_useless;Useless button 2]" ..
170 "button["..doc
.FORMSPEC
.ENTRY_START_X
..","..(doc
.FORMSPEC
.ENTRY_START_Y
+ 3)..";5,1;example_useless;Useless button 3]"
172 -- As you see, it's special at all. It's a normal formspec string, just longer.
175 -- This entry will be interactive.
176 doc
.add_entry("example3", "testbutton", {
178 -- This button actually will be used for an event …
179 data
= "button["..doc
.FORMSPEC
.ENTRY_START_X
..","..doc
.FORMSPEC
.ENTRY_START_Y
..";5,1;example_button;Event]",
182 -- … and here we react on the button event by writing something into the chat
183 -- This demonstrates how you can use an entry widget for custom actions
184 minetest
.register_on_player_receive_fields(function(player
, formname
, fields
)
185 -- Condition 1: This checks if the player is even using the entry tab.
186 -- This check is always the same.
187 if formname
== "doc:entry" then
188 local playername
= player
:get_player_name()
189 -- Condition 2: this check is required to make sure we “listen”
190 -- to the correct entry
191 local category_id
, entry_id
= doc
.get_selection(playername
)
192 if category_id
== "example3" and entry_id
== "testbutton" then
193 -- Condition 3: Has the widget we actually care about been pressed?
194 if fields
.example_button
then
195 -- All conditions are met! Now the custom action can be executed
196 minetest
.chat_send_player(playername
, "You have pressed the event button!")
202 -------------------------------------------------------------------------------
203 --[[ This category demonstrates the use of the gallery widget. ]]
204 -- FIXME: Depends on Minetest Game
205 doc
.add_category("example4", {
206 name
="Example: Galleries",
207 build_formspec
= function(data
, playername
)
208 -- The trick here is to include doc.widgets.gallery into the custom
209 -- build_formspec definition.
211 --[[ Mostly using default values, but we want an aspect ratio of
213 formspec
= formspec
.. doc
.widgets
.gallery(data
, playername
, nil, nil, 1)
218 -- Several gallery entries
219 doc
.add_entry("example4", "gallery2", {
220 name
="Gallery with 2 images",
221 -- The entry data will be also fed into `doc_widgets_gallery`
223 {image
="default_grass.png"},
224 {image
="default_book.png"}
228 doc
.add_entry("example4", "gallery3", {
229 name
="Gallery with 3 images",
231 {image
="default_grass.png"},
232 {image
="default_book.png"},
233 {image
="default_papyrus.png"}},
236 --[[ The default gallery size is 3. But this gallery has 4 images.
237 The Documentation System automatically adds “scroll buttons”
238 if the number of images exceeds the gallery size ]]
239 doc
.add_entry("example4", "gallery4", {
240 name
="Gallery with 4 images",
242 {image
="default_dirt.png"},
243 {image
="default_leaves.png"},
244 {image
="default_brick.png"},
245 {image
="default_gold_block.png"}
249 doc
.add_entry("example4", "gallery5", {
250 name
="Gallery with 5 images",
252 {image
="default_dirt.png"},
253 {image
="default_leaves.png"},
254 {image
="default_brick.png"},
255 {image
="default_gold_block.png"},
256 {image
="default_bronze_block.png"}
260 doc
.add_entry("example4", "gallery6", {
261 name
="Gallery with 6 images",
263 {image
="default_grass.png"},
264 {image
="default_dirt.png"},
265 {image
="default_leaves.png"},
266 {image
="default_brick.png"},
267 {image
="default_gold_block.png"},
268 {image
="default_bronze_block.png"}},
271 doc
.add_entry("example4", "gallery7", {
272 name
="Gallery with 7 item images",
274 -- You can use this syntax to display item images instead of normal textures
275 {image
="default:bookshelf", imagetype
="item"},
276 {image
="default:grass_5", imagetype
="item"},
277 {image
="default:dirt", imagetype
="item"},
278 {image
="default:fence_wood", imagetype
="item"},
279 {image
="default:flint", imagetype
="item"},
280 {image
="default:goldblock", imagetype
="item"},
281 {image
="default:bronzeblock", imagetype
="item"}},