- PVSM.RU - https://www.pvsm.ru -

2-я часть истории, которая началась с смс-ки от Кати «Не звони и не пиши мне больше!!!!»
Первая часть тут [1]. Для тех, кому лень читать, приведу краткое изложение:
4,5 года назад я имел неосторожность начать писать свою криптовалюту на совсем неподходящем для этого дела языке — на PHP. В итоге, конечно, написал (я упрямый), но получился костыль на костыле и то, что оно вообще работало было просто какой-то магией.
Сразу хочу предупредить, программер я самоучка-недоучка и пишу код, мягко сказать, неидеально.
Началось всё с того, что я расстался с девушкой, по имени Катя и в этот же день (4 апреля 2015-го) решил изучить Go и переписать свою криптовалюту. Для тех, кому интересно, что там с Катей, я сделал спойлеры, ну а кому не интересно, просто не обращайте внимание на Катю
Поздний вечер, я уверен, что Катя останется на ночь. Но она почему-то стала твердить, что ей надо домой. Я сказал, что хочу накормить её завтраком в постели. Договорись, что завтра утром она приедет завтракать. Вызвал такси, она уехала. Уснул счастливым, т.к. нашел себе красивую девушку, с которой весело и интересно. На следующий день от неё пришла смс-ка «Привет. Чем занимаешься?». Помню свои ощущения, ведь мне написала девушка, которая мне очень нравится, это было кайфово. И скоро мы с ней должны были снова встретиться…
В тот день мы так и не встретились. И на следующий тоже. Я не знаю, что у неё происходило в голове, но она постоянно переносила свидания. Даже не поздравила с 23 февраля.
Решил её как-то растормошить. Написал Кате смс-ку: «скоро буду, конечно захвачу»
Она ответила: «в смысле?»
Я: «упс, не туда»
Она: «вот значит как»
У неё включилась ревность. Через день предложил встретиться, она согласилась.
Проанализировав её поведение и, немного погуглив, я наткнулся на книгу «Новые правила. Секреты успешных отношений для современных девушек»
За вечер прочитал и понял, что она меня зачем-то в себя влюбляет, используя советы из этой книжки.
Итог 8 месяцев: приложение работает на Win (64 [2]/32 [3]), OSX(64 [4]/32 [5]), Linux(64 [6]/32 [7]), FreeBSD(64 [8]/32 [9]), Android [10], IOS [11] (будет круто, если кто-то закинет в App Store).
Общего кода ~73к строк, кода под разные ОС где-то несколько сотен строчек.
40к — обработка/генерация блоков/тр-ий, 17.5к — контроллеры для интерфейса, 15.5к — шаблоны
Поддерживаются PostgreSQL, SQLite, MySQL.
Тех, кто будет тестировать мое творение, предупреждаю — могут быть баги, и если у Вас есть время, чиркните о них, пожалуйста, на darwin@dcoin.club [12] или в личку на хабре. Пожелания и советы тоже приветствуются.
В первой части я рассказал про то, как в dcoin функционирует веб-сервер.
В этой статье опишу, как я использую html/template [13]
Для генерации html-страниц в Go есть очень удобный пакет — html/template. Проще всего понять, как он работает, можно поэкспериментировав вот с этим примером [14]. Как правило, шаблоны хранятся в отдельных html-файлах, но в примерах на play.golang.org, для наглядности, шаблоны вставлены в go-код.
Большую часть информации по шаблонам я получил с gohugo.io/templates/go-templates [15]
Шаблоны у меня лежат тут [16]. Каждый шаблон начинается с определения его имени {{ define «templateName» }}, а заканчивается {{end}}
Контроллеры, которые использует шаблоны получают html код через функцию makeTemplate [17]. В неё я передаю название html-файла, имя шаблона (которое в {{define}} указано), параметры.
TemplateStr, err := makeTemplate("template_name", "templateName", &tplPage{
Alert: c.Alert,
Lang: c.Lang,
TxType: txType,
TxTypeId: txTypeId})
Полученный в TemplateStr набор байт передается content.go [18] и в итоге браузер получает сформированную html-страничку
В makeTemplate для всех шаблонов я подключаю дополнительные шаблоны, такие как signatures.html, alert_success.html. А также, добавляю пользовательские функции (FuncMap), которые используются для обработки данных в шаблонах.
Чтобы включить в шаблон другой шаблон нужно использовать такую конструкцию {{ template «signatures». }}. Точка в конце говорит о том, что нужно обработать все параметры в шаблоне signatures, без точки параметры не будут обработаны. signatures я добавляю практически во все шаблоны, вот пример
Сравнение. Приведу сразу несколько примеров, чтобы показать, как всё просто:
{{if not .UserID}} <span>Пусто</span> {{end}}
{{if .UserID}} <span>Не пусто</span> {{end}}
{{if eq .UserID 0}} <span>UserID == 0</span> {{end}}
{{if ne .UserID 0}} <span>UserID != 0</span> {{end}}
{{if lt .UserID 0}} <span>UserID < 0</span> {{end}}
{{if le .UserID 0}} <span>UserID <= 0</span> {{end}}
{{if gt .UserID 0}} <span>UserID > 0</span> {{end}}
{{if ge .UserID 0}} <span>UserID >= 0</span> {{end}}
{{.Lang.pool} — Lang — это карта. Т.е. через точку мы получаем значение, у которого ключ «pool»
Забегу немного вперед и скажу, что после той самой смс-ки «Не звони и не пиши мне больше!!!!», я в ВК переманил на свою сторону её подружку, с которой она жила 2 года, чтобы та помогала мне вернуть Катю. Так вот, её подружка, сказала, что всю ту неделю, когда я не звонил, Катя очень переживала и ждала звонка от меня. Еще она рассказала, что после первого свидания Катя буквально светилась от радости. Также она добавила, что никакую книгу по соблазнению она не читала.
html-код в переменных нужно дизэскейпить. Для этого необходимо добавить функцию:
funcMap := template.FuncMap{
"noescape": func(s string) template.HTML {
return template.HTML(s)
},
}
Все пользовательские функции у меня собраны в makeTemplate [17]. Использовать так:
{{noescape .Lang.htmlText}}
Купил её любимые цветы, вино и пр. Хотел весь день провести с ней, но к обеду она была еще не готова, через час тоже и через два. К моему удивлению, к шести часам она, наконец, собралась. Я вызвал ей такси.
Чтобы разобрать какую-нибудь карту используется Range. Вот пример, взятый отсюда [19]:
{{range $k, $country := .Countries}}
<option value='{{$k}}' {{if eq $k $.MyCountry}} selected {{end}}>{{$country}}</option>
{{end}}
Из кода, наверное, понятно, что происходит. Но хочу обратить особое внимание на $.MyCountry. Если не добавить $, тогда доступа к параметру .MyCountry не будет. Я по началу очень часто об этом забывал и долго думал, что не так. За пределами range доступ к MyCountry снова получается через {{.MyCountry}}
В шаблонах можно создавать свои переменные. Вот пример, взятый отсюда [20]:
{{range $i, $pageType := .PagesArray}}
{{$counter := ""}}
{{if eq $pageType "funders"}}
{{$counter := " <span class='count h6 bg-grey-dark white'>{{$.ProjectCountFunders}}</span>"}}
{{else if eq $pageType "comments"}}
{{$counter := " <span class='count h6 bg-grey-dark white'>{{$.ProjectCountComments}}</span>"}}
{{end}}
{{$counter}}
{{end}}
В данном примере создается новая переменная $counter, которой присваивается значение, в зависимости от условия, и ниже выводится ее результат
Несколько непривычной для меня оказалась логика работы and/or.
Примеры:
{{if and (eq .Start 1) (ne .BlockId 1) (gt .UserId 0)}}
Если .Start == 1 и .BlockId != 1 и .UserId > 0
{{if or (eq .Start 1) (ne .BlockId 1) (gt .UserId 0)}}
Если .Start == 1 или .BlockId != 1 или .UserId > 0
Еще одна проблема отняла у меня довольно много времени. Если в контроллере нужно сформировать какой-то js-код, например:
var x="1";
То при выводе его в шаблоне через {{.SomeJSCode}} мы получим
"var x="1";"
noescape тут не поможет. Нужно добавить новую пользовательскую функцию:
"js": func(s string) template.JS {
return template.JS(s)
},
И в шаблоне использовать {{js .SomeJSCode}}
В контроллере использовать тип template.JS. Предварительно преобразовав переменную string: template.JS(SomeJsStringVariable). В самом шаблоне в таком случае нужно выводить {{.SomeJSCode}}
В следующих статьях я расскажу про БД, плавное завершение приложения через сигналы, обработку блоков из блокчейна, шифрование в GO и расшифровку в JS, про то, как я, немного изменил gomobile, добавив уведомления и работу в фоне для IOS и Android приложений.
Автор: c-darwin
Источник [22]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/go/106488
Ссылки в тексте:
[1] тут: http://habrahabr.ru/company/dcoin/blog/272695/
[2] 64: https://github.com/c-darwin/dcoin-go/releases/download/v1.0.2b7/dcoin_win64.exe
[3] 32: https://github.com/c-darwin/dcoin-go/releases/download/v1.0.2b7/dcoin_win32.exe
[4] 64: https://github.com/c-darwin/dcoin-go/releases/download/v1.0.2b7/dcoin_osx64.dmg
[5] 32: https://github.com/c-darwin/dcoin-go/releases/download/v1.0.2b7/dcoin_osx32.dmg
[6] 64: https://github.com/c-darwin/dcoin-go/releases/download/v1.0.2b7/dcoin_linux64.deb
[7] 32: https://github.com/c-darwin/dcoin-go/releases/download/v1.0.2b7/dcoin_linux32.deb
[8] 64: https://github.com/c-darwin/dcoin-go/releases/download/v1.0.2b7/dcoin_freebsd64.zip
[9] 32: https://github.com/c-darwin/dcoin-go/releases/download/v1.0.2b7/dcoin_freebsd32.zip
[10] Android: https://github.com/c-darwin/dcoin-go/releases/download/v1.0.2b7/dcoin.apk
[11] IOS: http://dcoin.club/ru/ios.html
[12] darwin@dcoin.club: mailto:darwin@dcoin.club
[13] html/template: https://golang.org/pkg/html/template/
[14] этим примером: https://play.golang.org/p/_3lNVlNSi8
[15] gohugo.io/templates/go-templates: http://gohugo.io/templates/go-templates/
[16] тут: https://github.com/c-darwin/dcoin-go/tree/master/static/templates
[17] makeTemplate: https://github.com/c-darwin/dcoin-go/blob/master/packages/controllers/common.go#L326
[18] content.go: https://github.com/c-darwin/dcoin-go/blob/master/packages/controllers/content.go
[19] отсюда: https://github.com/c-darwin/dcoin-go/blob/master/static/templates/change_geolocation.html#L56
[20] отсюда: https://github.com/c-darwin/dcoin-go/blob/master/static/templates/cf_page_preview.html#L213
[21] это видео: https://www.youtube.com/watch?v=LO83ozF302I
[22] Источник: http://habrahabr.ru/post/273333/
Нажмите здесь для печати.