If you like the idea of using data tiddlers, I think your architecture would be somewhat simplified by eliminating the spellbook
(etc.) field in favor of storing all a character’s known spells in their associated “Character Name/Spellbook” dictionary tiddler. If you already have this index (which contains both known spells and their current levels), there’s no particular value to having a field that only lists known spells; it’s one more thing you’d need to keep in sync, and it doesn’t provide any information you couldn’t access with [[Character Name/Spellbook]indexes[]]
.
I’ll try to go through your question marks in order and sketch out some possible approaches if you do go the data tiddler route. I’m not familiar with GURPS myself, so I’m not entirely sure how spellbooks are meant to function (does each character have a spellbook? More than one? How do editions factor into it?) So I’m using Character Name/Spellbook
as a placeholder title for a character-specific dictionary tiddler, but please adapt as appropriate.
-
Character view template - largely addressed above. Within a $list widget with the basic form…
<$let spellbook={{{ [<currentTiddler>] [[Spellbook]] +[join[/]] }}}>
<$list filter="[<spellbook>indexes[]]" variable="spell">
<$let level={{{ [<spellbook>getindex<spell>] ~0 }}}> <!-- displays "0" if the <<spell>> index does not exist or is blank -->
<<spell>>: <<level>>
</$let>
</$list>
</$let>
Here, I first defined the spellbook
variable assuming the form <<currentTiddler>>/Spellbook
.
You can use whatever formatting you like inside the list; to make a table with one spell per line, add <table>...</table>
around the entire $list and put your <tr><td>column content</td></tr>
within the list widget. (Header/footer row(s) go outside the $list.)
You should also be able to use this base list filter (though not the <<spell>>
variable) with a Shiraz dynamic table as part of a character tiddler view template; you’ll just need to make some custom /body/...
cell templates to display the columns you want. Dynamic table columns do not need to correspond to fields on the tiddler where the table will be displayed; they’re just an ordered list of column “types”. So if you have a “spell” column, it will look for a tiddler with the tag $:/tags/Table/BodyTemplate
which contains spell
in its tbl-column-list
field and use this tiddler as the cell template.
In this case, that template could look like
<td class="shiraz-dtable-title"><$link to=<<currentRecord>> /></td>
and a spell-level
cell template could look like
<td class="shiraz-dtable-title"><$text text={{{ [[Character Name/Spellbook]getindex<currentRecord>] }}} /></td>
You can use additional columns to pull information from the tiddler corresponding to that spell, e.g. <$transclude tiddler=<<currentRecord>> field="college" />
to transclude the contents of that spell’s college
field.
-
Character edit template - I’m not sure I understand this one on a conceptual level, but generally speaking, to make a dropdown containing all tiddlers with the Spellbook tag, you could use a $select widget something like this:
<$select tiddler="..." field="...">
<$list filter="[tag[Spellbook]]">
<option>{{!!title}}</option>
</$list>
</$select>
You’ll notice that I left the tiddler and field attributes blank; what goes there will depend on how you want to use this.
- If each character has one spellbook (or only one active at a time), you could use
tiddler=<<currentTiddler>>
(assuming <<currentTiddler>>
= character tiddler) and field="spellbook"
or "current-spellbook"
.
- If a character can have multiple spellbooks, you’ll want the
$select
widget to invoke an $action-listops
widget that modifies a field. In this case, you’ll need to save the selection to a temporary field (or the text field of a temporary tiddler, if you prefer), use it in the $action-listops
subfilter, and then delete the temporary field if desired.
\procedure add-spellbook()
<$action-listops $field="spellbooks" $subfilter="+[toggle{!!temp-spellbook}]" />
<$action-deletefield temp-spellbook />
\end
<$select field="temp-spellbook" actions=<<add-spellbook>>>
<$list filter="[tag[Spellbook]]">
<option>{{!!title}}</option>
</$list>
</$select>
-
Spellbook view template - this may be part of point #1? No need to deal with a “spellbook” field containing a list of spells; the data tiddler itself is our sole source of truth. (This is a good TW practice, generally speaking: don’t duplicate information that’s already available elsewhere in your wiki, when you can retrieve it with a filter instead!)
-
Spellbook edit template - this could look a lot like your view template, but with an $edit-text widget in place of the index value.
<$let spellbook={{{ [<currentTiddler>] [[Spellbook]] +[join[/]] }}}>
<$list filter="[<spellbook>indexes[]]" variable="spell">
<<spell>>: <$edit-text tiddler=<<spellbook>> index=<<spell>> type=number default="0" size=2 />
</$list>
</$let>
And a general note on adding spells (since the $action-listops
solution we worked out earlier assumes a single field, not a data tiddler):
- To make a comparable button that adds/removes
<<currentRecord>>
from the <<spellbook>>
data tiddler:
<% if [<spellbook>has:index<currentRecord>] %>
<!-- DELETE THIS SPELL FROM THE DATA TIDDLER -->
<$action-setfield $tiddler=<<spellbook>> $index=<<currentRecord>> />
<% else %>
<!-- ADD THIS SPELL TO THE DATA TIDDLER -->
<$action-setfield $tiddler=<<spellbook>> $index=<<currentRecord>> $value="0" />
<% endif %>
Despite the name, the $action-setfield widget is the simplest way to modify an index.
- Assuming
<<spellbook>>
has already been defined to refer to the appropriate data tiddler…
- If the data tiddler has an index corresponding to
<<currentRecord>>
, delete it.
- For whatever reason,
$action-deletefield
does not work with indexes! Instead, to delete an index, we need to use the slightly unintuitive workaround of using $action-setfield
without a $value
.
- If not, add an index for
<<currentRecord>>
with a starting value (level) of 0.
I could also imagine adding a spell to a character’s spellbook from, say, that spell’s tiddler; in this case, you’d probably want to use
- a
$select
(storing its value to the text field of $:/temp
-prefixed tiddler) to choose the character
- a
$let
widget defining the data tiddler to be modified based on the character selection, e.g. <$let spellbook={{{ [[$:/temp/character]get[text]] [[Spellbook]] +[join[/]] }}}
>, wrapping
- a button that adds/removes a
<<currentTiddler>>
index (rather than <<currentRecord>>
) from the chosen data tiddler.
…
Sorry, this got quite long! Let me know if you’d me to expand on anything.