Skip to content

Commit 27d179c

Browse files
authored
Adding Slim (#4)
Added Slim template support: https://slim-lang.com/ - Added a new directive "@slim" to parse Slim templates into Go code - Added "@haml" for existing Haml templates Deprecating "@Goht" template directive; templates should use "@haml" instead. * Slim templating added
1 parent 89b2e77 commit 27d179c

File tree

193 files changed

+7802
-1361
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

193 files changed

+7802
-1361
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,3 +149,4 @@ $RECYCLE.BIN/
149149
*.lnk
150150

151151
# End of https://www.toptal.com/developers/gitignore/api/goland+all,windows,macos
152+
/scratch/

.version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
VERSION=v0.5.0
1+
VERSION=v0.6.0

README.md

Lines changed: 128 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
# GoHT (Go Haml Templates)
2-
A [Haml](http://haml.info/) template engine and file generation tool for Go.
1+
# GoHT (Go HTML Templates)
2+
A [Haml](http://haml.info/) and [Slim](https://slim-template.github.io/) template engine and file generation tool for Go.
33

4-
![GoHT](docs/goht_header.png)
4+
![GoHT](docs/goht_header_html.png)
55

66
[![Go Report Card](https://goreportcard.com/badge/github.com/stackus/goht)](https://goreportcard.com/report/github.com/stackus/goht)
77
[![](https://godoc.org/github.com/stackus/goht?status.svg)](https://pkg.go.dev/github.com/stackus/goht)
@@ -11,6 +11,8 @@ A [Haml](http://haml.info/) template engine and file generation tool for Go.
1111
- [Quick Start](#quick-start)
1212
- [Supported Haml Syntax & Features](#supported-haml-syntax--features)
1313
- [Unsupported Haml Features](#unsupported-haml-features)
14+
- [Supported Slim Syntax & Features](#supported-slim-syntax--features)
15+
- [Unsupported Slim Features](#unsupported-slim-features)
1416
- [GoHT CLI](#goht-cli)
1517
- [IDE Support](#ide-support)
1618
- [LSP](#lsp)
@@ -19,8 +21,8 @@ A [Haml](http://haml.info/) template engine and file generation tool for Go.
1921
- [Using GoHT with HTTP handlers](#using-goht-with-http-handlers)
2022
- [A big nod to Templ](#a-big-nod-to-templ)
2123
- [The GoHT template](#the-goht-template)
22-
- [Haml Syntax](#haml-syntax)
23-
- [GoHT and Haml differences](#goht-and-haml-differences)
24+
- [GoHT Syntax](#goht-syntax)
25+
- [GoHT template differences](#goht-template-differences)
2426
- [Go package and imports](#go-package-and-imports)
2527
- [Multiple templates per file](#multiple-templates-per-file)
2628
- [Doctypes](#doctypes)
@@ -29,6 +31,7 @@ A [Haml](http://haml.info/) template engine and file generation tool for Go.
2931
- [Attributes](#attributes)
3032
- [Classes](#classes)
3133
- [Object References](#object-references)
34+
- [Inlined Tags](#inlined-tags)
3235
- [Filters](#filters)
3336
- [Template nesting](#template-nesting)
3437
- [Contributing](#contributing)
@@ -42,13 +45,13 @@ A [Haml](http://haml.info/) template engine and file generation tool for Go.
4245
- Easy nesting of templates
4346

4447
## Quick Start
45-
First create a GoHT file, a file which mixes Go and Haml with a `.goht` extension:
48+
First create a GoHT file, a file which mixes Go and Haml (and Slim!) with a `.goht` extension:
4649
```haml
4750
package main
4851
4952
var siteTitle = "GoHT"
5053
51-
@goht SiteLayout(pageTitle string) {
54+
@haml SiteLayout(pageTitle string) {
5255
!!!
5356
%html{lang:"en"}
5457
%head
@@ -59,9 +62,9 @@ var siteTitle = "GoHT"
5962
= @children
6063
}
6164
62-
@goht HomePage() {
65+
@slim HomePage() {
6366
= @render SiteLayout("Home Page")
64-
%p This is the home page for GoHT.
67+
p This is the home page for GoHT.
6568
}
6669
```
6770

@@ -110,19 +113,39 @@ Which would serve the following HTML:
110113
- [x] Doctypes (`!!!`)
111114
- [x] Tags (`%tag`)
112115
- [x] Attributes (`{name: value}`) [(more info)](#attributes)
113-
- [x] Classes and IDs (`.class` `#id`) [(more info)](#classes)
116+
- [x] Classes and IDs (`.class`, `#id`) [(more info)](#classes)
114117
- [x] Object References (`[obj]`) [(more info)](#object-references)
115118
- [x] Unescaped Text (`!` `!=`)
116119
- [x] Comments (`/` `-#`)
120+
- [x] Self-closing Tags (`%tag/`)]
117121
- [x] Inline Interpolation (`#{value}`)
118122
- [x] Inlining Code (`- code`)
119123
- [x] Rendering Code (`= code`)
120124
- [x] Filters (`:plain`, ...) [(more info)](#filters)
121-
- [x] Whitespace Removal (`%tag>` `%tag<`) [(more info)](#whitespace-removal)
125+
- [x] Whitespace Removal (`%tag>`, `%tag<`) [(more info)](#whitespace-removal)
122126

123127
### Unsupported Haml Features
124128
- [ ] Probably something I've missed, please raise an issue if you find something missing.
125129

130+
## Supported Slim Syntax & Features
131+
- [x] Doctypes (`doctype`)
132+
- [x] Tags (`tag`)
133+
- [x] Attributes (`{name: value}`) [(more info)](#attributes)
134+
- [x] Classes and IDs (`.class`, `#id`) [(more info)](#classes)
135+
- [x] Inline Tags (`tag: othertag`)
136+
- [x] Unescaped Text (`|`)
137+
- [x] Comments (`/`, `/!`)
138+
- [x] Self-closing Tags (`tag/`)
139+
- [x] Inline Interpolation (`#{value}`)
140+
- [x] Inlining Code (`- code`)
141+
- [x] Rendering Code (`= code`, `== code`)
142+
- [x] Filters (`:plain`, ...) [(more info)](#filters)
143+
- [x] Long Statement wrapping (`\`), (`,`)]
144+
145+
### Unsupported Slim Features
146+
147+
- [ ] Whitespace Addition (`tag<` `tag>`)
148+
126149
## GoHT CLI
127150

128151
### Installation
@@ -149,6 +172,9 @@ goht generate --force
149172
See more options with `goht help generate` or `goht generate -h`.
150173

151174
## IDE Support
175+
176+
> Note: The IDE extensions are being worked on to add the new Slim syntax highlighting.
177+
152178
![vscode_ide_example.png](docs/vscode_ide_example.png)
153179
- VSCode [Extension](https://marketplace.visualstudio.com/items?itemName=stackus.goht-vscode) and code [repository](https://github.com/stackus/goht-vscode)
154180
- JetBrains (GoLand and others) [Plugin](https://plugins.jetbrains.com/plugin/23783-goht) and code [repository](https://github.com/stackus/goht-jetbrains)
@@ -217,7 +243,7 @@ The second parameter passed into the `Render` method can be anything that implem
217243
such as a file or a buffer, or the `http.ResponseWriter` that you get from an HTTP handler.
218244

219245
### Using GoHT with HTTP handlers
220-
Using the GoHT templates is made very easy.
246+
Using the GoHT templates is made straightforward.
221247
```go
222248
package main
223249

@@ -245,36 +271,48 @@ There are a number of examples showing various Haml and GoHT features in the [ex
245271
### A big nod to Templ
246272
The way that you use GoHT is very similar to how you would use [Templ](https://templ.guide). This is no accident as I am a big fan of the work being done with that engine.
247273

248-
After getting the Haml properly lexed, and parsed, I did not want to reinvent the wheel and come up with a whole new rendering API.
274+
After getting the Haml properly lexed and parsed, I did not want to reinvent the wheel and come up with a whole new rendering API.
249275
The API that Templ presents is nice and easy to use, so I decided to replicate it in GoHT.
250276

251277
## The GoHT template
252278
GoHT templates are files with the extension `.goht` that when processed will produce a matching Go file with the extension `.goht.go`.
253279

254-
In these files you are free to write any Go code that you wish, and then drop into Haml mode using the `@goht` directive.
280+
In these files you are free to write any Go code that you wish, and then drop into Haml mode using the `@haml` directive.
281+
282+
> Note: The original `@goht` directive is still supported for HAML templating, but it is deprecated and will be removed in a future version.
255283
256284
The following starts the creation of a SiteLayout template:
257285
```haml
258-
@goht SiteLayout() {
286+
@haml SiteLayout() {
287+
288+
or
289+
290+
@slim SiteLayout() {
259291
```
260292

261293
GoHT templates are closed like Go functions, with a closing brace `}`. So a complete but empty example is this:
262294
```haml
263-
@goht SiteLayout() {
295+
@haml SiteLayout() {
296+
}
297+
298+
or
299+
300+
@slim SiteLayout() {
264301
}
265302
```
266-
Inside the template you can use any Haml features, such as tags, attributes, classes,
303+
Inside the templates you can use any Haml or Slim features, such as tags, attributes, classes,
267304
IDs, text, comments, interpolation, code inlining, code rendering, and filters.
268305

269-
## Haml Syntax
306+
## GoHT Syntax
270307
The Haml syntax is documented at the [Haml](http://haml.info/) website.
271308
Please see that site or the [Haml Reference](https://haml.info/docs/yardoc/file.REFERENCE.html) for more information.
309+
The Slim syntax is documented at the [Slim](https://slim-lang.com/) website.
272310

273-
GoHT has implemented the Haml syntax very closely.
274-
So, if you are already familiar with Haml then you should be able to jump right in.
311+
GoHT has implemented nearly all Haml and Slim syntax.
312+
So, if you are already familiar with Haml or Slim then you should be able to jump right in.
275313
There are some minor differences that I will document in the next section.
276314

277-
### GoHT and Haml differences
315+
### GoHT template differences
278316

279317
Important differences are:
280318
- [Go package and imports](#go-package-and-imports): You can declare a package and imports for your templates.
@@ -283,9 +321,9 @@ Important differences are:
283321
- [Indents](#indents): GoHT follows the rules of GoFMT for indents.
284322
- [Inlined code](#inlined-code): You won't be using Ruby here, you'll be using Go.
285323
- [Rendering code](#rendering-code): The catch is what is being outputted will need to be a string in all cases.
286-
- [Attributes](#attributes): Only the Ruby 1.9 style of attributes is supported.
324+
- [Attributes](#attributes): Only the Ruby 1.9 (`{...}`) style of attributes is supported.
287325
- [Classes](#classes): Multiple sources of classes are supported.
288-
- [Object References](#object-references): Limited support for object references.
326+
- [Object References](#object-references): Haml Only: Limited support for object references.
289327
- [Filters](#filters): Partial list of supported filters.
290328
- [Template nesting](#template-nesting): Templates can be nested, and content can be passed into them.
291329

@@ -295,19 +333,21 @@ You can provide a package name at the top of your GoHT template file. If you do
295333
You may also import any packages that you need to use in your template. The imports you use and the ones brought in by GoHT will be combined and deduplicated.
296334

297335
### Multiple templates per file
298-
You can declare as many templates in a file as you wish. Each template must have a unique name in the module they will be output into.
336+
You can declare as many templates in a file as you wish.
337+
Each template must have a unique name in the module they will be output into.
338+
You may also mix Haml and Slim templates in the same file.
299339
```haml
300-
@goht SiteLayout() {
340+
@slim SiteLayout() {
301341
}
302342
303-
@goht HomePage() {
343+
@haml HomePage() {
304344
}
305345
```
306346

307347
The templates are converted into Go functions, so they must be valid Go function names.
308348
This also means that you can declare them with parameters and can use those parameters in the template.
309349
```haml
310-
@goht SiteLayout(title string) {
350+
@haml SiteLayout(title string) {
311351
!!!
312352
%html{lang:"en"}
313353
%head
@@ -316,23 +356,38 @@ This also means that you can declare them with parameters and can use those para
316356
-# ... the rest of the template
317357
}
318358
```
359+
The same applies to Slim templates:
360+
```slim
361+
@slim SiteLayout(title string) {
362+
doctype html
363+
html(lang="en")
364+
head
365+
title= title
366+
body
367+
/ ... the rest of the template
368+
}
369+
```
319370

320371
### Doctypes
321372
Only the HTML 5 doctype is supported, and is written using `!!!`.
322373
```haml
323-
@goht SiteLayout() {
374+
@haml SiteLayout() {
324375
!!!
325376
}
377+
378+
@slim SiteLayout() {
379+
doctype
380+
}
326381
```
327382

328-
> Note about indenting. GoHT follows the similar rules as Haml for indenting. The first line of the template must be at the same level as the `@goht` directive. After that, you MUST use tabs to indent the content of the template.
383+
> Note about indenting. GoHT follows the same rules as Haml for indenting. The first line of the template must be at the same level as the `@haml` or `@slim` directive. After that, you MUST use tabs to indent the content of the template.
329384
330385
### Indents
331386
GoHT follows the rules of GoFMT for indents, meaning that you should use tabs for indentation.
332387

333-
You must also indent the content of the template, and the closing brace should be at the same level as the `@goht` directive.
388+
You must also indent the content of the template, and the closing brace should be at the same level as the `@haml` directive.
334389
```haml
335-
@goht SiteLayout() {
390+
@haml SiteLayout() {
336391
%html
337392
%head
338393
%title GoHT
@@ -341,6 +396,18 @@ You must also indent the content of the template, and the closing brace should b
341396
}
342397
```
343398

399+
Slim:
400+
```slim
401+
@slim SiteLayout() {
402+
doctype
403+
html
404+
head
405+
title GoHT
406+
body
407+
h1 GoHT
408+
}
409+
```
410+
344411
> Note: Two spaces are being used in this README for display only. Keep that in mind if you copy and paste the examples from this document.
345412
346413
### Inlined code
@@ -353,20 +420,26 @@ So instead of this with Ruby:
353420
- if user
354421
%strong The user exists
355422
```
356-
You would write this with Go:
423+
You would write this with Go (Go needs the `!= nil` check):
357424
```haml
358425
- if user != nil
359426
%strong The user exists
360427
```
361428
There is minimal processing performed on the Go code you put into the templates, so it needs to be valid Go code sans braces.
429+
362430
> You may continue to use the braces if you wish. Existing code with braces will continue to work without modifications.
363431
364432
### Rendering code
365-
Like in Haml, you can output variables and the results of expressions. The `=` script syntax and text interpolation `#{}` are supported.
433+
Like in Haml, you can output variables and the results of expressions. The `=` script syntax and text interpolation `#{}` are supported for both template languages.
366434
```haml
367435
%strong= user.Name
368436
%strong The user's name is #{user.Name}
369437
```
438+
Slim:
439+
```slim
440+
strong= user.Name
441+
strong The user's name is #{user.Name}
442+
```
370443

371444
The catch is what is being outputted will need to be a string in all cases.
372445
So instead of writing this to output an integer value:
@@ -388,7 +461,8 @@ The interpolation also supports the shortcut:
388461
When formatting a value into a string `fmt.Sprintf` is used under the hood, so you can use any of the formatting options that it supports.
389462

390463
### Attributes
391-
Only the Ruby 1.9 style of attributes is supported.
464+
**Only the Ruby 1.9 style of attributes is supported.**
465+
392466
This syntax is closest to the Go syntax, and is the most readable.
393467
Between the attribute name, operator, and value you can include or leave out as much whitespace as you like.
394468
```haml
@@ -472,15 +546,29 @@ type ObjectClasser interface {
472546
The result of these methods will be used
473547
to populate the id and class attributes in a similar way to how Haml would apply the Ruby object references.
474548

549+
### Inlined Tags
550+
**Slim Only**
551+
552+
GoHT supports inlining tags to keep templates as compact as possible.
553+
554+
```slim
555+
ul
556+
li: a.First Fist Item
557+
li: a.Second Second Item
558+
li: a.Third Third Item
559+
```
560+
475561
### Filters
476562
Only the following Haml filters are supported:
477-
- `:plain`
478-
- `:escaped`
479-
- `:preserve`
563+
- `:plain` (Haml Only)
564+
- `:escaped` (Haml Only)
565+
- `:preserve` (Haml Only)
480566
- `:javascript`
481567
- `:css`
482568

483569
### Whitespace Removal
570+
**Haml Only**
571+
484572
GoHT supports the removal of whitespace between tags. This is done by adding a `>` or `<` to the end of the tag.
485573

486574
- `>` will remove all whitespace between the tag and its parent or siblings.
@@ -491,20 +579,20 @@ Both can be used together to remove whitespace both inside and outside a tag; th
491579
### Template nesting
492580
The biggest departure from Haml is how templates can be combined. When working Haml you could use `= render :partial_name` or `= haml :partial_name` to render a partial. The `render` and `haml` functions are not available in GoHT, instead you can use the `@render` directive.
493581
```haml
494-
@goht HomePage() {
582+
@haml HomePage() {
495583
= @render SiteLayout()
496584
}
497585
```
498586
The above would render the `SiteLayout` template, and you would call it with any parameters that it needs. You can also call it and provide it with a block of content to render where it chooses.
499587
```haml
500-
@goht HomePage() {
588+
@haml HomePage() {
501589
= @render SiteLayout()
502590
%p This is the home page for GoHT.
503591
}
504592
```
505593
Any content nested under the `@render` directive will be passed into the template that it can render where it wants using the `@children` directive.
506594
```haml
507-
@goht SiteLayout() {
595+
@haml SiteLayout() {
508596
!!!
509597
%html{lang:"en"}
510598
%head

0 commit comments

Comments
 (0)