diff --git a/src/formatters.nim b/src/formatters.nim
index bb8698c..28bfa1c 100644
--- a/src/formatters.nim
+++ b/src/formatters.nim
@@ -60,11 +60,11 @@ proc replaceUrls*(body: string; prefs: Prefs; absolute=""): string =
result = result.replace("/c/", "/")
if prefs.replaceTwitter.len > 0 and ("twitter.com" in body or tco in body):
- result = result.replace(tco, https & prefs.replaceTwitter & "/t.co")
+ result = result.replace(tco, &"{https}{prefs.replaceTwitter}/t.co")
result = result.replace(cards, prefs.replaceTwitter & "/cards")
result = result.replace(twRegex, prefs.replaceTwitter)
result = result.replacef(twLinkRegex, a(
- prefs.replaceTwitter & "$2", href = https & prefs.replaceTwitter & "$1"))
+ prefs.replaceTwitter & "$2", href = &"{https}{prefs.replaceTwitter}$1"))
if prefs.replaceReddit.len > 0 and ("reddit.com" in result or "redd.it" in result):
result = result.replace(rdShortRegex, prefs.replaceReddit & "/comments/")
@@ -76,7 +76,7 @@ proc replaceUrls*(body: string; prefs: Prefs; absolute=""): string =
result = result.replace(igRegex, prefs.replaceInstagram)
if absolute.len > 0 and "href" in result:
- result = result.replace("href=\"/", "href=\"" & absolute & "/")
+ result = result.replace("href=\"/", &"href=\"{absolute}/")
proc getM3u8Url*(content: string): string =
var matches: array[1, string]
diff --git a/src/query.nim b/src/query.nim
index cf9b0e6..d128f6f 100644
--- a/src/query.nim
+++ b/src/query.nim
@@ -93,11 +93,11 @@ proc genQueryUrl*(query: Query): string =
if query.text.len > 0:
params.add "q=" & encodeUrl(query.text)
for f in query.filters:
- params.add "f-" & f & "=on"
+ params.add &"f-{f}=on"
for e in query.excludes:
- params.add "e-" & e & "=on"
+ params.add &"e-{e}=on"
for i in query.includes.filterIt(it != "nativeretweets"):
- params.add "i-" & i & "=on"
+ params.add &"i-{i}=on"
if query.since.len > 0:
params.add "since=" & query.since
diff --git a/src/routes/embed.nim b/src/routes/embed.nim
index 1a93d40..8690357 100644
--- a/src/routes/embed.nim
+++ b/src/routes/embed.nim
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: AGPL-3.0-only
-import asyncdispatch, strutils, options
+import asyncdispatch, strutils, strformat, options
import jester, karax/vdom
import ".."/[types, api]
import ../views/[embed, tweet, general]
@@ -31,6 +31,6 @@ proc createEmbedRouter*(cfg: Config) =
let id = @"id"
if id.len > 0:
- redirect("/i/status/" & id & "/embed")
+ redirect(&"/i/status/{id}/embed")
else:
resp Http404
diff --git a/src/routes/list.nim b/src/routes/list.nim
index d466080..c97b1c1 100644
--- a/src/routes/list.nim
+++ b/src/routes/list.nim
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: AGPL-3.0-only
-import strutils, uri
+import strutils, strformat, uri
import jester
@@ -10,14 +10,17 @@ export getListTimeline, getGraphList
template respList*(list, timeline, title, vnode: typed) =
if list.id.len == 0 or list.name.len == 0:
- resp Http404, showError("List " & @"id" & " not found", cfg)
+ resp Http404, showError(&"""List "{@"id"}" not found""", cfg)
let
html = renderList(vnode, timeline.query, list)
- rss = "/i/lists/$1/rss" % [@"id"]
+ rss = &"""/i/lists/{@"id"}/rss"""
resp renderMain(html, request, cfg, prefs, titleText=title, rss=rss, banner=list.banner)
+proc title*(list: List): string =
+ &"@{list.username}/{list.name}"
+
proc createListRouter*(cfg: Config) =
router list:
get "/@name/lists/@slug/?":
@@ -28,24 +31,22 @@ proc createListRouter*(cfg: Config) =
slug = decodeUrl(@"slug")
list = await getCachedList(@"name", slug)
if list.id.len == 0:
- resp Http404, showError("List \"" & @"slug" & "\" not found", cfg)
- redirect("/i/lists/" & list.id)
+ resp Http404, showError(&"""List "{@"slug"}" not found""", cfg)
+ redirect(&"/i/lists/{list.id}")
get "/i/lists/@id/?":
cond '.' notin @"id"
let
prefs = cookiePrefs()
list = await getCachedList(id=(@"id"))
- title = "@" & list.username & "/" & list.name
timeline = await getListTimeline(list.id, getCursor())
vnode = renderTimelineTweets(timeline, prefs, request.path)
- respList(list, timeline, title, vnode)
+ respList(list, timeline, list.title, vnode)
get "/i/lists/@id/members":
cond '.' notin @"id"
let
prefs = cookiePrefs()
list = await getCachedList(id=(@"id"))
- title = "@" & list.username & "/" & list.name
members = await getGraphListMembers(list, getCursor())
- respList(list, members, title, renderTimelineUsers(members, prefs, request.path))
+ respList(list, members, list.title, renderTimelineUsers(members, prefs, request.path))
diff --git a/src/routes/rss.nim b/src/routes/rss.nim
index 40aa6a7..700c215 100644
--- a/src/routes/rss.nim
+++ b/src/routes/rss.nim
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: AGPL-3.0-only
-import asyncdispatch, strutils, tables, times, hashes, uri
+import asyncdispatch, strutils, strformat, tables, times, hashes, uri
import jester
@@ -42,8 +42,8 @@ proc timelineRss*(req: Request; cfg: Config; query: Query): Future[Rss] {.async.
template respRss*(rss, page) =
if rss.cursor.len == 0:
let info = case page
- of "User": " \"$1\" " % @"name"
- of "List": " $1 " % @"id"
+ of "User": &""" "{@"name"}" """
+ of "List": &""" "{@"id"}" """
else: " "
resp Http404, showError(page & info & "not found", cfg)
@@ -67,7 +67,7 @@ proc createRssRouter*(cfg: Config) =
let
cursor = getCursor()
- key = "search:" & $hash(genQueryUrl(query)) & ":" & cursor
+ key = &"search:{hash(genQueryUrl(query))}:cursor"
var rss = await getCachedRss(key)
if rss.cursor.len > 0:
@@ -86,7 +86,7 @@ proc createRssRouter*(cfg: Config) =
let
cursor = getCursor()
name = @"name"
- key = "twitter:" & name & ":" & cursor
+ key = &"twitter:{name}:{cursor}"
var rss = await getCachedRss(key)
if rss.cursor.len > 0:
@@ -109,7 +109,7 @@ proc createRssRouter*(cfg: Config) =
of "search": initQuery(params(request), name=name)
else: Query(fromUser: @[name])
- var key = @"tab" & ":" & @"name" & ":"
+ var key = &"""{@"tab"}:{@"name"}:"""
if @"tab" == "search":
key &= $hash(genQueryUrl(query)) & ":"
key &= getCursor()
@@ -132,11 +132,11 @@ proc createRssRouter*(cfg: Config) =
cursor = getCursor()
if list.id.len == 0:
- resp Http404, showError("List \"" & @"slug" & "\" not found", cfg)
+ resp Http404, showError(&"""List "{@"slug"}" not found""", cfg)
- let url = "/i/lists/" & list.id & "/rss"
+ let url = &"/i/lists/{list.id}/rss"
if cursor.len > 0:
- redirect(url & "?cursor=" & encodeUrl(cursor, false))
+ redirect(&"{url}?cursor={encodeUrl(cursor, false)}")
else:
redirect(url)
@@ -146,7 +146,7 @@ proc createRssRouter*(cfg: Config) =
cursor = getCursor()
key =
if cursor.len == 0: "lists:" & @"id"
- else: "lists:" & @"id" & ":" & cursor
+ else: &"""lists:{@"id"}:{cursor}"""
var rss = await getCachedRss(key)
if rss.cursor.len > 0:
diff --git a/src/routes/search.nim b/src/routes/search.nim
index 3fc44a9..554f2f6 100644
--- a/src/routes/search.nim
+++ b/src/routes/search.nim
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: AGPL-3.0-only
-import strutils, uri
+import strutils, strformat, uri
import jester
@@ -37,7 +37,7 @@ proc createSearchRouter*(cfg: Config) =
resp Http404, showError("Invalid search", cfg)
get "/hashtag/@hash":
- redirect("/search?q=" & encodeUrl("#" & @"hash"))
+ redirect(&"""/search?q={encodeUrl("#" & @"hash")}""")
get "/opensearch":
let url = getUrlPrefix(cfg) & "/search?q="
diff --git a/src/routes/timeline.nim b/src/routes/timeline.nim
index a0a6e21..9d97c29 100644
--- a/src/routes/timeline.nim
+++ b/src/routes/timeline.nim
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: AGPL-3.0-only
-import asyncdispatch, strutils, sequtils, uri, options, times
+import asyncdispatch, strutils, strformat, sequtils, uri, options, times
import jester, karax/vdom
import router_utils
@@ -102,7 +102,7 @@ proc showTimeline*(request: Request; query: Query; cfg: Config; prefs: Prefs;
template respTimeline*(timeline: typed) =
let t = timeline
if t.len == 0:
- resp Http404, showError("User \"" & @"name" & "\" not found", cfg)
+ resp Http404, showError(&"""User "{@"name"}" not found""", cfg)
resp t
template respUserId*() =
diff --git a/src/views/general.nim b/src/views/general.nim
index b18dae5..f242e66 100644
--- a/src/views/general.nim
+++ b/src/views/general.nim
@@ -81,7 +81,7 @@ proc renderHead*(prefs: Prefs; cfg: Config; req: Request; titleText=""; desc="";
title:
if titleText.len > 0:
- text titleText & " | " & cfg.title
+ text &"{titleText}|{cfg.title}"
else:
text cfg.title
diff --git a/src/views/renderutils.nim b/src/views/renderutils.nim
index 3e0cd19..bab01cd 100644
--- a/src/views/renderutils.nim
+++ b/src/views/renderutils.nim
@@ -1,11 +1,11 @@
# SPDX-License-Identifier: AGPL-3.0-only
-import strutils
+import strutils, strformat
import karax/[karaxdsl, vdom, vstyles]
import ".."/[types, utils]
proc icon*(icon: string; text=""; title=""; class=""; href=""): VNode =
var c = "icon-" & icon
- if class.len > 0: c = c & " " & class
+ if class.len > 0: c = &"{c} {class}"
buildHtml(tdiv(class="icon-container")):
if href.len > 0:
a(class=c, title=title, href=href)
diff --git a/src/views/rss.nimf b/src/views/rss.nimf
index f910f92..96f6466 100644
--- a/src/views/rss.nimf
+++ b/src/views/rss.nimf
@@ -117,7 +117,7 @@ ${renderRssTweets(profile.tweets.content, cfg)}