It appears to me that there's a great deal I don't know about this subject. What I do know, however, is enough to create functioning nodetypes which do interesting things.
Like just about everything else in Everything, a nodetype is a node. In fact, the nodetype called nodetype is, itself, a node: node_id=1. Put that in your pipe and smoke it. I'm told that deleting that one is a bad idea.
When you create a new nodetype, it "inherits" its properties from an existing nodetype. The root of this inheritance tree is the "node" nodetype. The properties are as follows:
- Nodetype Properties
- Authorized Readers (usergroup node_id)
- Authorized Creators (usergroup node_id)
- Authorized Deleters (usergroup node_id)
- Restrict Duplicates (node_identical titles) (yes|no)
- SQL Table (dbtable node_id)
- Extends Nodetype (nodetype node_id)
- Relevant pages (list of node_ids)
- Active Maintenances (list of node_ids)
Now, let's go down that list and look at each one.
- Authorized Readers
This field and the next two define permissions enforced by the Everything core. A nodetype can implement its own permissions if the programmer chooses, but that's a lot more work. You'd do that in the nodetype's associated htmlpages, which we'll be getting to.
This field is the node_id of a usergroup node. If this value is 0, any user account may read a node of this type; otherwise, it can only be read by members of the specified usergroup. Members of the gods group can read anything, of course, unless the nodetype itself implements a permission scheme of its own which explicitly prevents gods from reading it. Hell, if you've got too much time on your hands, you could restrict access to users whose names begin with 'w', or to users who use <pre> tags in their homenode bios. I don't know why you'd do that, but you could.
- Authorized Creators
Same deal as Authorized Readers, but applying to creation.
- Authorized Deleters
Same deal as Authorized Readers and Authorized Creators, but applying to deletion.
- Restrict Duplicates
If this is "true", then when a user attempts to create a node with op=new, the system will refuse to create a new node if there is an existing node of the same type with the requested title. That doesn't mean a god can't waltz by and rename two nodes to the same title.
- SQL Table
All nodes of any type have a record in the node dbtable. A nodetype can specify a second table in which the node will store further information. This is inherited. If you inherit from the document nodetype, nodes of your new type will have all the fields in the node table, plus all the fields in the document table.
You can then add your own new dbtable, and (in theory) get the fields in all three. In practice, I haven't been able to make this happen: The middle one seemed to get lost. However, the writeup nodetype does exactly that. It inherits from document, it clearly uses the doctext field from the document table, and it's got its own table as well. Go figure. Any insight into this puzzling phenomenon would be very welcome.
- Extends Nodetype
This is the nodetype from which your nodetype inherits.
- Relevant Pages
This is where the fun starts. It's not a property of the nodetype itself, really. You might want to read the "displaytype" section of Everything2 URL Interface to get some more grounding into what this is about.
When a node is displayed, it can be displayed in varying ways. This is the "displaytype". The default displaytype is "display"; otherwise, the system tries to use the value displaytype= parameter from the query.
A displaytype is implemented as an htmlpage node (see writeup display page for an example). By convention, these are named "nodetype displaytype page". They have a pagetype field, which is the node_id of the nodetype they're used to display. They also have a displaytype field, which is an arbitrary string. If you try to display a writeup node with displaytype=edit, the system will look for an htmlpage with a pagetype of "writeup" and a displaytype of "edit". It happens that there is one, so you're set. If there isn't one -- displaytype=arglebargle, for example (try it!) -- the system will spit in your eye.
htmlpages also have a parent container field, which is the node_id of a node of type container. The system starts with the displaytype htmlpage and works outward to the parent container, then the parent container of the parent container, etc., until it hits a dead end: Each "page" generates a string which is inserted into the next one out (containers should have the string "CONTAINED_STUFF" in them somewhere: "CONTAINED_STUFF" is replaced with the stuff to be contained). If the parent container is e2container, you'll get an ordinary E2 page, with nodelets and so on. rawdata raw page (for rawdata nodes, when displaytype=raw) is an example of an htmlpage with no parent container.
If you just stick with e2container, you won't have to worry about all the nesting CONTAINED_STUFF stuff.
An htmlpage can also belong to a theme. If there are two writeup display pages for your chosen displaytype, one belonging to no theme and one belonging to the theme you're using, the system will use the one belonging to your theme.
This is one of the places where a nodetype can implement its own special permissioning scheme (Active Maintenances is the other): You can put any arbitrary code you like in one of these, so your code could just refuse to display anything for users who have too many vowels in their names.
These are inherited along with everything else, but note that the nodetype itself doesn't "know" about them. They associate themselves with it, not vice versa. When you display a nodetype, the nodetype display page digs up all the relevant pages and lists them.
- Active Maintenances
This is a list of nodes of type maintenance. A maintenance node contains perl code which is executed in response to the creation, deletion, or updating of a node of a given type. Like the displaytype thing, maintenance nodes associate themselves with a given nodetype, and they also specify which of the three events they apply to. Unlike displaytypes, you only get those three events.
Maintenances are like constructors and destructors, mainly: For example, when you delete an e2node, the system should delete all of the writups belonging that that node. This is done in e2node maintenance delete.
There are other topics of interest: If your nodetype inherits from the nodegroup type, you get a nodegroup. The writeups belonging to an e2node are a nodegroup, as are the replies to a debatecomment node. I have no clue how this is implemented. See e2node maintenance delete for a clear and simple example of how to iterate through the items in a nodegroup. writeup maintainance create has code for adding a node to somebody's nodegroup.
When trying to decipher this stuff, your best friend is List Nodes of Type. Use it, every day.
Comments and questions are more than welcome: They're eagerly solicited. I just barfed up everything I could remember about the topic and shoehorned it into an arbitrary outline. Inevitably, there will be errors, omissions, and bits that don't make much sense.