2018年6月20日 星期三

[Gulp] browser sync


  gulp    Browser sync  


Introduction


We will use gulp and browser-sync to make the browsers refresh after modify specify files, like javascript or CSS.


Environment


gulp.js 3.9.1
browser-sync 2.24.4


Implement


Install packages


$ npm install gulp --save-dev

$ npm install browser-sync --save-dev



gulpfile.js


// BrowserSync serve
gulp.task('serve', function () {

    browserSync.init({
        host: 'http://localhost:7777',
        browser: ["google chrome", "firefox", "iexplore"],
        open: "local",
        //port: 3000,
        files: ["wwwroot/css/**/*.css", "wwwroot/js/**/*.js"]
    });
});

gulp.task("default", ["serve"]);




Embed the browser-sync initial js on master page

Copy and paste the following js in the master page.

<script id="__bs_script__">
          //<![CDATA[
          document.write("<script async src='http://HOST:3000/browser-sync/browser-sync-client.js?v=2.24.4'><\/script>".replace("HOST", location.hostname));
          //]]>
      </script>



Reference



2018年6月18日 星期一

2018 南方莊園&卡司蒂菈樂園 輕旅行


週五下班後很臨時安排了這次的輕旅行。 地點則為上次偶然來參加集訓南方莊園及上網找到評價不錯的金格崎蛋糕觀光工廠 卡司.蒂菈樂園

我們中午從台北出發,路上小塞一下大約一個小時後抵達南方莊園,記得入住飯店前可先在外面大街採買一些零食。

另外櫃台旁邊有一個親子活動的時刻表,建議先拍照及安排一下,以免錯過活動時間。


飯店的Check-in/out時間分別為15:0011:00,我們寄放行李後就先到外面大草原玩風箏和小朋友的遊樂器具;風箏、傳接球等一些兒童玩物需要到B1押房卡(若尚未Check-in則押證件)租借。










夏日剛好有一個滑水道的活動,是從約三樓高的山坡滑水道溜下去,小莉亞看到一直說想玩,我心裡想這你玩一次就怕了吧! 結果果不其然換完泳衣去玩一次他就不敢玩了,反而是我多玩了一次,嘿嘿。



飯店內有兒童遊戲場、游泳池、水療池和健身房。 兒童遊戲場規劃得很不錯,大人可以舒服地靠著休息,小朋友可以一群一群找到專屬的位置一起遊玩,比較不會有奔跑或碰撞的情況; 也可以排隊開開小車,大小孩和大人也可以去旁邊打撞球、桌球。












游泳池忘了拍,裡面有三個大型浮具(獨角獸、海豚、比薩),也有小溜滑梯,我們玩了兩個小時才起來。

房間(家庭房)的部分,有小朋友的鹽洗用具,也可另外請飯店準備嬰兒床和澡盆。 另外室內有一大一小泡湯池,電視可轉到泡湯池觀看,非常的舒服,只不過少了浴室用的小椅子墊腳,身高100公分的小莉亞無法自己打開洗手台的水龍頭;建議可請飯店準備一下。

另外房間的隔音並不好,不過基本上因為入住的大部分為家庭,所以應該不是太大問題。



餐飲的部分算是中規中矩,因為我不吃海鮮(生魚片或蝦子之類),所以算是還滿對我胃口;另外牛肉相當好吃。




結束了南方莊園的行程,我們就驅車去拜訪剛新婚不久的朋友,然後前往金格崎蛋糕觀光工廠 卡司.蒂菈樂園





為什麼會來這裡呢? 因為這邊有一個必參加的點心DIY課程。 每段時間的DIY是不一樣的,但是看起來成品都很有趣(好吃)






小莉亞認真的做作品中







完成!!



我猜這兩位應該就是卡司和蒂菈?!



四樓有一個小型的碰碰車,需另外購買代幣遊玩。




離開前當然要買一些伴手禮啦! 太久沒吃長崎蛋糕,沒想到多出來這麼多口味。 (又忘了拍…)


兩天的輕旅行充電一下,接下來就準備迎戰放暑假了 lol




2018年6月14日 星期四

[Vue] Custom plugin for getting i18n data with vue-i18n (2)


  Vue.js    vue-i18n     Plugins 


Introduction


In previous article, [Vue] Custom plugin for getting i18n data with vue-i18n (1), we created a plugin to make vue-i18n get the backend’s i18n json data.
In this tutorial, we will improve the plugin to support getting multiple i18n data from backend with keys. For example, the plugin will send a HttpGet request to

http://xxxxx/api/i18n/Get?lang=en-US&keys=key1,key2,key3

which will get the following response data:


{"key1": {"A":"Hello", "B":"world"}, "key2": {"C":"Vue.js", "D":"is awesome"}}




Environment


vue.js 2.5.13
vue-i18n 7.4.2
ASP.NET Web API 2



Implement


Update Web API to support multiple keys response

We had an ASP.NET Web API action for responding the i18n json data in this article: [Vue] Internationalization with vue-i18n

Let’s modify it to make it support multiple keys query.

[HttpGet]
[Route("api/i18n/Get")]
public async Task<HttpResponseMessage> Get(string keys, string lang)
{
            CultureInfo ci = new CultureInfo(lang);

            var keyArr = keys.Split(',');
            dynamic expando = new ExpandoObject();
           
            foreach (string key in keyArr)
            {
                var resource = ResourceFactory.GetResource(key, ci); //Get the key-value pairs as Dictionary<string, string>
                addProperty(expando, key, resource);
            }

            string json = JsonFactory.SerializeObjectToCamelJson(expando);
            var response = this.Request.CreateResponse(HttpStatusCode.OK);
            response.Content = new StringContent(json, Encoding.UTF8, "application/json");
            return response;
        }

        private void addProperty(ExpandoObject expando, string propertyName, object propertyValue)
        {
            // ExpandoObject supports IDictionary so we can extend it like this
            var expandoDict = expando as IDictionary<string, object>;
            if (expandoDict.ContainsKey(propertyName))
                expandoDict[propertyName] = propertyValue;
            else
                expandoDict.Add(propertyName, propertyValue);
}

Here we use ExpandoObject to create a dynamic object since Web API don’t know what keys will be sent.
(Reference: [C#] ExpandoObject)




Modify the Vue plugin

All we have to do is make the plugin read the keys from the Vue instance’s property and send the request with keys.

JS (plugin)

Take a look at the modified part of the plugin.

Vue.mixin({
            created: function () {
                if (this.i18nKey) {
                    let keys = this.i18nKey;
                    let getEnUS = this.getI18n(keys, 'en-US');
                    let getZhTW = this.getI18n(keys, 'zh-TW');
                    let getZhCN = this.getI18n(keys, 'zh-CN');

                    this.$i18nPromise = axios.all([getEnUS, getZhTW, getZhCN])
                        .then(axios.spread(function (response1, response2, response3) {
                            i18n.setLocaleMessage('enUS', response1.data);
                            i18n.setLocaleMessage('zhTW', response2.data);
                            i18n.setLocaleMessage('zhCN', response3.data);
                            i18n.locale = Vue.prototype.$locale;
                        }));
                }
            }
)

We get the keys from this.i18nKeys, which will be set in the Vue instance, and getI18n(keys, 'en-US') will send the request like http://xxxxx/api/i18n/Get?lang=en-US&keys=key1,key2,key3

A full version is as following,

Vue.use(VueI18n);

// Create VueI18n instance with options
const i18n = new VueI18n({
    locale: '', // set locale
    fallbackLocale: 'zhTW',
});

const serverUrl = "http://xxxx/api/i18n/Get";

var MyPlugin = {
    install: function (Vue, options) {

        //If Vue instance use i18n data immediately, such as in created, mounted, then you have to use this promise
        Vue.prototype.$i18nPromise = null;

        /* Instance method */
        Vue.prototype.getI18n = function (keys, lang) {
let uri = serverUrl.concat("?lang=", lang, "&keys=" , keys);
            return axios.get(uri);
        }

        // Vue.mixin() for injecting functionality into all components.
        Vue.mixin({
            created: function () {
                if (this.i18nKeys) {
                    let keys = this.i18nKeys;
                    let getEnUS = this.getI18n(keys, 'en-US');
                    let getZhTW = this.getI18n(keys, 'zh-TW');
                    let getZhCN = this.getI18n(keys, 'zh-CN');

                    this.$i18nPromise = axios.all([getEnUS, getZhTW, getZhCN])
                        .then(axios.spread(function (response1, response2, response3) {
                            i18n.setLocaleMessage('enUS', response1.data);
                            i18n.setLocaleMessage('zhTW', response2.data);
                            i18n.setLocaleMessage('zhCN', response3.data);
                            i18n.locale = Vue.prototype.$locale;
                        }));
                }
            },
            methods: {
               
            }

           
        });
    }
};



Use the plugin

Now we can use the plugin in the Vue instance like this,



Vue.use(MyPlugin);

var app = new Vue({
    el: '#app',
    i18n: i18n,
    data: {
        //Load i18n
        i18nKeys: 'Key1, Key2, Key3',
    },
    methods: {
    },
    created: function () {
        this.locale = 'zhTW';
    },
})





Reference