ComicFury Template System Documentation

Welcome to the official DragonSlayer Template Engine syntax documentation. Hopefully this instruction will be able to make you understand how things work when editing your Layout using HTML. Note that you are expected to have at the very least a vague idea of what HTML is and how to use it. It's kind of a prerequisite to editing Layouts anyway, but you're not expected to be an expert or anything. Let's clear up some terminology first:

Terminology & Explanation of Elements:
Template
A template is, for our purposes, just the HTML code for the different areas of the Layout.



Template Engine
A template engine is a system that allows you to seperate your HTML code from the actual content. This means instead of having to write the HTML code for every new page of your comic, you only have to write one page, and the template engine will automatically fill in the data for each page. It does this using a bunch of special constructs, explained below.



Element
In this context, and element is a piece of code that will get replaced by the template engine in one way or another. The different elements are explained below. An element always has a name that usually gives a hint to what it contains.



Variable
A variable is, for our purposes, a code name for something that is different from page to page or webcomic to webcomic. For example, if you want to show the image of your comic strip, you are going to need a variable holding the comic image, so that it can change to the correct image on each page. To put it more simply, a variable is something that gets replaced with content that can change from page to page.

Example:
[v:comicimage]




Condition
A condition (or sometimes conditional) consists of two parts. A starting part and an ending part. Between those parts you will usually find HTML or text, and sometimes more template code, like variables or even more conditions and loops. The purpose of a condition is simple, it only displays the text if the condition itself is true. Usually this means if the content of a variable is not empty and not zero. This can be useful, for example, if you only want to show a "next comic" button if there is a next comic. Often there will be variables specifically created to be used in conditions, these often start with "is" or "has".

Example:
[c:islastcomic]This is the last comic currently uploaded![/]




Negated condition
Conditions only display the text between their start and end if the variable exists. But what if you want to only display the text if it doesn't exist? Look at the previous example. It's displaying a text if the comic is the last currently uploaded. Wouldn't it make more sense if it didn't display a text if it was the last, like the link to the next comic? A negated condition will do just that. In many programming languages, the exclamation point is used to signify negation. This is true of this template engine as well.

Example:
[c:!islastcomic]Click here for the next comic[/]




Loop
A loop looks and behaves similarly to a condition. It too has a starting code and an ending code.
But what does a loop do? A loop contains data that needs to be repeated a certain amount of times, with different data each time. For example, you will want to be able to display whatever amount of comments was left on the comic, without having to repeat the code over and over again. A loop does this for you. It takes sets of data, and repeats it one time for each set.

Example:
[l:comment]This text will get repeated once for each comment left.[/]




End tags
The ending code is the "[/]" that you saw in both loops and conditions above. It closes a command. For example, a condition tells you to only show the text/html until the end tag if the variable in the condition exists and is not empty.
In the dragonslayer template engine, the universal ending code is "[/]". This stops you from accidentally messing up the order in which you close elements.


Loop variables
Loops wouldn't be very useful if you didn't have a way to make the data change in each iteration. You've already learned about variables being replaced with different content each page, and loop variables get replaced with different content each iteration of a loop. They are technically just like normal variables, but the name always starts with "l."

Optional addendum for experts: If you're familiar with programming, you may know what an Array is. It's a construct that stores data (usually) of the same type. In this template engine, the period in variable names signifies the array, and what follows after it is the element name. The l array is dynamically generated each iteration of the loop.

Example:
[l:comment]Comment: [v:l.comment] - End of comment. [/]




Loop conditions
Loop conditions are just like regular conditions. Their contents either get removed or stay, depending on the content of the variable. The only differences are, just like with loop variables, that they can have different contents each iteration of the loop, and that their name always starts with "l."

Example:
[l:comment]Was this comment left by someone not logged in? [c:l.isguest]Yes![/] [/]


Negated example:
[l:comment]Was this comment left by someone not logged in? [c:!l.isguest]No![/] [/]



And that's it! Now you are familiar with all the different elements that compose a template engine. This is technically all you need to know. But let's look at the different elements a bit closer and familiarize ourselves with everything.


Recognizing layout codes:
You wouldn't want to accidentally chop off some important layout codes and break your layout. But what parts of the layout are layout codes, and how do I tell if they're any important?
Let's look at the different layout codes a bit more carefully and examine how everything goes together.
We will look at a simple example making use of all the different codes.
<ul id="nav">
	<li><a href="/comics/">Latest</a></li>
	<li><a href="/comics/first">First</a></li>
	<li><a href="/archive/">Archive</a></li>
	<li><a href="/blog/">Blog</a></li>
	[c:searchon]
		<li><a href="/search/">Search</a></li>
	[/]
	[l:extrapages]
		<li><a href="[v:l.link]">[v:l.title]</a></li>
	[/]
	[c:!hidefromhost]
		<li><a href="[v:addsubscriptionlink]">Subscribe</a></li>
	[/]
</ul>


This is the code for a typical webcomic navigation, the basic links on your comic. You will see variables, conditions, loops and loop variables.

The first thing you probably notice is that every element is surrounded in brackets: [ ]
Then, a single character determines the type of element:
c - condition
l - loop
v - variable
After that, a colon seperates the element type from the element name. If the element starts with l., it's a loop-element.

Then finally, if the element is a condition or a loop, it has to end. The next "[/]" you find will end the element. Only loops and conditions get ending tags.

Now that we've done the basic rundown, let's look at every piece of this code to understand what it does:

<ul id="nav">
	<li><a href="/comics/">Latest</a></li>
	<li><a href="/comics/first">First</a></li>
	<li><a href="/archive/">Archive</a></li>
	<li><a href="/blog/">Blog</a></li>

Just regular HTML code generating some links to different parts of the comic

[c:searchon]

A condition checking if the webcomic has enabled the comic search in it's webcomic settings. Everything after this until the next "[/]" will only be displayed if the search feature is turned on!

<li><a href="/search/">Search</a></li>

Display a link to the search, if the search is turned on.

[/]

End the condition! Everything from here on is display as usual, not just when the search is turned on.

[l:extrapages]

Start the extrapage loop. Everything from here on is repeated for each extra page you have created

<li><a href="[v:l.link]">[v:l.title]</a></li>

The HTML code that generates a link to the extra page, it will get repeated once for each extra page.
This also contains two loop variables. "[v:l.link]" will get replaced with the link to the extra page, and "[v:l.title]" with the title.

[/]

End of loop. Code from here on will no longer get repeated.

[c:!hidefromhost]

A negated condition. If the "hide from host" setting is turned off in the webcomic settings, display the following code:

<li><a href="[v:addsubscriptionlink]">Subscribe</a></li>

"[v:addsubscriptionlink]" will get replaced with the subscription link. Although this will usually stay the same for your webcomic, it differs from webcomic to webcomic, and using a variable allows layout code to be re-used on different webcomics. This can be useful if you want to later use the layout on a different comicfury comic.

[/]
</ul>

end the negated condition to display stuff regardless of webcomic settings again, and then some closing HTML code.


Advanced conditions:
You think you got the hang of this template stuff? But you're an advanced user, a big strong man or woman? Well maybe you are ready to tackle comparative conditions!

This is something most users probably won't need, but is incredibly useful and powerful if used right. If you feel inadequate and weak, you can skip this section.

So you know about conditions
[c:comments]comments exist[/]

negated conditions
[c:!comments]comments do not exist![/]


but what if you wanted to check if there is 3 comments on a particular comic? How are your conditions going to help you now? Well, easy!
[c:comments=3]there is exactly 3 comments, so there[/]

Comparative conditions look something like this:
First, the condition opening:
[c:

then, the name of the variable we are checking:
comments

then, an operator to do a comparison, in this case an equals-sign to check if the variable "comments" is equal to 3, i.e. has the content "3":
=

and finally the thing we are comparing against, the actual 3, followed by the condition closing
3

]


Easy right? You can compare variables to anything, though! Not just numbers. For example:
[l:comments]
	[c:l.username=Kyo]The user leaving this comment is a git[/]
[/]

In this case, within our comments loop, we're checking if the username of the person commenting is Kyo:
[c:l.username=Kyo]

Or, to put it in robotic terms, we are checking if the content of "l.username" is "Kyo". And if it is, we're calling that user a git.

Okay, but that's still not all! There are other operators, for example:
[c:l.username!=Kyo]The user leaving this comment is probably not a git at all[/]

if we use "!=" instead of "=", we are checking if a variable does not match something. In this example, the text "The user leaving this comment is probably not a git at all" will only appear, if the person leaving the comment is not named "Kyo". So basically the opposite of before.

And that's still not all!
Okay, so much about usernames, but back to numbers. Earlier we were checking if there are 3 comments:
[c:comments=3]there is exactly 3 comments, so there[/]

But what if we want to check if there's more than 3 comments? Easy!
[c:comments>3]There's more than 3 comments[/]

Yes, that works exactly the way it looks like. The opposite works too:
[c:comments<3]There's less than 3 comments[/]

So you can check for amounts as well! This can be useful, if, for example you want to hide the comments by default if there's more than 10 of them.

Is that all? Not quite!
Now we can compare variables to numbers, text, but what if we want to compare them to another variable? easy!
[c:comicwidth=v:comicheight]comic width and height are the same[/]
[c:comicwidth>v:comicheight]comic width is bigger than height[/]

It's as easy as it looks. If you stick a "v:" before the second part of the comparison, it will compare two variables. In this case the variables comicwidth and comicheight. Easy, right?


Advanced Loops:
What about loops? Are there any neat tricks for loops? Yes, there is one!
[l:comments]
	[v:l.comment]<br />
[/]

This is the (very simplified) code to show all comments for your comic, oldest first, newest last. But what if you wanted to show the newest comments first? Easy!
[l:@comments]
	[v:l.comment]<br />
[/]

Done! There really isn't much to explain here. If you put an "@" after the "[l:" (or in other words, before the loop name), it will do the loop in reverse order.


Advanced variables:
What?! Variables too? It's a little code that gets replaced with something depending on the page, how advanced can it get?
Well, there are some special variables. A programmer would call them "arrays", but I don't want to smother you in terminology.

Okay, so this is a normal variable:
[v:comictitle]


It'll get replaced with the comic strip title. Simple enough.

Loop variables
Then we have loop variables, which I've already explained to you as well. Just to reiterate if you didn't completely understand.
[l:comments]
 [v:l.comment]<br />
[/]

[v:l.comment] will get replaced with a comment left on the page, and will be repeated as many times as there are comments (in addition with the "<br />", which is HTML for a newline).

So e.g. if there are 3 comments on the page, The final HTML that is displayed might look something like this:
Wow! Great page!<br />

This page sucks!!!<br />

Wait I take it back, it's great!<br />


GET variables
Disclaimer: This is very advanced, and most of you will never need this! Don't let yourself be confused by the explanations below. This section is totally safe to skip!

a GET variable is a variable that's filled with data in the comic URL. A normal URL might look like this:
http://beststory.thecomicseries.com/

But sometimes you see URLs that look like this:
http://beststory.thecomicseries.com/?variable=1&anothervariable=hello&3rdvar=asd

That would be a URL that has some GET variables in it. The variables, and their values would be:
variable : 1
anothervariable : hello
3rdvar : asd


Basically if you append a question mark to a URL (only if there isn't already one in it!), you can add variables to it by appending "something=value" after the question mark. If there already is a question mark and some variables on the page, or you just want to append more than one variable, you can use an &-sign to separate them. This is all a bit complicated but just play around with it a bit. Add a question mark, and then variable assignments, separated by the &-sign.

Now you can access these variables like this:
How are you doing, [v:get.name]?<br />


If the url accessing your webcomic would be e.g.
http://yourwebcomic.thecomicseries.com/?name=Frank

Then that would result in the following HTML code:
How are you doing, Frank?<br />


But if the url was e.g.
http://yourwebcomic.thecomicseries.com/?name=James

Then your HTML code would say:
How are you doing, James?<br />


You get it? The content of the variable changes depending on the url! You can use this with forms, for example.
<form method="get">
What is your name? <input type="text" name="name" /><br />
<input type="submit" />
</form>


Would produce a form that the user could submit to enter their name, resulting in a URL with get variables.

This is also especially useful with conditions, e.g. you can do this:

[c:get.secretpassword=mynameiskyo]You cracked the code![/]


Would only show the text "You cracked the code!" if someone had the right password in the URL.


What about conditions within conditions?:
You may ask, what if I want to only display something if it matches two conditions? Like, say I want to display the comments only if the comic has the commenting feature enabled, and the comic has comments on it. How do I do that?

It's as easy as it seems
[c:allowcomments]
	[c:comments]
		Put comments here!
	[/]
[/]


So what about the closing tags? They're all the same, so a closing tag will always close the element which was opened last, first. In this example, the comments condition is closed first, then the allowcomments condition.


Why are the closing tags all the same?:You may wonder why it's done like this, and why the names don't appear in the closing tags, like they do in html. This is done to protect you from making mistakes. Let's imagine a template engine that has the names in the closing tags as well. It would look something like this:
[c:allowcomments]
	[c:comments]
		Put comments here!
	[/c:comments]
[/c:allowcomments]


That's all well and nice, but not only is it more typework, it also allows for nonsense constructs like this:
[c:allowcomments]
	[c:comments]
		Put comments here!
	[/c:allowcomments]
[/c:comments]

How can I close a condition that is only opened if comments are allowed, if they're not? This code doesn't make any sense! That kind of code is impossible with Dragonslayer, and the reason we do it like this.


What if I forget a closing tag?:
Simply put, the template engine adds it for you. However, the template engine doesn't know where you actually wanted to close the condition or loop you wanted to close, so it will add it at the very end of the page. More often than not, this is not what you want. So make sure your closing tags match up! If you remove an opening tag, always make sure to remove the right closing tag as well. And if you add an opening tag, don't forget to close it!

So which element will receive the added tag at the end of the page, in case of a forgotten one? Good question. This is somewhat hard to answer. Imagine something like this:
[c:allowcomments]
	Comments are Allowed
	[c:comments]
		And there are some comments on this page!
[/]

Technically, the author of this code forgot to close the "comments" condition, but the remember that the innermost conditions and loops always get closed first. This means the comments condition would steal the closing tag from the allowcomments condition, thus allowcomments would be left unclosed, and the rest of the page would only be displayed if comments are allowed. This all sounds kind of complicated, but it's not really that important as long as you always remember your closing tags.
_______________________
hello