10
"xelbot.com/reprogl/container"
11
"xelbot.com/reprogl/models"
12
"xelbot.com/reprogl/utils"
13
"xelbot.com/reprogl/utils/hashid"
14
"xelbot.com/reprogl/views/style"
17
const RegionalIndicatorOffset = 127397
19
func rawHTML(s string) template.HTML {
20
return template.HTML(s)
23
func urlGenerator(routeName string, pairs ...string) string {
24
return container.GenerateURL(routeName, pairs...)
27
func absUrlGenerator(routeName string, pairs ...string) string {
28
return container.GenerateAbsoluteURL(routeName, pairs...)
31
func tags(tl models.TagList) template.HTML {
35
links := make([]string, len(tl))
36
for i, t := range tl {
37
links[i] = fmt.Sprintf(
38
"<a href=\"%s\">%s</a>",
39
urlGenerator("tag-first", "slug", t.Slug),
44
s += strings.Join(links, ", ")
47
return template.HTML(s)
50
func nl2br(s string) string {
51
return strings.Replace(s, "\n", "<br/>", -1)
54
func authorBio() string {
59
rune(0x1F980), // crab
60
rune(0x1F997), // cricket
61
rune(0x1F577), // spider
62
rune(0x1F982), // scorpion
63
rune(0x1F990), // shrimp
66
return container.GetConfig().Author.Bio + " " + string(emoij[rand.Intn(len(emoij))])
69
func authorDataPart(item string) (str string) {
70
author := container.GetConfig().Author
76
str = fmt.Sprintf("https://github.com/%s", author.GithubUser)
78
str = fmt.Sprintf("https://t.me/%s/", author.TelegramChannel)
80
str = author.MastodonLink
82
str = fmt.Sprintf("https://gitverse.ru/%s", author.GitVerseUser)
90
func authorLocation() template.HTML {
91
location := container.GetConfig().AuthorLocationRu
92
s := make([]string, 0, 3)
94
if location.City != "" {
95
s = append(s, "<span class=\"locality\">"+location.City+"</span>")
97
if location.Region != "" {
98
s = append(s, "<span class=\"region\">"+location.Region+"</span>")
100
if location.Country != "" {
101
s = append(s, "<span class=\"country-name\">"+location.Country+"</span>")
104
return template.HTML(strings.Join(s, ", "))
107
func authorJob() template.HTML {
108
jobs := container.GetConfig().Jobs
111
"<span class=\"title\">%s</span> в <a class=\"org\" href=\"%s\">%s</a>",
117
return template.HTML(s)
120
func authorAvatar() string {
121
return models.AvatarLink(1, hashid.Male|hashid.User, 200)
124
func renderESI(routeName string, pairs ...string) template.HTML {
126
"<esi:include src=\"%s\" onerror=\"continue\"/>",
127
urlGenerator(routeName, pairs...),
130
return template.HTML(s)
133
func subString(input string, length int) (str string) {
134
symbols := []rune(input)
136
if len(symbols) >= length {
137
str = string(symbols[:length-3]) + "..."
145
func timeTag(t time.Time) template.HTML {
146
var s = "<time class=\"post-date\" datetime=\"" +
147
t.Format(time.RFC3339) + "\">" +
149
utils.RuMonthName(t.Month(), true) +
150
t.Format(" 2006, 15:04:05.000") +
153
return template.HTML(s)
156
func commentsCountString(cnt int) (str string) {
159
str = fmt.Sprintf("%d комментарий", cnt)
162
if modulo > 1 && modulo < 5 {
163
str = fmt.Sprintf("%d комментария", cnt)
166
if modulo > 4 || modulo == 0 {
167
str = fmt.Sprintf("%d комментариев", cnt)
170
modulo100 := cnt % 100
171
if modulo100 >= 11 && modulo100 <= 14 {
172
str = fmt.Sprintf("%d комментариев", cnt)
178
func timesCountString(cnt int) (str string) {
181
str = fmt.Sprintf("%d раз", cnt)
184
if modulo > 1 && modulo < 5 {
185
str = fmt.Sprintf("%d раза", cnt)
188
if modulo > 4 || modulo == 0 {
189
str = fmt.Sprintf("%d раз", cnt)
192
modulo100 := cnt % 100
193
if modulo100 >= 12 && modulo100 <= 14 {
194
str = fmt.Sprintf("%d раз", cnt)
200
func flagCounterImage(fullSize bool) func() template.HTML {
208
cdn := container.GetConfig().CDNBaseURL
209
if container.IsDevMode() {
210
url = cdn + "/images/flagcounter.png"
212
url = cdn + "/images/flagcounter_mini.png"
217
url = "//s05.flagcounter.com/count2/D9g3/bg_23222D/txt_FFFFFF/border_FFFFFF/columns_2/maxflags_4/viewers_3/labels_0/pageviews_1/flags_0/percent_1/"
219
url = "//s05.flagcounter.com/mini/D9g3/bg_23222D/txt_FFFFFF/border_23222D/flags_0/"
225
return func() template.HTML {
226
return template.HTML(
227
fmt.Sprintf("<img src=\"%s\" alt=\"Free counters!\" width=\"%d\" height=\"%d\">", url, w, h),
232
func emojiFlag(countryCode string) string {
233
if countryCode == "-" {
234
// https://apps.timwhitlock.info/unicode/inspect?s=%F0%9F%8F%B4%E2%80%8D%E2%98%A0%EF%B8%8F
235
return string([]rune{'\U0001F3F4', '\u200D', '\u2620', '\uFE0F'})
238
if len(countryCode) != 2 {
242
countryCode = strings.ToUpper(countryCode)
244
resultBytes := make([]rune, 0, 2)
245
for _, b := range []byte(countryCode) {
246
resultBytes = append(resultBytes, rune(RegionalIndicatorOffset+int(b)))
249
return string(resultBytes)
252
func articleStyles(article *models.Article, acceptAvif, acceptWebp bool) template.HTML {
253
return template.HTML(style.GenerateArticleStyles(article, acceptAvif, acceptWebp))
256
func statisticsStyles() template.HTML {
257
return template.HTML(style.GenerateStatisticsStyles())
260
func indexStyles() template.HTML {
261
return template.HTML(style.GenerateIndexStyles())
264
func infoStyles() template.HTML {
265
return template.HTML(style.GenerateInfoStyles())
268
func profileStyles() template.HTML {
269
return template.HTML(style.GenerateProfileStyles())