What Is Kit?
A *.kit file is just HTML with special comments.
Kit adds two things to HTML: imports and variables. CodeKit compiles Kit files into HTML, so Kit is ideal for static sites.
Imports
You may import any file, of any type, into a Kit file. The syntax is just like CSS:
<!-- @import "someFile.kit" --> <!-- @import "file.html" -->
The syntax is flexible. You may use @include instead of @import if you prefer. Quotes and spaces are totally optional (except for the space after the import statement). All of these are valid:
<!-- @include someFile.kit --> <!-- @import '../../someFileAtRelativePath.html' --> <!--@include no_spaces_at_beginning_or_end.txt-->
When compiling, CodeKit replaces this special comment with the entire text of the file you're importing. If the import is also a Kit file, CodeKit will compile it recursively. This way, you can chain multiple files together.
File Extension
The extension is optional. If you exclude it, CodeKit will automatically add .kit when it looks for the file. An extension IS required to import other file types, such as HTML.
Root-Relative Imports
If the import path begins with a slash, CodeKit will look for the file relative to the project's root folder. Otherwise, the path is evaluated relative to the Kit file that contains the @import statement.
<!-- Resolved from the project's root folder: --> <!-- @import '/someSubfolder/someFile' -->
Multiple Imports
You may import more than one file at a time by using a comma-separated list:
<!-- @import someFile, otherFile.html, ../thirdFile.kit -->
The "Partial" Convention
Kit adopts the "partial" convention from Sass. If a file is ONLY meant to be imported into others, add a leading underscore to the filename. This helps you recognize "import-only" files in the Finder. You are NOT required to include the underscore in @import statements.
Example: suppose a file named master.kit contains this special comment: <!-- @include someFile -->. CodeKit follows this sequence to resolve the import:
- Look for someFile.kit in the same folder as master.kit
- If that fails, look for _someFile.kit in the same folder
- If that fails, look for someFile.kit in all CodeKit Framework folders
- If that fails, look for _someFile.kit in all CodeKit Framework folders
Base64 Imports
If you write @import-base64, CodeKit will base64-encode the content of the file you're targeting. Here's an example of how to use it:
<img src="data:image/png;base64, <!--@import-base64 'myImage.png'-->">
Compiling Imports
If you want CodeKit to compile a file before importing it, write @compile:
<!-- @compile 'someFile.pug' -->
CodeKit will compile "someFile.pug", then replace the special comment with the compiled output. This works with any type of file, including custom types you may have defined in CodeKit.
Details
"someFile.pug" is compiled and its output is written to disk. This allows any Hooks that you may have defined to run on the output just as they normally would. Afterwards, CodeKit will delete the output file from disk.
Practical Examples
An excellent time to use this feature is when you're building HTML emails and must in-line CSS because you cannot link to an external stylesheet:
<style> <!-- @compile '../stylesheet.scss' --> </style>
Limitations
You may not pass a comma-separated list to a @compile statement. A file extension is required. If it's missing, CodeKit assumes *.kit
Use Judiciously
Each @compile statement that you add increases the overall time it takes to compile the Kit file. If you use this statement to compile a stylesheet file (Sass, Less, or Stylus) CodeKit won't be able to inject changes into the Browser Preview. Instead, the whole page will be reloaded.
There are still good reasons to use external CSS and JS files. Blindly bundling everything into one massive HTML file may slow down page-loads or prevent caching, for instance.
Variables
Declaring a variable in Kit is simple:
<!-- $width = 40px --> <!-- $myVar = We finish each other's sandwiches. -->
At any point after the declaration, we can use these variables like this:
<body> <p> <!-- $myVar --> </p> <div style="width: <!--$width-->;"> Stuff </div> </body>
And the final output becomes:
<body> <p> We finish each other's sandwiches. </p> <div style="width: 40px;"> Stuff </div> </body>
Flexible Syntax
You can use either $ or @ to denote a variable name. You can use equals signs, colons or just a space to assign a value. All of the following are valid variable declarations:
<!--$myVar:This text is amazing--> <!--@var2=Some other incredible text--> <!-- @width = 40px --> <!-- $manifesto Who needs colons and equals signs? -->
All Variables Are Strings
All Kit variables are simple strings. This means you can NOT do things like add variables together, etc. (If you need that capability, it's time to step up to PHP, Jade, Haml or Slim.)
Also, everything after the variable name is considered part of the variable value. If you wrap your string in quotation marks, the quotation marks will appear when you use the variable. Leading and trailing whitespace in the variable value, however, is ignored.
One Variable Per Comment
You may only declare or use a single variable per special comment. Attempting to declare or use multiple variables in a single comment will result in undefined behavior.
Nil Variables
You may set a variable's value to "nothing" using the same flexible syntax and the nil keyword:
<!-- $myVar = nil --> <!--$myVar:nil-->
A variable that is set to nil becomes essentially a "no-op". Nothing will be substituted for it in the HTML output.
Optionals
Kit adopts the "optional" syntax from Swift. Suppose you're building a navigation menu. A partial named _nav.kit contains this code:
<dl> <dd class='<!-- $myVar? -->'> Page 1 </dd> <dd class='<!-- $otherVar? -->'> Page 2 </dd> </dl>
The ? after the variable name means, "If this variable has a value, put it here. Otherwise, if the variable is not defined, just skip it."
You can easily use this to add "active" states to nav menu items. Here's what page1.kit would look like:
<body> ... <!-- $myVar = nav-menu-active --> <!-- @import _nav.kit --> ... </body>
The compiled HTML for page 1 would look like this:
<body> ... <dl> <dd class='nav-menu-active'> Page 1 </dd> <dd class=''> Page 2 </dd> </dl> ... </body>
And then page2.kit would contain:
<body> ... <!-- $otherVar = 'nav-menu-active' --> <!-- @import _nav.kit --> ... </body>
And the compiled output for Page 2 would look like:
<body> ... <dl> <dd class=''> Page 1 </dd> <dd class='nav-menu-active'> Page 2 </dd> </dl> ... </body>
Now just write some CSS that targets the nav-menu-active class and you're done!
Note: If you attempt to use an undefined variable without the optional operator, you'll receive an error.
Variable Scope
A variable can be used at any point after it is declared. This extends into imported files. If you declare a variable in master.kit, then import beta.kit, the variable from "master" will be available in "beta". By contrast, any variables declared in "beta" will NOT be available in "master".
Getting Started
Simply take any regular HTML file and rename it from *.html to *.kit.
You can also use Kit for more than just HTML. In fact, your output file can have any extension you'd like. Kit is really just a simple text-substitution language, so the input and output languages don't matter. See Setting Output Paths for details.
Note: to change the extension of an HTML file in the Finder, you must right-click the file, choose "Get Info" and then change the extension in the window that pops up. If you try to do so in the Finder window itself, Finder will actually rename the file to *.kit.html.
Common Questions
Why Does Kit Exist?
Lots of people asked me to add "imports for HTML files". They don't want to use PHP just to do simple things like including a navigation bar on every page. That's the very specific problem Kit is designed to solve.
Why Didn't You Just Use The HTML Extension?
Once you add these special comments to a file, that file is not really HTML any more. You could open it in a browser and it would display, but you'd be missing all the included content and anything that relied on variables. As such, using a different file extension makes it clear that the contents of the file is more than just regular HTML.
I Want Loops! And Conditionals!
If you need more complex patterns, it's time to step up to a more robust language. Kit is just simple string substitution; its scope is limited by design to keep it approachable and easy. Plus: if's and loops inside of HTML comments quickly get really ugly.
You're Locking Us Into CodeKit!
Negative. The Kit compiler is open source and any developer is welcome to add Kit support to any product. I want to be crystal clear: The Kit language is NOT an attempt to tie people to CodeKit. It's simply the best way I know to fulfill a really common feature request. I want folks to use my app because it's the best tool for the job, not because they're forced to use it.