свой первый блог я завёл в жж в 2003 году. Несколько лет спустя в 2006 я тихо открыл этот «техноблог». Он был для меня песочницей, в которой я игрался с Django, и для контента писал сюда околорабочие вещи. А основная аудитория была у моих нетехнических постов в жж, и мне вполне нравилось это разделение
со временем я стал писать намного реже, и частота постов в обоих блогах приблизительно сравнялась, а количество комментариев в жж упало до минимума. Кроме того, я неоднократно сталкивался с тем, что для некоторых постов было сложно определить, к какой категории они относятся. Ещё недавно я парой неаккуратных кликов случайно снёс минималистичный дизайн жж, и восстанавливать его было лень. Но последней соломинкой стало то, что фейсбук забанил поддомен users.livejournal.com, на котором размещались блоги всех недостойных собственного поддомена. Тогда я понял, что пора валить™
довольно долго это была мысль просто о переезде личного блога на свою платформу. Но теперь я решил, что больше нет смысла содержать два блога, и многие вещи станут проще, если блог будет один — вот этот. Сегодня и начну!
я ещё не до конца определился, что делать с существующим содержимым жж. Не думаю, что на него ставили много ссылок, поэтому скорее всего я перенесу его куда-нибудь к себе, а посты в жж спрячу под замок
в большинстве правильно сделанных программ поля для ввода чисел имеют по соседству две маленькие стрелочки: вверх и вниз. С их помощью указанное число можно увеличить или уменьшить, не прибегая к помощи клавиатуры, только мышью. Практически всегда эти поля отзываются и на прокрутку колёсика мыши аналогичным образом. Не то, чтобы мне часто приходилось подправлять числа, но это маленькое удобство мне очень нравится.
однако в браузерах в течение долгого времени поля ввода были очень примитивны, и только относительно недавно стали понимать своё предназначение: для любого текста, для дат, для чисел, и т.п. Числовые обзавелись стрелочками, вот как это: , однако во многих браузерах ещё не умеют реагировать на колёсико мыши. Благодаря расширяемости платформы этот недостаток легко исправить пользовательским скриптом Adjust number values using mousewheel.
я уже не раз писал о том, как люблю сайты на статических файлах. Выходило слегка иронично, потому что сам блог с этими записями работал на очень даже динамическом Django. Однако в блоге всё-таки довольно много разных типов взаимосвязанных страниц, поэтому я даже не пытался перевести его на статические рельсы. Так и приходилось жить, регулярно страдая от необходимости подстраивать код под очередной релиз Django.
а вот в 2014 году мне стало попадаться много ссылок про инструменты, которые замечательно облегчают создание таких статических сайтов, и порой даже легко интегрируются с гитхабом. «Время пришло,» — подумал я, и взялся изучать тему. Инструментов оказалось в изобилии, но только потому, что самих подходов тоже изобилие. Например, есть metalsmith со своими плагинами, который из-за отчаянной низкоуровневости мало чем отличается от программирования всего самостоятельно. Например, есть DocPad, который умеет кучу всего, не фокусируясь непосредственно на блогах. Есть по паре движков под модные языки программирования, которые работают именно над блогами. Из них самым заметным в моих новостях был jekyll, но он оказался на Ruby, и с ним снова пришлось бы отлаживать запутанный код на малознакомом языке, а для этого мне хватает Питона. В рамках набора опыта с Node.js я попытал счастья с Hexo, но не смог преодолеть некоторые из его противоестественных практик.
в итоге я остановился на пеликане, и вот этот пост пишу уже в него. Процесс занял некоторое время, потому что пришлось вынимать данные из старого блога в нужном формате, подстраивать шаблоны под слегка отличающийся синтаксис и кардинально новые API, а также (как и ожидалось) отправлять авторам несколько исправлений и дополнений. Поскольку каждое из них нужно оформлять как отдельный pull request, я познал радость ручной интеграции оных в своей копии кода. Но результатом я пока что доволен, посмотрим теперь, как пойдёт дальше.
я ведь теперь и из ЖЖ хочу перенести блог на эту же платформу.
в angular.js есть удобный механизм инъекции зависимостей. Среди прочего он позволяет довольно удобным образом подменять эти зависимости имитациями при модульном тестировании: достаточно написать $provide.value('name', mockedDependency). Ну и создать эту имитацию тоже нужно.
однако в большом проекте часто не всё оказывается так гладко, и проявляются проблемы этого «наивного» подхода. Во-первых, программист может добавить в модуль новую зависимость, но забыть подменить её имитацией в тесте. Во-вторых, имитации активно используемых модулей дублируются в десятках тестов. В третьих, неопытные программисты часто будут подгружать в тест реальную зависимость, и навешивать заглушку только на одну её функцию. Соответственно, остальные её функции останутся реальными, да и заодно будут инициализированы зависимости второго и следующих уровней.
я вдохновился тем, как разработчики самого angular.js создали отдельный файл с имитациями популярных модулей — angular-mocks.js. (Достаточно подключить его в страницу тестов, и работать с таймаутами, HTTP и обещаниями станет намного проще.) Нам было нужно что-то вроде этого, но для всех наших модулей. Для директив и контроллеров всё очевидно, но вот тестировать модули, для которых заглушки уже есть, так не получится: тесты будут ожидать реальных результатов от имитации. Поэтому нашу глобальную имитацию использовать слегка сложнее: помимо подключения файла нужно ещё указать, что именно будет имитироваться. Например, в начале теста директивы, для которой нет заглушки, мы пишем beforeEach(NS.mocks.all()). А вот в начале теста модуля routing, для которого есть заглушка, ставится beforeEach(NS.mocks.except('routing')).
NS.mocks.all = function() {
return function() {
module(function($provide) {
Object.keys(NS.mocks.factories).forEach(function(mockName) {
var mockInstance = NS.mocks.factories[mockName]();
$provide.value(mockName, mockInstance);
});
});
};
};
NS.mocks.except = function(excludedName) {
if (!(excludedName in NS.mocks.factories)){
throw new Error("Don't forget to implement mock for " + excludedName + " in mocks.js");
}
return function() {
module(function($provide) {
var mocks = Object.keys(NS.mocks.factories).filter(function(name) {
return (name !== excludedName);
});
mocks.forEach(function(mockName) {
var mockInstance = NS.mocks.factories[mockName]();
$provide.value(mockName, mockInstance);
});
});
};
};
NS.mocks.factories.routing = function() {
return jasmine.createSpyObj('routing', ['to', 'from']);
};
элементы доменного имени расположены в порядке «от специфичного к общему». Элементы пути в URL расположены в порядке «от общего к специфичному», так же, как и в файловой системе, и во многих других. Конечно, уже давно поздно это менять, но мне кажется, что было бы удобнее иметь в этих двух частях URL одинаковый порядок. И лучше ему быть именно «от общего к специфичному»: ru.gov.kremlin.documents/laws/12345.html. Если бы мы использовали его с самого начала, у нас бы не было проблемы безопасности «поддомен evil.com притворяется, что он на самом деле paypal.com»