<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[rinat.io]]></title><description><![CDATA[Blog about web development]]></description><link>https://rinat.io</link><generator>RSS</generator><lastBuildDate>Mon, 18 Jan 2021 00:58:13 +0000</lastBuildDate><atom:link href="https://rinat.io/feed" rel="self" type="application/rss+xml"/><author><![CDATA[mail@rinat.io (Rinat)]]></author><dc:creator>Rinat</dc:creator><item><title><![CDATA[Mixing in and Extending JavaScript Getters and Setters]]></title><description><![CDATA[Updating popular mixin helpers to extend JavaScript getters and setters  using Object.getOwnPropertyDescriptor and Object.defineProperty]]></description><link>https://rinat.io/blog/mixing-in-and-extending-javascript-getters-and-setters</link><guid isPermaLink="false">https://rinat.io/blog/mixing-in-and-extending-javascript-getters-and-setters</guid><dc:creator><![CDATA[mail@rinat.io (Rinat)]]></dc:creator><pubDate>Sun, 24 Aug 2014 21:06:26 +0000</pubDate><content:encoded>&lt;p&gt;I like to use JavaScript getters and setters. Even though they do not work in IE6-8, we
can use them with node.js on server side. There&amp;#x27;s one issue though — mixing in those methods.&lt;/p&gt;&lt;p&gt;A lot of JavaScript libraries and frameworks have
&lt;a href=&quot;http://addyosmani.com/resources/essentialjsdesignpatterns/book/#mixinpatternjavascript&quot;&gt;mixin&lt;/a&gt;
helpers, for example &lt;code&gt;jQuery.extend()&lt;/code&gt;, &lt;code&gt;angular.extend()&lt;/code&gt; and &lt;code&gt;_.extend()&lt;/code&gt;. It is simple and powerful,
although if you try to use those methods for extending getters, here&amp;#x27;s what you&amp;#x27;ll get:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;hljs language-javascript&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;var&lt;/span&gt; sumMixin = {
    &lt;span class=&quot;hljs-attr&quot;&gt;a&lt;/span&gt;: &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;,
    &lt;span class=&quot;hljs-attr&quot;&gt;b&lt;/span&gt;: &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;,
    &lt;span class=&quot;hljs-keyword&quot;&gt;get&lt;/span&gt; sum() {
        &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;this&lt;/span&gt;.a + &lt;span class=&quot;hljs-keyword&quot;&gt;this&lt;/span&gt;.b;
    }
}

&lt;span class=&quot;hljs-keyword&quot;&gt;var&lt;/span&gt; Foo = &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{};
_.extend(Foo.prototype, sumMixin);

&lt;span class=&quot;hljs-keyword&quot;&gt;var&lt;/span&gt; foo = &lt;span class=&quot;hljs-keyword&quot;&gt;new&lt;/span&gt; Foo();
foo.a = &lt;span class=&quot;hljs-number&quot;&gt;3&lt;/span&gt;;
foo.b = &lt;span class=&quot;hljs-number&quot;&gt;3&lt;/span&gt;;
&lt;span class=&quot;hljs-built_in&quot;&gt;console&lt;/span&gt;.log(foo.sum); &lt;span class=&quot;hljs-comment&quot;&gt;// will output 2&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That&amp;#x27;s because after &lt;code&gt;_.extend&lt;/code&gt; execution &lt;code&gt;Foo.prototype.sum&lt;/code&gt; is not a method,
it is actually a result of &lt;code&gt;sumMixin.sum&lt;/code&gt; execution.&lt;/p&gt;&lt;p&gt;We can workaround this issue by assigning prototype directly, although if you want to add other
methods to &lt;code&gt;Foo.prototype&lt;/code&gt; you&amp;#x27;ll have to make it this way:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;hljs language-javascript&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;var&lt;/span&gt; Foo = &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{};
Foo.prototype = sumMixin;
Foo.prototype.bar = &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{};
Foo.prototype._test = &lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;test&amp;#x27;&lt;/span&gt;;
&lt;span class=&quot;hljs-comment&quot;&gt;// And here&amp;#x27;s a getter :/&lt;/span&gt;
&lt;span class=&quot;hljs-built_in&quot;&gt;Object&lt;/span&gt;.defineProperty(Foo.prototype, &lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;test&amp;#x27;&lt;/span&gt;, {
    &lt;span class=&quot;hljs-attr&quot;&gt;get&lt;/span&gt;: &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
        &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;this&lt;/span&gt;._test;
    }
});

&lt;span class=&quot;hljs-keyword&quot;&gt;var&lt;/span&gt; foo = &lt;span class=&quot;hljs-keyword&quot;&gt;new&lt;/span&gt; Foo();
foo.a = &lt;span class=&quot;hljs-number&quot;&gt;3&lt;/span&gt;;
foo.b = &lt;span class=&quot;hljs-number&quot;&gt;3&lt;/span&gt;;
&lt;span class=&quot;hljs-built_in&quot;&gt;console&lt;/span&gt;.log(foo.sum); &lt;span class=&quot;hljs-comment&quot;&gt;// will output 6 now&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It works, but&lt;/p&gt;&lt;ul&gt;&lt;li&gt;we can apply only one mixin this way&lt;/li&gt;&lt;li&gt;we lose the sugar we had with &lt;code&gt;extend()&lt;/code&gt; helpers.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;If you still like magic methods and mixins you can tweak your favorite &lt;code&gt;extend()&lt;/code&gt; method
to respect getters and setters like this (based on Underscore):&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;hljs language-javascript&quot;&gt;_.extend = &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;obj&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;hljs-built_in&quot;&gt;Array&lt;/span&gt;.prototype.slice.call(&lt;span class=&quot;hljs-built_in&quot;&gt;arguments&lt;/span&gt;, &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;).forEach(&lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;source&lt;/span&gt;) &lt;/span&gt;{
        &lt;span class=&quot;hljs-keyword&quot;&gt;var&lt;/span&gt; descriptor, prop;
        &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; (source) {
            &lt;span class=&quot;hljs-keyword&quot;&gt;for&lt;/span&gt; (prop &lt;span class=&quot;hljs-keyword&quot;&gt;in&lt;/span&gt; source) {
                descriptor = &lt;span class=&quot;hljs-built_in&quot;&gt;Object&lt;/span&gt;.getOwnPropertyDescriptor(source, prop);
                &lt;span class=&quot;hljs-built_in&quot;&gt;Object&lt;/span&gt;.defineProperty(obj, prop, descriptor);
            }
        }
    });
    &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; obj;
};&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;Object.getOwnPropertyDescriptor&lt;/code&gt; and &lt;code&gt;Object.defineProperty&lt;/code&gt;
help us copy &lt;code&gt;sum&lt;/code&gt; method description instead of its value to the prototype.
Now mixing in works as expected:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;hljs language-javascript&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;var&lt;/span&gt; Foo = &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{};
_.extend(Foo.prototype, sumMixin, {
    &lt;span class=&quot;hljs-attr&quot;&gt;bar&lt;/span&gt;: &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{},
    &lt;span class=&quot;hljs-attr&quot;&gt;_test&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;test&amp;#x27;&lt;/span&gt;,
    &lt;span class=&quot;hljs-keyword&quot;&gt;get&lt;/span&gt; test() {
        &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;this&lt;/span&gt;._test;
    }
});

&lt;span class=&quot;hljs-keyword&quot;&gt;var&lt;/span&gt; foo = &lt;span class=&quot;hljs-keyword&quot;&gt;new&lt;/span&gt; Foo();
foo.a = &lt;span class=&quot;hljs-number&quot;&gt;3&lt;/span&gt;;
foo.b = &lt;span class=&quot;hljs-number&quot;&gt;3&lt;/span&gt;;
&lt;span class=&quot;hljs-built_in&quot;&gt;console&lt;/span&gt;.log(foo.sum); &lt;span class=&quot;hljs-comment&quot;&gt;// will output 6&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;</content:encoded></item><item><title><![CDATA[AngularJS & jQuery Plugins Memory Leaks]]></title><description><![CDATA[Checking JavaScript memory leaks in a single page application with Chrome DevTools memory timeline.  Using AngularJS $destroy event to unload jQuery plugins]]></description><link>https://rinat.io/blog/angularjs-and-jquery-plugins-memory-leaks</link><guid isPermaLink="false">https://rinat.io/blog/angularjs-and-jquery-plugins-memory-leaks</guid><dc:creator><![CDATA[mail@rinat.io (Rinat)]]></dc:creator><pubDate>Tue, 18 Feb 2014 18:22:12 +0000</pubDate><content:encoded>&lt;p&gt;Sooner or later working on single page applications you start worrying about
JavaScript memory leaks. We&amp;#x27;re using AngularJS in our project and while it does a lot of magic behind the
scene you still need to make sure jQuery plugins are getting unloaded when you leave the page because
that stuff is out of AngularJS scope.&lt;/p&gt;&lt;h3&gt;tl;dr&lt;/h3&gt;&lt;p&gt;Use AngularJS &lt;code&gt;$destroy&lt;/code&gt; event
to unload your jQuery plugins and DOM events:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;hljs language-javascript&quot;&gt;.directive(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;dtPicker&amp;#x27;&lt;/span&gt;, &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; {
        &lt;span class=&quot;hljs-attr&quot;&gt;link&lt;/span&gt;: &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;scope, elm&lt;/span&gt;) &lt;/span&gt;{
            elm.datetimepicker();
            scope.$on(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;$destroy&amp;#x27;&lt;/span&gt;, &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
                elm.data(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;DateTimePicker&amp;#x27;&lt;/span&gt;).destroy();
            });
        }
    };
});&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Checking memory leak&lt;/h3&gt;&lt;p&gt;First you need to check if there&amp;#x27;s a memory leak or not. Here&amp;#x27;s a great
&lt;a href=&quot;http://www.youtube.com/watch?v=L3ugr9BJqIs&quot;&gt;video&lt;/a&gt; that helped me to get started with
timeline and profiling in chrome DevTools. It also has a good explanation on how the JavaScript
garbage collector works and why memory leaks happen.&lt;/p&gt;&lt;h3&gt;Example&lt;/h3&gt;&lt;p&gt;To illustrate the issue I added a &lt;a href=&quot;/example/angular-and-jquery-plugin-memory-leak/&quot;&gt;simple test page&lt;/a&gt;
with two directives. Both of them use bootstrap &lt;a href=&quot;https://github.com/eonasdan/bootstrap-datetimepicker&quot;&gt;datetimepicker&lt;/a&gt;
jQuery plugin as an example and one of them have memory leak while another one doesn&amp;#x27;t.&lt;/p&gt;&lt;p&gt;In short: when you suspect a memory leak on some of your pages you need to open that page in incognito mode,
run memory timeline recording and load-unload the page few times. Here&amp;#x27;s a short video
where I test first datetime picker directive:&lt;/p&gt;&lt;div class=&quot;video-container&quot;&gt;&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;//www.youtube.com/embed/q248ySuB5II&quot; frameBorder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;p&gt;On the timeline you can see that number of DOM nodes and event listeners is constantly increasing, that&amp;#x27;s a sign
of memory leak:&lt;/p&gt;&lt;a href=&quot;static/memory-leak-timeline-31f78386f312964d9110f09bb9971907.png&quot;&gt;&lt;img src=&quot;static/memory-leak-timeline-31f78386f312964d9110f09bb9971907.png&quot;/&gt;&lt;/a&gt;&lt;p&gt;This process might be very time consuming, but it is the most straightforward and simple way I found so far.&lt;/p&gt;&lt;h3&gt;AngularJS $destroy event&lt;/h3&gt;&lt;p&gt;To fix this memory leak we need to unload the jQuery plugin when the page is changed or scope is destroyed.
AngularJS has a handy &lt;code&gt;$destroy&lt;/code&gt; event and
most of the jQuery plugins provide some kind of &lt;code&gt;destroy&lt;/code&gt; method. All you need to do is call that method on &lt;code&gt;$destroy&lt;/code&gt;
event:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;hljs language-javascript&quot;&gt;.directive(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;dtPicker&amp;#x27;&lt;/span&gt;, &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; {
        &lt;span class=&quot;hljs-attr&quot;&gt;link&lt;/span&gt;: &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;scope, elm&lt;/span&gt;) &lt;/span&gt;{
            elm.datetimepicker();
            scope.$on(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;$destroy&amp;#x27;&lt;/span&gt;, &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
                elm.data(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;DateTimePicker&amp;#x27;&lt;/span&gt;).destroy();
            });
        }
    };
});&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If we try same steps on the &lt;a href=&quot;/example/angular-and-jquery-plugin-memory-leak/#/plugin-without-memory-leak&quot;&gt;example page&lt;/a&gt;
for the new directive now, you can see that memory is getting unloaded properly
and number of DOM nodes and event listeners stay the same:&lt;/p&gt;&lt;a href=&quot;static/no-memory-leak-timeline-162c008aa3db28b0df81c18f5ef1fb95.png&quot;&gt;&lt;img src=&quot;static/no-memory-leak-timeline-162c008aa3db28b0df81c18f5ef1fb95.png&quot;/&gt;&lt;/a&gt;&lt;p&gt;AngularJS also triggers jQuery &lt;code&gt;$destroy&lt;/code&gt; event on the DOM element:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;hljs language-javascript&quot;&gt;elm.on(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;$destroy&amp;#x27;&lt;/span&gt;, &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
    elm.data(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;DateTimePicker&amp;#x27;&lt;/span&gt;).destroy();
});&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can make a clean up this way as well if you&amp;#x27;d like, I haven&amp;#x27;t found any difference so far.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[AngularJS Directives with jQuery Plugins]]></title><description><![CDATA[Creating AngularJS input directive with ngModel and jQuery plugins. Considering the spectrum color picker as an example]]></description><link>https://rinat.io/blog/angular-directives-with-jquery-plugins</link><guid isPermaLink="false">https://rinat.io/blog/angular-directives-with-jquery-plugins</guid><dc:creator><![CDATA[mail@rinat.io (Rinat)]]></dc:creator><pubDate>Sun, 03 Nov 2013 00:00:00 +0000</pubDate><content:encoded>&lt;p&gt;AngularJS directives are very powerful, but first time
it looks quite tricky on how to set them up with jQuery plugins.
Let&amp;#x27;s say we want to add the &lt;a href=&quot;http://bgrins.github.io/spectrum/&quot;&gt;spectrum&lt;/a&gt;
jQuery color picker on our form using a directive.
Here&amp;#x27;s how we could make that with an isolate scope and two way data binding:&lt;/p&gt;&lt;div data-height=&quot;566&quot; data-theme-id=&quot;0&quot; data-slug-hash=&quot;ucpzt&quot; data-user=&quot;rinatio&quot; data-default-tab=&quot;js&quot; class=&quot;codepen&quot;&gt;&lt;pre&gt;&lt;code class=&quot;hljs language-javascript&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;var&lt;/span&gt; app = angular.module(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;app&amp;#x27;&lt;/span&gt;, []);

app.directive(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;colorPicker&amp;#x27;&lt;/span&gt;, &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; {
        &lt;span class=&quot;hljs-attr&quot;&gt;scope&lt;/span&gt;: {
            &lt;span class=&quot;hljs-attr&quot;&gt;color&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;=&amp;quot;&lt;/span&gt;
        },
        &lt;span class=&quot;hljs-attr&quot;&gt;link&lt;/span&gt;: &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;scope, elm, attrs&lt;/span&gt;) &lt;/span&gt;{

            elm.spectrum({
                &lt;span class=&quot;hljs-attr&quot;&gt;color&lt;/span&gt;: scope.color,
                &lt;span class=&quot;hljs-attr&quot;&gt;change&lt;/span&gt;: &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;color&lt;/span&gt;) &lt;/span&gt;{
                    scope.$apply(&lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
                        scope.color = color.toHexString();
                    });
                }
            });

            scope.$watch(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;color&amp;#x27;&lt;/span&gt;, &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;newColor&lt;/span&gt;) &lt;/span&gt;{
                elm.spectrum(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;set&amp;#x27;&lt;/span&gt;, newColor);
            });

        }
    };
});&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;See the &lt;a href=&quot;http://codepen.io/rinatio/pen/ucpzt&quot;&gt;Pen&lt;/a&gt; by Rinat (&lt;a href=&quot;http://codepen.io/rinatio&quot;&gt;@rinatio&lt;/a&gt;) on &lt;a href=&quot;http://codepen.io&quot;&gt;CodePen&lt;/a&gt;&lt;/p&gt;&lt;div&gt;&lt;script async src=&quot;//codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Here we&amp;#x27;re listening for the color picker change event to update the data
when user chooses a new one. Note that you have to use
&lt;code&gt;$apply&lt;/code&gt; here
because event is being triggered from outside of angular framework.
On the other hand we&amp;#x27;re watching for
external data changes with angular
&lt;code&gt;$watch&lt;/code&gt;
to update the color picker value.&lt;/p&gt;&lt;p&gt;Usually in such cases it&amp;#x27;s better to use &lt;code&gt;ngModel&lt;/code&gt;
with &lt;code&gt;NgModelController&lt;/code&gt;
instead of isolate scope and two way data binding,
since it also provides a validation behavior for our input:&lt;/p&gt;&lt;div data-height=&quot;513&quot; data-theme-id=&quot;0&quot; data-slug-hash=&quot;jAaoE&quot; data-user=&quot;rinatio&quot; data-default-tab=&quot;js&quot; class=&quot;codepen&quot;&gt;&lt;pre&gt;&lt;code class=&quot;hljs language-javascript&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;var&lt;/span&gt; app = angular.module(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;app&amp;#x27;&lt;/span&gt;, []);

app.directive(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;colorPicker&amp;#x27;&lt;/span&gt;, &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; {
        &lt;span class=&quot;hljs-attr&quot;&gt;require&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;ngModel&amp;#x27;&lt;/span&gt;,
        &lt;span class=&quot;hljs-attr&quot;&gt;link&lt;/span&gt;: &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;scope, elm, attrs, ngModel&lt;/span&gt;) &lt;/span&gt;{
            elm.spectrum({
                &lt;span class=&quot;hljs-attr&quot;&gt;color&lt;/span&gt;: ngModel.$viewValue,
                &lt;span class=&quot;hljs-attr&quot;&gt;change&lt;/span&gt;: &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;color&lt;/span&gt;) &lt;/span&gt;{
                    scope.$apply(&lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
                        ngModel.$setViewValue(color.toHexString());
                    });
                }
            });

            ngModel.$render = &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
                elm.spectrum(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;set&amp;#x27;&lt;/span&gt;, ngModel.$viewValue || &lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;&amp;#x27;&lt;/span&gt;);
            };

        }
    };
});&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;See the &lt;a href=&quot;http://codepen.io/rinatio/pen/jAaoE&quot;&gt;Pen&lt;/a&gt; by Rinat (&lt;a href=&quot;http://codepen.io/rinatio&quot;&gt;@rinatio&lt;/a&gt;) on &lt;a href=&quot;http://codepen.io&quot;&gt;CodePen&lt;/a&gt;&lt;/p&gt;&lt;div&gt;&lt;script async src=&quot;//codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Now we can check if the form is valid and show a proper validation error etc. In this example
the text input value won&amp;#x27;t be updated and submit button will be disabled
until we select the white color. Note that we
&lt;a href=&quot;http://docs.angularjs.org/api/ng.directive:ngModel.NgModelController#description_isolated-scope-pitfall&quot;&gt;cannot use&lt;/a&gt;
isolate scope with &lt;code&gt;ngModel&lt;/code&gt; directive.&lt;/p&gt;&lt;p&gt;Finally imagine we want to reuse this directive somewhere else,
but it needs a different options for jQuery plugin:&lt;/p&gt;&lt;div data-height=&quot;533&quot; data-theme-id=&quot;0&quot; data-slug-hash=&quot;gwvBl&quot; data-user=&quot;rinatio&quot; data-default-tab=&quot;js&quot; class=&quot;codepen&quot;&gt;&lt;pre&gt;&lt;code class=&quot;hljs language-javascript&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;var&lt;/span&gt; app = angular.module(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;app&amp;#x27;&lt;/span&gt;, []);

app.directive(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;colorPicker&amp;#x27;&lt;/span&gt;, &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; {
        &lt;span class=&quot;hljs-attr&quot;&gt;require&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;ngModel&amp;#x27;&lt;/span&gt;,
        &lt;span class=&quot;hljs-attr&quot;&gt;link&lt;/span&gt;: &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;scope, elm, attrs, ngModel&lt;/span&gt;) &lt;/span&gt;{
            &lt;span class=&quot;hljs-keyword&quot;&gt;var&lt;/span&gt; options = angular.extend({
                &lt;span class=&quot;hljs-attr&quot;&gt;color&lt;/span&gt;: ngModel.$viewValue,
                &lt;span class=&quot;hljs-attr&quot;&gt;change&lt;/span&gt;: &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;color&lt;/span&gt;) &lt;/span&gt;{
                    scope.$apply(&lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
                        ngModel.$setViewValue(color.toHexString());
                    });
                }
            }, scope.$&lt;span class=&quot;hljs-built_in&quot;&gt;eval&lt;/span&gt;(attrs.colorPicker));

            ngModel.$render = &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
                elm.spectrum(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;set&amp;#x27;&lt;/span&gt;, ngModel.$viewValue || &lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;&amp;#x27;&lt;/span&gt;);
            };

            elm.spectrum(options);
        }
    };
});&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;See the &lt;a href=&quot;http://codepen.io/rinatio/pen/gwvBl&quot;&gt;Pen&lt;/a&gt; by Rinat (&lt;a href=&quot;http://codepen.io/rinatio&quot;&gt;@rinatio&lt;/a&gt;) on &lt;a href=&quot;http://codepen.io&quot;&gt;CodePen&lt;/a&gt;&lt;/p&gt;&lt;div&gt;&lt;script async src=&quot;//codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Now we can set an additional plugin
options in the &lt;code&gt;colorPicker&lt;/code&gt; attribute like this:
&lt;code&gt;&amp;lt;input color-picker=&amp;quot;{showInput: true}&amp;quot;&amp;gt;&lt;/code&gt;. Notice how they are getting extended
with &lt;code&gt;angular.extend&lt;/code&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[OOP Wrapper for Facebook Test Users API]]></title><description><![CDATA[Introducing OOP wrapper for Facebook test users API that allows to create, read, update and delete Facebook test users]]></description><link>https://rinat.io/blog/oop-wrapper-for-facebook-test-users-api</link><guid isPermaLink="false">https://rinat.io/blog/oop-wrapper-for-facebook-test-users-api</guid><dc:creator><![CDATA[mail@rinat.io (Rinat)]]></dc:creator><pubDate>Tue, 15 Oct 2013 00:00:00 +0000</pubDate><content:encoded>&lt;p&gt;If you have a tight Facebook integration in your project and
it&amp;#x27;s time for tests, there&amp;#x27;s a useful &lt;a href=&quot;https://developers.facebook.com/docs/test_users/&quot;&gt;test
users API&lt;/a&gt;
with a simple GUI as well as a programmatic access.&lt;/p&gt;&lt;p&gt;Since I worked on automatic testing with behat BDD framework,
I&amp;#x27;ve created a simple &lt;a href=&quot;https://github.com/rinatio/Facebook&quot;&gt;oop wrapper&lt;/a&gt;
with &lt;a href=&quot;/blog/guzzle&quot;&gt;Guzzle&lt;/a&gt; for their json API. It&amp;#x27;s easy to install and configure,
just use composer&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot;&gt;$ php composer.phar require --dev rinatio/Facebook:~0.1&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;then configure namespaces, set your Facebook application
&lt;a href=&quot;https://developers.facebook.com/docs/web/tutorials/scrumptious/register-facebook-application/&quot;&gt;credentials&lt;/a&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;hljs language-php&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;hljs-title&quot;&gt;rinatio&lt;/span&gt;\&lt;span class=&quot;hljs-title&quot;&gt;Facebook&lt;/span&gt;\&lt;span class=&quot;hljs-title&quot;&gt;Test&lt;/span&gt;\&lt;span class=&quot;hljs-title&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;hljs-title&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;hljs-title&quot;&gt;TestUser&lt;/span&gt;;
&lt;span class=&quot;hljs-keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;hljs-title&quot;&gt;rinatio&lt;/span&gt;\&lt;span class=&quot;hljs-title&quot;&gt;Facebook&lt;/span&gt;\&lt;span class=&quot;hljs-title&quot;&gt;Facebook&lt;/span&gt;;

Facebook::setAppId(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;fbAppId&amp;#x27;&lt;/span&gt;);
Facebook::setAppSecret(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;fbAppSecret&amp;#x27;&lt;/span&gt;);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and you&amp;#x27;re ready to go:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;hljs language-php&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;// create a user&lt;/span&gt;
$user = TestUser::create(&lt;span class=&quot;hljs-keyword&quot;&gt;array&lt;/span&gt;(
    &lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;name&amp;#x27;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;Jack Black&amp;#x27;&lt;/span&gt;
));
&lt;span class=&quot;hljs-keyword&quot;&gt;echo&lt;/span&gt; $user-&amp;gt;access_token;
&lt;span class=&quot;hljs-keyword&quot;&gt;echo&lt;/span&gt; $user-&amp;gt;login_url;

&lt;span class=&quot;hljs-comment&quot;&gt;// add a friend&lt;/span&gt;
$friend = TestUser::create(&lt;span class=&quot;hljs-keyword&quot;&gt;array&lt;/span&gt;(
    &lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;name&amp;#x27;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;John White&amp;#x27;&lt;/span&gt;
));
$user-&amp;gt;addFriend($friend);

&lt;span class=&quot;hljs-comment&quot;&gt;// Get full user profile&lt;/span&gt;
$user-&amp;gt;fetchProfile();
&lt;span class=&quot;hljs-keyword&quot;&gt;echo&lt;/span&gt; $user-&amp;gt;username;
&lt;span class=&quot;hljs-keyword&quot;&gt;echo&lt;/span&gt; $user-&amp;gt;gender;

&lt;span class=&quot;hljs-comment&quot;&gt;// Get all test users created in your app&lt;/span&gt;
$users = TestUser::all();

&lt;span class=&quot;hljs-comment&quot;&gt;// Delete a user&lt;/span&gt;
$user-&amp;gt;delete();

&lt;span class=&quot;hljs-comment&quot;&gt;// Or delete all of them&lt;/span&gt;
TestUser::deleteAll();&lt;/code&gt;&lt;/pre&gt;</content:encoded></item><item><title><![CDATA[Installing Bower Dependencies from Grunt]]></title><description><![CDATA[Adding simple grunt task to handle bower dependencies using bower's programmatic api instead of manually running bower install]]></description><link>https://rinat.io/blog/installing-bower-dependencies-from-grunt</link><guid isPermaLink="false">https://rinat.io/blog/installing-bower-dependencies-from-grunt</guid><dc:creator><![CDATA[mail@rinat.io (Rinat)]]></dc:creator><pubDate>Wed, 02 Oct 2013 00:00:00 +0000</pubDate><content:encoded>&lt;p&gt;If you use both bower and grunt
in your node.js project and you don&amp;#x27;t like to perform &lt;code&gt;bower install&lt;/code&gt; manually every time
while you already have a &lt;code&gt;grunt default&lt;/code&gt;, here&amp;#x27;s a simple task you can add to your &lt;code&gt;Gruntfile.js&lt;/code&gt; using
bower&amp;#x27;s &lt;a href=&quot;http://bower.io/#programmatic-api&quot;&gt;programmatic api&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;hljs language-javascript&quot;&gt;grunt.registerTask(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;bower&amp;#x27;&lt;/span&gt;, &lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;Install bower dependencies&amp;#x27;&lt;/span&gt;, &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;hljs-keyword&quot;&gt;var&lt;/span&gt; bower = &lt;span class=&quot;hljs-built_in&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;bower&amp;#x27;&lt;/span&gt;),
        done = &lt;span class=&quot;hljs-keyword&quot;&gt;this&lt;/span&gt;.async();
    bower.commands.install().on(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;log&amp;#x27;&lt;/span&gt;, &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;result&lt;/span&gt;) &lt;/span&gt;{
        grunt.log.writeln(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;bower &amp;#x27;&lt;/span&gt; + result.id + &lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27; &amp;#x27;&lt;/span&gt; + result.message);
    }).on(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;error&amp;#x27;&lt;/span&gt;, &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
        done(&lt;span class=&quot;hljs-literal&quot;&gt;false&lt;/span&gt;);
    }).on(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;end&amp;#x27;&lt;/span&gt;, &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;results&lt;/span&gt;) &lt;/span&gt;{
        done();
    });
});&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note that it has to be &lt;a href=&quot;http://gruntjs.com/creating-tasks#custom-tasks&quot;&gt;asynchronous&lt;/a&gt;.
Now you can add it into your default task:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;hljs language-javascript&quot;&gt;grunt.registerTask(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;default&amp;#x27;&lt;/span&gt;, [&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;bower&amp;#x27;&lt;/span&gt;, &lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;concat&amp;#x27;&lt;/span&gt;, &lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;uglify&amp;#x27;&lt;/span&gt;]);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And make sure you have bower in your npm dependencies:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot;&gt;npm install bower --save&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now you don&amp;#x27;t even need to install bower globally and you can run everything you need
with one &lt;code&gt;grunt&lt;/code&gt; command.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Guzzle]]></title><description><![CDATA[Meeting Guzzle, a wonderful PHP HTTP client & framework for building RESTful web service clients]]></description><link>https://rinat.io/blog/guzzle</link><guid isPermaLink="false">https://rinat.io/blog/guzzle</guid><dc:creator><![CDATA[mail@rinat.io (Rinat)]]></dc:creator><pubDate>Thu, 15 Aug 2013 00:00:00 +0000</pubDate><content:encoded>&lt;p&gt;I never liked to use php curl functions.
Consider this code which sends a simple POST request:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;hljs language-php&quot;&gt;$resource = curl_init(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;http://example.com&amp;#x27;&lt;/span&gt;);
curl_setopt($resource, CURLOPT_POST, &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;);
curl_setopt($resource, CURLOPT_POSTFIELDS, [&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;name&amp;#x27;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;value&amp;#x27;&lt;/span&gt;]);
curl_setopt($resource, CURLOPT_RETURNTRANSFER, &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;);
$response = curl_exec($resource);
curl_close($resource);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It is so unreadable and hard! And all those &lt;code&gt;curl_setopt&lt;/code&gt; constants...&lt;/p&gt;&lt;p&gt;But recently I discovered an amazing library with funny name: &lt;a href=&quot;http://guzzlephp.org/&quot;&gt;Guzzle&lt;/a&gt;.
It is so powerful and simple, I&amp;#x27;d like to use it everywhere. Here&amp;#x27;s a code for the same POST request
with Guzzle:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;hljs language-php&quot;&gt;Guzzle\Http\StaticClient::mount();
$response = Guzzle::post(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;http://example.com&amp;#x27;&lt;/span&gt;, [
    &lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;body&amp;#x27;&lt;/span&gt; =&amp;gt; [&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;name&amp;#x27;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;value&amp;#x27;&lt;/span&gt;]
])-&amp;gt;getMessage();&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Isn&amp;#x27;t it simple?&lt;/p&gt;&lt;p&gt;If you look at the &lt;a href=&quot;http://guzzlephp.org/docs.html&quot;&gt;documentation&lt;/a&gt; you
will find how flexible and powerful it is. It even
&lt;a href=&quot;http://guzzlephp.org/tour/http.html#send-http-requests-in-parallel&quot;&gt;allows&lt;/a&gt;
to send a parallel requests through &lt;code&gt;curl_multi_*&lt;/code&gt; functions. Guzzle is used by
&lt;a href=&quot;https://drupal.org/node/1862446&quot;&gt;Drupal&lt;/a&gt;
and other php libraries like
Amazon AWS &lt;a href=&quot;https://github.com/aws/aws-sdk-php&quot;&gt;SDK&lt;/a&gt; and &lt;a href=&quot;https://github.com/fabpot/Goutte&quot;&gt;Goutte&lt;/a&gt;.
Alright, try it yourself!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Deploying Yii Application with Capistrano]]></title><description><![CDATA[Automating Yii application deploy routine using ruby and capistrano gem]]></description><link>https://rinat.io/blog/yii-and-capistrano</link><guid isPermaLink="false">https://rinat.io/blog/yii-and-capistrano</guid><dc:creator><![CDATA[mail@rinat.io (Rinat)]]></dc:creator><pubDate>Fri, 12 Jul 2013 00:00:00 +0000</pubDate><content:encoded>&lt;p&gt;There&amp;#x27;s no standard solution to deploy a php application to a server.
Many developers have their own self written scripts or tools. If you&amp;#x27;re
looking for something simple and powerful, try &lt;a href=&quot;http://www.capistranorb.com/&quot;&gt;capistrano&lt;/a&gt;,
it&amp;#x27;s awesome.
It might be not so fast to learn and understand the flow of that tool,
but it&amp;#x27;ll be very very useful once you get it.
Even though it was originally written for ruby on rails, it isn&amp;#x27;t so hard to
adjust it for any other framework/language.&lt;/p&gt;&lt;p&gt;Let&amp;#x27;s consider simple example with yii/php application:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot;&gt;$ gem install capistrano
$ &lt;span class=&quot;hljs-built_in&quot;&gt;clone&lt;/span&gt; git@github.com:yiisoft/yii2-app-basic.git
$ &lt;span class=&quot;hljs-built_in&quot;&gt;cd&lt;/span&gt; yii2-app-basic/
$ capify .&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now you have a &lt;code&gt;Capify&lt;/code&gt; and &lt;code&gt;config/deploy.rb&lt;/code&gt; files in your app.
Copy &lt;a href=&quot;https://gist.github.com/rinatio/5980122&quot;&gt;this&lt;/a&gt; code sample into your &lt;code&gt;config.rb&lt;/code&gt;,
change &lt;code&gt;:user&lt;/code&gt;, &lt;code&gt;server&lt;/code&gt; settings, load composer and deploy your app:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot;&gt;$ curl -sS https://getcomposer.org/installer | php
$ git add .
$ git commit -m &lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;Added composer.phar and capistrano config&amp;#x27;&lt;/span&gt;
$ &lt;span class=&quot;hljs-built_in&quot;&gt;cap&lt;/span&gt; deploy:setup      &lt;span class=&quot;hljs-comment&quot;&gt;# prepare servers (create basic directory structure etc)&lt;/span&gt;
$ &lt;span class=&quot;hljs-built_in&quot;&gt;cap&lt;/span&gt; deploy:check      &lt;span class=&quot;hljs-comment&quot;&gt;# check if everything requred is installed (git for example)&lt;/span&gt;
$ &lt;span class=&quot;hljs-built_in&quot;&gt;cap&lt;/span&gt; deploy&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now setup your http server to look into correct directory. It would be
something like &lt;code&gt;/home/username/www/yii2-app-basic/current/www&lt;/code&gt; (notice &lt;code&gt;current&lt;/code&gt;).
And &lt;a href=&quot;http://yii2-app-basic.rinat.io/&quot;&gt;there we are&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Here&amp;#x27;re some useful links:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Deployment directory structure: &lt;a href=&quot;https://github.com/capistrano/capistrano/wiki/2.x-from-the-beginning#deployment-directory-structure&quot;&gt;wiki&lt;/a&gt;.
(we replaced &lt;code&gt;logs&lt;/code&gt;, &lt;code&gt;pids&lt;/code&gt;, &lt;code&gt;system&lt;/code&gt; with &lt;code&gt;www/assets&lt;/code&gt;, &lt;code&gt;runtime&lt;/code&gt;, &lt;code&gt;vendor&lt;/code&gt; in our case)&lt;/li&gt;&lt;li&gt;Original &lt;code&gt;deploy.rb&lt;/code&gt; code: &lt;a href=&quot;https://github.com/capistrano/capistrano/blob/master/lib/capistrano/recipes/deploy.rb&quot;&gt;deploy.rb&lt;/a&gt;&lt;/li&gt;&lt;li&gt;An explanation of default deployment behaviour: &lt;a href=&quot;https://raw.github.com/mpasternacki/capistrano-documentation-support-files/master/default-execution-path/Capistrano%20Execution%20Path.jpg&quot;&gt;picture&lt;/a&gt;
and &lt;a href=&quot;https://github.com/capistrano/capistrano/wiki/2.x-Default-Deployment-Behaviour&quot;&gt;wiki&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Still cannot figure out how to set up logger...&lt;/p&gt;&lt;p&gt;Also you can find more information about capistrano tasks with &lt;code&gt;cap -T&lt;/code&gt; or &lt;code&gt;cap -e deploy:setup&lt;/code&gt;.
Good luck!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Handling Yii Debug Mode]]></title><description><![CDATA[Different approaches to enable/disable Yii debug mode for specific server: 1. Using some special file 2. Using Yii environment config 3. Using server environment variable with nginx, apache]]></description><link>https://rinat.io/blog/handling-yii-debug-mode</link><guid isPermaLink="false">https://rinat.io/blog/handling-yii-debug-mode</guid><dc:creator><![CDATA[mail@rinat.io (Rinat)]]></dc:creator><pubDate>Thu, 20 Jun 2013 00:00:00 +0000</pubDate><content:encoded>&lt;p&gt;If you&amp;#x27;re working with Yii, you most probably
&lt;a href=&quot;http://www.yiiframework.com/doc/guide/1.1/en/basics.entry#debug-mode&quot;&gt;know&lt;/a&gt; what &lt;code&gt;YII_DEBUG&lt;/code&gt; constant
is and
you know that it should be disabled on production servers. Default Yii bootstrap just put a note
in &lt;code&gt;index.php&lt;/code&gt; saying that you should remove &amp;quot;define-yii-debug-true&amp;quot; line in production mode, but
how would you handle that? I&amp;#x27;ve seen few different approaches.&lt;/p&gt;&lt;h3&gt;Create specific file for debug mode&lt;/h3&gt;&lt;p&gt;It might be something like &lt;code&gt;debugmodeon&lt;/code&gt; in your project directory.
In your &lt;code&gt;index.php&lt;/code&gt; you check if that file exists or not and enable/disable debug accordingly.
This approch forces you to apply some VCS stuff, for example you
have to put &lt;code&gt;debugmodeon&lt;/code&gt; into &lt;code&gt;.gitignore&lt;/code&gt;.&lt;/p&gt;&lt;h3&gt;Put settings into environment config&lt;/h3&gt;&lt;p&gt;If you use an architecture like YiiBoilerplate
with different config for specific environment, you might put code to enable/disable
debug in those config files, but... In this case you should include that config before
Yii being included, otherwise Yii will define constant itself and you will get a notice
that &amp;quot;Constant &lt;code&gt;YII_DEBUG&lt;/code&gt; already defined&amp;quot;. So you have to either replace &lt;code&gt;CMap::mergeArray&lt;/code&gt;
with something else, or load &lt;code&gt;CMap&lt;/code&gt; class directly without Yii autoload.&lt;/p&gt;&lt;h3&gt;Use server environment variable&lt;/h3&gt;&lt;p&gt;In my opinion best approach is to use server environment variable (like &lt;code&gt;APPLICATION_ENV/RAILS_ENV&lt;/code&gt; in ZF/RoR). It&amp;#x27;s quite simple
and you don&amp;#x27;t have to handle &lt;code&gt;.gitignore&lt;/code&gt; or do some magic with configs.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;hljs language-php&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; (!defined(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;YII_DEBUG&amp;#x27;&lt;/span&gt;) &amp;amp;&amp;amp; getenv(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;YII_DEBUG&amp;#x27;&lt;/span&gt;)) {
    define(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;YII_DEBUG&amp;#x27;&lt;/span&gt;, &lt;span class=&quot;hljs-keyword&quot;&gt;true&lt;/span&gt;);
}
&lt;span class=&quot;hljs-comment&quot;&gt;// In apache:&lt;/span&gt;
&lt;span class=&quot;hljs-comment&quot;&gt;// SetEnv YII_DEBUG 1&lt;/span&gt;

&lt;span class=&quot;hljs-comment&quot;&gt;// Or nginx:&lt;/span&gt;
&lt;span class=&quot;hljs-comment&quot;&gt;// fastcgi_param YII_DEBUG 1;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can even set that value for whole server, and every project
will use it. The only drawback is that you have to know apache or nginx config
a little bit :)&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Click Events on Elements with CSS Transition]]></title><description><![CDATA[Investigating why click event doesn't get fired on HTML elements with CSS transition on :active state (like 3D buttons)]]></description><link>https://rinat.io/blog/click-event-on-elements-with-css-transition</link><guid isPermaLink="false">https://rinat.io/blog/click-event-on-elements-with-css-transition</guid><dc:creator><![CDATA[mail@rinat.io (Rinat)]]></dc:creator><pubDate>Thu, 06 Jun 2013 00:00:00 +0000</pubDate><content:encoded>&lt;p&gt;Yesterday I faced interesting issue: click event sometimes doesn&amp;#x27;t get fired
on html elements with css transition on &lt;code&gt;:active&lt;/code&gt; state. For instance button
with 3D push effect. In the example below try to click on the top edge of button
and you can find a place where counter won&amp;#x27;t be updated.&lt;/p&gt;&lt;pre class=&quot;codepen&quot; data-height=&quot;200&quot; data-type=&quot;result&quot; data-href=&quot;wFtKc&quot; data-user=&quot;rinatio&quot; data-safe=&quot;true&quot;&gt;&lt;code&gt;&lt;/code&gt;&lt;a href=&quot;http://codepen.io/rinatio/pen/wFtKc&quot;&gt;Check out this Pen!&lt;/a&gt;&lt;/pre&gt;&lt;p&gt;The issue become even worse if you have an html inside your button:&lt;/p&gt;&lt;pre class=&quot;codepen&quot; data-height=&quot;200&quot; data-type=&quot;result&quot; data-href=&quot;rCqpF&quot; data-user=&quot;rinatio&quot; data-safe=&quot;true&quot;&gt;&lt;code&gt;&lt;/code&gt;&lt;a href=&quot;http://codepen.io/rinatio/pen/rCqpF&quot;&gt;Check out this Pen!&lt;/a&gt;&lt;/pre&gt;&lt;p&gt;Very annoying. It took me a while to figure out and seems like
click event get fired only when you mousedown/mouseup on same html node.
I found very interesting
&lt;a href=&quot;http://css-tricks.com/video-screencasts/123-if-it-moves-when-you-click-make-something-stick/&quot;&gt;explanation and solution&lt;/a&gt;
by Chris Coyier. The trick is to add :after pseudoelement with absolute position and
proper left, right, top and bottom. Although Chris considered simple example without
html inside button that approach seems to work in thit case too:&lt;/p&gt;&lt;pre class=&quot;codepen&quot; data-height=&quot;200&quot; data-type=&quot;result&quot; data-href=&quot;FqGAC&quot; data-user=&quot;rinatio&quot; data-safe=&quot;true&quot;&gt;&lt;code&gt;&lt;/code&gt;&lt;a href=&quot;http://codepen.io/rinatio/pen/FqGAC&quot;&gt;Check out this Pen!&lt;/a&gt;&lt;/pre&gt;&lt;p&gt;Other way around is to use mouseup or mousedown event handlers instead of
click for such buttons.&lt;/p&gt;&lt;div&gt;&lt;script async src=&quot;//codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Hover Info Popup with CSS]]></title><description><![CDATA[Creating simple hover-info/hovercard popup with pure CSS]]></description><link>https://rinat.io/blog/css-hover-info</link><guid isPermaLink="false">https://rinat.io/blog/css-hover-info</guid><dc:creator><![CDATA[mail@rinat.io (Rinat)]]></dc:creator><pubDate>Fri, 24 May 2013 00:00:00 +0000</pubDate><content:encoded>&lt;p&gt;Last week I got a task to add hover info on some of our pages, like this:&lt;/p&gt;&lt;img src=&quot;static/1-6d2197728b1243a797bfdab04a5662f6.png&quot; alt=&quot;Hover info&quot;/&gt;&lt;p&gt;At first I was intended to use &lt;a href=&quot;http://designwithpc.com/Plugins/Hovercard&quot;&gt;jQuery hovercard&lt;/a&gt;
but seems like it supposed to work only for one line (one word) hovering. So I decided to
make it with pure css, and here&amp;#x27;s what I came up with:&lt;/p&gt;&lt;div&gt;&lt;pre class=&quot;codepen&quot; data-height=&quot;300&quot; data-type=&quot;result&quot; data-href=&quot;exEwF&quot; data-user=&quot;rinatio&quot; data-safe=&quot;true&quot;&gt;&lt;code&gt;&lt;/code&gt;&lt;a href=&quot;http://codepen.io/rinatio/pen/exEwF&quot;&gt;Check out this Pen!&lt;/a&gt;&lt;/pre&gt;&lt;div&gt;&lt;script async src=&quot;//codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;It&amp;#x27;s two divs with same rules for padding, border, shadow etc (left picture) and that&amp;#x27;s why
there&amp;#x27;re some side effects. For example if you set big blur radius for box shadow (right picture):&lt;/p&gt;&lt;table style=&quot;margin-bottom:0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;border-bottom:0&quot;&gt;&lt;img style=&quot;margin-bottom:0&quot; src=&quot;static/2-2a1f442428d79ef873537179ce2ab9b0.png&quot; alt=&quot;Hover info parts&quot; title=&quot;Hover info parts&quot;/&gt;&lt;/td&gt;&lt;td style=&quot;border-bottom:0&quot;&gt;&lt;img style=&quot;margin-bottom:0&quot; src=&quot;static/3-133bc8f72fbd5bc349903bcc9bdd3bab.png&quot; alt=&quot;Hover info box shadow&quot; title=&quot;Hover info box shadow side effect&quot;/&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;But it works alright in simplest cases, although it worth to apply a
transition here someday.&lt;/p&gt;&lt;p&gt;If you need to show info only on hovering part of visible text,
you will have to adjust css a bit and
use javascript to toggle some class name, for example:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;hljs language-javascript&quot;&gt;$(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;.hover-info&amp;#x27;&lt;/span&gt;).on(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;mouseenter mouseleave&amp;#x27;&lt;/span&gt;, &lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;h3&amp;#x27;&lt;/span&gt;, &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;e&lt;/span&gt;) &lt;/span&gt;{
    $(e.delegateTarget).toggleClass(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;hover&amp;#x27;&lt;/span&gt;, &lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;mouseenter&amp;#x27;&lt;/span&gt; == e.type);
});&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Have fun!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Cleaning Assets after Deploy]]></title><description><![CDATA[Cleaning Yii application assets with JavaScript, CSS and image files after deploy]]></description><link>https://rinat.io/blog/yii-cleaning-assets-after-deploy</link><guid isPermaLink="false">https://rinat.io/blog/yii-cleaning-assets-after-deploy</guid><dc:creator><![CDATA[mail@rinat.io (Rinat)]]></dc:creator><pubDate>Sun, 12 May 2013 00:00:00 +0000</pubDate><content:encoded>&lt;p&gt;If you use assets for your js, css stuff in yii application, you have
to re-publish it on deploy. And probably simplest way would be to delete everything
under &lt;code&gt;/path/to/public/www/assets&lt;/code&gt;. And we used to do that same way with
&lt;a href=&quot;https://github.com/clevertech/YiiBoilerplate&quot;&gt;YiiBoilerplate&lt;/a&gt;
deployer for example. Although it isn&amp;#x27;t quite right solution:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;If browser cached html page, the js/css tags in it still point to old directory
which you deleted.&lt;/li&gt;&lt;li&gt;If you built heavy javascript application (or even single page application)
which loads JS files on the fly, with &lt;a href=&quot;http://requirejs.org/&quot;&gt;require.js&lt;/a&gt; for example,
it won&amp;#x27;t be able to find those deleted files after deploy until you refresh the page.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;And you will have an errors like this in your log:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;hljs language-javascript&quot;&gt;[error] [exception.CHttpException&lt;span class=&quot;hljs-number&quot;&gt;.404&lt;/span&gt;] exception
&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;CHttpException&amp;#x27;&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;with&lt;/span&gt; message &lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;Unable to resolve the request
&amp;quot;assets/c7d87fdd/js/libs/jquery/jquery.min.js&amp;quot;.&amp;#x27;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So, what&amp;#x27;s a solution? Best way to clean assets I found so far is to
update modification time of assets directory with shell or php
&lt;code&gt;touch&lt;/code&gt; function, since &lt;code&gt;CAssetManager::publish&lt;/code&gt;
&lt;a href=&quot;http://www.yiiframework.com/doc/api/1.1/CAssetManager#publish-detail&quot;&gt;takes&lt;/a&gt;
hash name based on path and path mtime.&lt;/p&gt;&lt;p&gt;Although you won&amp;#x27;t have such issues when you publish file, not directory,
because modification time will be changed on content change.
But modification time of directory won&amp;#x27;t be updated unless you
added/deleted some files in there.&lt;/p&gt;&lt;p&gt;One more note: if you use some preprocessor like
&lt;a href=&quot;http://compass-style.org/&quot;&gt;compass&lt;/a&gt;
or &lt;a href=&quot;https://github.com/jrburke/r.js&quot;&gt;r.js&lt;/a&gt;,
don&amp;#x27;t forget to apply it before &amp;quot;touching&amp;quot; a directory
that has to be published.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Yii2 Preview and Composer]]></title><description><![CDATA[Yii2 public preview release review. Setting up Yii2 with composer]]></description><link>https://rinat.io/blog/yii2-preview-and-composer</link><guid isPermaLink="false">https://rinat.io/blog/yii2-preview-and-composer</guid><dc:creator><![CDATA[mail@rinat.io (Rinat)]]></dc:creator><pubDate>Sat, 04 May 2013 00:00:00 +0000</pubDate><content:encoded>&lt;p&gt;Great news -
&lt;a href=&quot;http://www.yiiframework.com/news/71/yii-2-public-preview-available/&quot;&gt;Yii2 in town&lt;/a&gt;!
I decided to spend some time and switch this
site for it. I use composer for dependencies and since Yii2 doesn&amp;#x27;t support it
yet I added repository definition by myself. Here&amp;#x27;s what I came up with:&lt;/p&gt;&lt;div&gt;&lt;script src=&quot;https://gist.github.com/rinatio/5979353.js&quot;&gt;&lt;/script&gt;&lt;/div&gt;&lt;p&gt;Since there&amp;#x27;s no documentation for Yii2 yet, upgrading was tricky sometimes.
&lt;a href=&quot;http://www.slideshare.net/samdark/alexander-makarov-yii2-whats-new&quot;&gt;This slideshare&lt;/a&gt;
helped me a lot. Also built in
&lt;a href=&quot;https://github.com/yiisoft/yii2-app-basic&quot;&gt;demo app&lt;/a&gt;
was very useful. Here&amp;#x27;re some notes:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Everything under namespaces (except &lt;code&gt;Yii&lt;/code&gt; and &lt;code&gt;YiiBase&lt;/code&gt; classes
which is questionable)&lt;/li&gt;&lt;li&gt;&lt;code&gt;$this&lt;/code&gt; isn&amp;#x27;t instance of current controller in views.
It&amp;#x27;s instance of &lt;code&gt;\yii\base\View&lt;/code&gt; class with bunch of
interesting methods like &lt;code&gt;beginPage, head, beginBody&lt;/code&gt; etc.
You still can access controller through &lt;code&gt;$this-&amp;gt;context&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Asset manager supports bundles that looks promising but I wasn&amp;#x27;t able
to figure out how to forcePublish them on development environment
and it doesn&amp;#x27;t have old &lt;code&gt;excludeFiles&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;You have to use &lt;code&gt;echo $this-&amp;gt;render(&amp;#x27;view&amp;#x27;)&lt;/code&gt; in controller
actions&lt;/li&gt;&lt;li&gt;For rendering partials in view you can use
&lt;code&gt;echo $this-&amp;gt;render(&amp;#x27;_partial&amp;#x27;)&lt;/code&gt;
which is the same as
&lt;code&gt;echo $this-&amp;gt;context-&amp;gt;renderPartial(&amp;#x27;_partial&amp;#x27;)&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Still cannot figure out how to set up logger...&lt;/p&gt;&lt;p&gt;I haven&amp;#x27;t spent too much time playing with it, so I might be wrong somewhere.
Definitely a lot of stuff was changed and a lot of stuff will be changed,
and it certainly looks interesting and surely going to be fun!&lt;/p&gt;&lt;p&gt;UPD: They needed 3 days, now you can download yii2 from
&lt;a href=&quot;https://packagist.org/packages/yiisoft/yii&quot;&gt;packagist&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;P.S.: &lt;a href=&quot;https://github.com/rinatio/yii2.init&quot;&gt;Here&amp;#x27;s&lt;/a&gt;
a simple yii2 kickstart app on github. Comments are welcome!&lt;/p&gt;</content:encoded></item></channel></rss>