Layout on the web
When targeting the web, Salam's layout DSL compiles to HTML, CSS, and (when needed) JavaScript. This lesson focuses on web-specific output and runtime behavior: building, browser/DOM interactivity, and serving pages.
Building web output
salam page build page.salam produces page.html and page.css, plus page.js when scripts/events are present. Use --inline for a single self-contained HTML file. With multiple inputs (e.g. salam page build home.salam about.salam) each page gets its own HTML and they can share a common style.css. With no file name, the tool typically builds main.salam if present, otherwise layout pages in the folder.
Styles are extracted into generated classes/rules in the stylesheet so HTML stays compact and reusable.
Browser events and DOM
Event attributes such as click, submit, input, change, etc. become interactive behavior in the browser. Salam handlers attached to events are compiled into the page script for web builds. In handlers you can work with the DOM (e.g. dom.ById/dom.Query) as covered in the events lessons.
See Mouse events through State, the DOM and timers for the full browser event/DOM model.
Parameterized layouts and runtime rendering
Parameterized layouts can render HTML at runtime with request-specific data, which is useful for Salam web servers. Inserted parameter text is escaped for safety. For sensitive/structured values (URLs, colors, lengths, etc.) validate/parse them appropriately before use.
page Card(name: str, score: int):
title = "Card " + name
heading: size = 2 content = name end
if score >= 50:
paragraph: content = "pass" end
else:
paragraph: content = "fail" end
end
end
func main:
println Card("Ali", 70)
endimport net.http
import net.router
page Greeting(name: str):
title = "Hello " + name
heading: size = 1 content = "Hello, " + name end
paragraph: content = "This page was rendered on the server." end
end
func home(ctx: i64):
mut name := http.Query(ctx, "name")
if name == "":
name = "guest"
end
http.Html(ctx, Greeting(name))
end
func main:
mut r := router.NewRouter()
router.Get(r, "/", home)
mut s := http.NewServer(8080)
http.Use(s, r)
http.Run(s)
endServing and web projects
Built files can be hosted on any static web server, or served locally/production with salam serve. Salam programs can also return rendered HTML using networking packages such as net.http and net.router.
component Badge(text: str):
span: content = text background = #fde68a end
end
page Inbox(user: str, subjects: Vector<str>):
title = "Inbox of " + user
heading: size = 1 content = "Hello, " + user end
if subjects.IsEmpty():
paragraph: content = "No new messages" end
else:
paragraph: content = "Unread: " + subjects.Len() end
list:
each i, s in subjects:
item: content = (i + 1) + ". " + s end
end
end
end
end
func main:
mut subjects := Vector {} as Vector<str>
defer subjects.Free()
subjects.Push("Meeting at 10")
subjects.Push("<b>FREE</b> prize & more")
println Inbox("Sara", subjects)
println Badge("new")
endNotes
- Browser features (forms behavior, media APIs, scrolling, clipboard, storage, etc.) are web-environment specific.
- Interactive pages rely on the page script running in the browser.
- For browserless native windows, see Layout in native apps.