對上一次介紹ASP.NET的Free Hosting已經是幾年前 - (2009年1月11日 - 免費的ASP.NET網頁空間),幾年前那一番說話:( 其實Free ASP.NET Hosting真是少之有少,你在Google找遍全世界都可能找不到超過10個。 )
到今天,依然有效。
今天再度整理一下現在的免費空間,只著眼於比較主要的項目,排名不分先後 :
網頁
▼
2012年5月30日星期三
2012年5月29日星期二
7-Zip 換新裝 - 7-Zip Theme Manager
幾日前轉貼 - 電腦軟件《ZIP》背後原來包含一個鮮為人知的悲劇,90年代未期,eDonkey,Pub FTP興起,大多數Warez,Moviez都是Rar...r01..r02的分割檔案發放,造就WinRAR取代WinZIP,但時至今日,其實WinRAR都不好過,有很多開源/免費軟件已經慢慢侵占佔有率。
7-Zip大家當然聽過亦用過,但無奈介面實在非常嘔心,表面好像是Windows 98時代產物,而作者似乎多年來從未有想過搞一搞介面的Icon,所以有一段時間我轉用了PeaZip,但PeaZip亦過於複雜,起動時間慢,資料夾內的檔案雜亂無章,最後我還是用回7-Zip,而其中一個原因就是7-Zip終於可以靠第三方軟件去修改介面圖示或Windows檔案圖示了。
7-Zip Theme Manager
http://www.7ztm.de/
這個軟件其實是一個Patch檔,修改7-Zip的exe去替換圖示。
我已經用了幾個月,沒有什麼問題。
經修改後的7-Zip顯然有返一點時代感。
有多款圖示給你選擇,其實任何一款都一定比原版的好看,所以用7-Zip的人可以試用下。
7-Zip大家當然聽過亦用過,但無奈介面實在非常嘔心,表面好像是Windows 98時代產物,而作者似乎多年來從未有想過搞一搞介面的Icon,所以有一段時間我轉用了PeaZip,但PeaZip亦過於複雜,起動時間慢,資料夾內的檔案雜亂無章,最後我還是用回7-Zip,而其中一個原因就是7-Zip終於可以靠第三方軟件去修改介面圖示或Windows檔案圖示了。
7-Zip Theme Manager
http://www.7ztm.de/
這個軟件其實是一個Patch檔,修改7-Zip的exe去替換圖示。
我已經用了幾個月,沒有什麼問題。
經修改後的7-Zip顯然有返一點時代感。
有多款圖示給你選擇,其實任何一款都一定比原版的好看,所以用7-Zip的人可以試用下。
2012年5月22日星期二
2012年5月20日星期日
電腦軟件《ZIP》背後原來包含一個鮮為人知的悲劇
ZIP 背後是一個沒落天才的故事,Phil Katz 不願意為一個壓縮軟件付錢,因此索性自己編寫一個更好的算法,然後免費公開,但他於 2000 年 4 月 14 日被發現死於一家汽車旅館,年僅 37 歲,死時手中握著一個空酒瓶……
一堆免費的BBCode Web Editor
作為高登巴打一份子,經常都會轉載網上的文字,純文字的話還好,如果連帶多張圖片的話,不可能一張一張去補上BBCode的[IMG] Tag。
我之前的習慣就會利用HotEditor - HTML網頁轉換至Forum BBCode工具,但HotEditor的官網Demo有時候很慢,所以上網看看,有沒有其他選擇,最後找到4個不錯的。
很有名的TinyMCE w/ BBCode Plugin
http://www.tinymce.com/tryit/bbcode.php
跟上者同樣出名的CKEditor w/ BBCode Plugin
http://nightly.ckeditor.com/latest/ckeditor/_samples/bbcode.html
再來兩個小品:
SCEditor – A WYSIWYG HTML & BBCode editor
http://www.samclarke.com/2011/07/sceditor/
Demo
WYSIWYG BBCode Editor
http://wysiwygbbcode.codeplex.com/
我之前的習慣就會利用HotEditor - HTML網頁轉換至Forum BBCode工具,但HotEditor的官網Demo有時候很慢,所以上網看看,有沒有其他選擇,最後找到4個不錯的。
很有名的TinyMCE w/ BBCode Plugin
http://www.tinymce.com/tryit/bbcode.php
跟上者同樣出名的CKEditor w/ BBCode Plugin
http://nightly.ckeditor.com/latest/ckeditor/_samples/bbcode.html
再來兩個小品:
SCEditor – A WYSIWYG HTML & BBCode editor
http://www.samclarke.com/2011/07/sceditor/
Demo
WYSIWYG BBCode Editor
http://wysiwygbbcode.codeplex.com/
2012年5月15日星期二
Blogger Recent Posts by jQuery / Ajax / JSONP
之前已經貼過的Recent Comments,當然不會少得Recent Posts。
Demo : http://webapp.heliohost.org/html/blogger_recent_posts_json.htm
使用方法都是一樣很簡單 :
如果你的Template並未加入jQuery,請去設計 / 修改 HTML / 修改範本中,把以下程式碼放在<head>與</head>之間。
然後在Blogger新增一個HTML/Javascript小工具,然後把下面的程式碼貼上後,再儲存就完成。
大家使用前,需要去調整一下設定 :
maxcount (line 18) - 最多文章顯示數目。
maxlength (line 19) - 長度多於這個值時,用"..."代替。
feedURL (line 48) - 換上你blogger的ID。
樣式方面,大家可以自行去修改。
Demo : http://webapp.heliohost.org/html/blogger_recent_posts_json.htm
使用方法都是一樣很簡單 :
如果你的Template並未加入jQuery,請去設計 / 修改 HTML / 修改範本中,把以下程式碼放在<head>與</head>之間。
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"> </script>
然後在Blogger新增一個HTML/Javascript小工具,然後把下面的程式碼貼上後,再儲存就完成。
大家使用前,需要去調整一下設定 :
maxcount (line 18) - 最多文章顯示數目。
maxlength (line 19) - 長度多於這個值時,用"..."代替。
feedURL (line 48) - 換上你blogger的ID。
樣式方面,大家可以自行去修改。
<script type="text/javascript"> var BloggerFunctions = { getPosts : function(feedURL) { var paras = { alt : 'json-in-script' }; $.ajax({ url : feedURL, type : 'GET', dataType : "jsonp", success : BloggerFunctions.onGotPostData, data : paras }); }, //Parse the JSON post data returned by the Google Blogger API onGotPostData : function(data) { var maxcount = 10; var maxlength = 20; var feed = data.feed; var entries = feed.entry || []; var title = ""; var content = ""; var url = ""; var published = ""; var cnt = 0; var html = ""; for(var i = 0; i < entries.length; ++i) { var entry = entries[i]; var title = entry.title.$t; //var content = entry.content.$t; var url = entry.link[4].href; var published = entry.published.$t.substring(0,10); html += "<a href='" + url +"'><span style='font-family:Arial;color:#333;font-size:11px;font-weight:bold;'>" + "[" + published + "] " + (title.length > maxlength ? title.substring(0, maxlength) + '...' : title) + " </span></a><br />"; cnt++; if(cnt == maxcount) break; } var dom = $(html); $('#recent_posts').append(dom); } } $(document).ready(function() { var feedURL = "http://tatmingstudio.blogspot.com/feeds/posts/default"; BloggerFunctions.getPosts(feedURL); }); </script> <div id="recent_posts"></div>
2012年5月14日星期一
Aptana Studio 3 安裝 PHP xDebug
自從Aptana Studio 3重新加入PHP開發功能後,我幾乎已經完全用它取代了Eclipse PDT。
Aptana Studio 3很多地方都要比PDT或另一免費的PHP IDE - Netbeans強,但到目前為止Aptana唯一失色的地方就是沒有PHP Debugger。
幸好Aptana團隊自3.0版本開始十分積極,差不多一個月有一次更新。預計v3.2.0版本就會支援Zend Debugger 和 xDebug了。
而PHP Debugger亦隨著nightly build公開下載,貼一下安裝攻略。
首先第一樣要做,當然是更新至Nightly Build的Aptana Studio 3,或者有人擔心用Nightly會不穩定,但我親身試用了5個月Nightly Build,沒有任何問題,只是提示更新比較頻密而已。
我自己是用xDebug的,其實設定上比Netbeans或其他商業IDE更要下點功夫,但都跟PDT大同小異。
至於怎樣設置xDebug,可以參考下文 : Configure Eclipse PDT / XDebug for PHP debugging
唯一要注意的是在Debug Configurations中,是否需要使用URL/Auto Generate? 又是否需要Path Mapping?
好像我的情況就要取消Auto Generate URL和自行設定Path Mapping了。
送上一些圖給大家參考一下吧。
Aptana Studio 3很多地方都要比PDT或另一免費的PHP IDE - Netbeans強,但到目前為止Aptana唯一失色的地方就是沒有PHP Debugger。
幸好Aptana團隊自3.0版本開始十分積極,差不多一個月有一次更新。預計v3.2.0版本就會支援Zend Debugger 和 xDebug了。
而PHP Debugger亦隨著nightly build公開下載,貼一下安裝攻略。
首先第一樣要做,當然是更新至Nightly Build的Aptana Studio 3,或者有人擔心用Nightly會不穩定,但我親身試用了5個月Nightly Build,沒有任何問題,只是提示更新比較頻密而已。
安裝
- 前往Preferences,打開Install/Updates,選擇Available Software Sites。
- 按Add,Name位置輸入Aptana Studio Nightly Updates,Location輸入http://preview.appcelerator.com/aptana/studio3/standalone/update/nightly/,緊記要選取CheckBox才算是完成,之後按OK退出Preferences。
- 前往Help,按Check for updates,此時應該會見到3.2.0.xxxx版本了,之後安裝完成,重新開啟Aptana(很重要!)。
- 然後前往Aptana的IssueTracker Sitehttps://jira.appcelerator.org/browse/APSTUD-769,下載Attachments - com.aptana.php.debug.site.zip,把它放到Aptana安裝目錄的plugins資料夾之中。
- 再次前往Preferences,打開Install/Updates,選擇Available Software Sites,按Add,Name位置輸入PHP Debugger,Location按Archive按鈕,選取剛下載回來的com.aptana.php.debug.site.zip,跟之前一樣,要選取CheckBox,然後按OK退出,安裝完成,重新開啟Aptana
- 重新啟動後,可以打開Preferences/Aptana Studio/Editors/PHP,看看有沒有Debug選項,有的話就大功告成。
我自己是用xDebug的,其實設定上比Netbeans或其他商業IDE更要下點功夫,但都跟PDT大同小異。
至於怎樣設置xDebug,可以參考下文 : Configure Eclipse PDT / XDebug for PHP debugging
唯一要注意的是在Debug Configurations中,是否需要使用URL/Auto Generate? 又是否需要Path Mapping?
好像我的情況就要取消Auto Generate URL和自行設定Path Mapping了。
送上一些圖給大家參考一下吧。
2012年5月8日星期二
為何.NET叫.NET?
若你在Google搜尋的話,便發現很多人都有同一個疑問 - Why was .NET called .NET?。
.NET這個名稱,既不Search Engine family,作為Logo/Domain中的一員,又因為那一個Dot - "."太細小或字眼問題,要轉成Dot或放大那一點。
雖然時至今日大家都叫慣叫熟,但我都覺得應該可以有更好的命名。
剛剛又看到一名國外Blogger寫有關的文章 - Why was .NET called .NET?
最多人認同的答案在StackOverFlow - Why was .NET called .NET?
.NET enabled Microsoft's marketing people to emphasise the "Network"-ing aspect of its technologies, and was also a reaction to the marketing blitz by Sun Microsystems in the late 1990s whose theme was "The network is the computer". The term "Dot-Com" was synonymous with the Internet that time, and "Dot-NET" was a play on that term.或多或少我都同認的,90年代正值Internet發展年代,叫".NET",有點意識流,令人感覺.NET Framework不單是Offline本機的技術,而是關聯到Internet。
2012年5月5日星期六
Build Blogger Recent Comments by jQuery / Ajax / JSONP
用上Blogger後,試用一下Google提供的小工具。
使用最近留言(Recent Comments)和最近文章(Recent Posts)幾乎是Blog站的指定部件。
Google提供的小工具是由第三方 - Blogger Buster 製作的。
但可惜廢得可憐,因為是透過iframe呈現,又不能自定樣式,而且最不能接受的是連Trackback都包含在內,又不能把我自己的回應去掉。
上Google搜尋,有很多都隨著Google API的更新不能用,或者是我不能理解的做法。
最後當然又是自己動手做,但出師不利,前幾天就遇到問題 - jQuery Cross-Domain Ajax w/XML = NO WAY!
所以唯有轉用JSONP方式,參考了以下文件。
現在大家在右手邊的Sidebar看到的最近留言就是了。
Demo : http://webapp.heliohost.org/html/blogger_recent_comments_json.htm
使用方法很簡單,
如果你的Template並未加入jQuery,請去設計 / 修改 HTML / 修改範本中,把以下程式碼放在<head>與</head>之間。
然後在Blogger新增一個HTML/Javascript小工具,然後把下面的程式碼貼上後,再儲存就完成。
大家使用前,需要去調整一下設定 :
maxcount (line 29) - 最多留言顯示數目。
minlength (line 30) - 長度多於這個值才顯示。
maxlength (line 31) - 長度多於這個值時,用"..."代替。
exclude_name (line 32) - 過濾字。
feedURL (line 69) - 換上你blogger的ID。
樣式方面,大家可以自行去修改。
使用最近留言(Recent Comments)和最近文章(Recent Posts)幾乎是Blog站的指定部件。
Google提供的小工具是由第三方 - Blogger Buster 製作的。
但可惜廢得可憐,因為是透過iframe呈現,又不能自定樣式,而且最不能接受的是連Trackback都包含在內,又不能把我自己的回應去掉。
上Google搜尋,有很多都隨著Google API的更新不能用,或者是我不能理解的做法。
最後當然又是自己動手做,但出師不利,前幾天就遇到問題 - jQuery Cross-Domain Ajax w/XML = NO WAY!
所以唯有轉用JSONP方式,參考了以下文件。
- Using JSON in the Google Data Protocol
- Simple example of retrieving JSON feeds from Blogger Data API
現在大家在右手邊的Sidebar看到的最近留言就是了。
Demo : http://webapp.heliohost.org/html/blogger_recent_comments_json.htm
使用方法很簡單,
如果你的Template並未加入jQuery,請去設計 / 修改 HTML / 修改範本中,把以下程式碼放在<head>與</head>之間。
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"> </script>
然後在Blogger新增一個HTML/Javascript小工具,然後把下面的程式碼貼上後,再儲存就完成。
大家使用前,需要去調整一下設定 :
maxcount (line 29) - 最多留言顯示數目。
minlength (line 30) - 長度多於這個值才顯示。
maxlength (line 31) - 長度多於這個值時,用"..."代替。
exclude_name (line 32) - 過濾字。
feedURL (line 69) - 換上你blogger的ID。
樣式方面,大家可以自行去修改。
<script type="text/javascript"> function contains(arr, obj) { for(var i = 0; i < arr.length; i++) { if(arr[i].toLowerCase() == obj.toLowerCase() && arr[i].length == obj.length) return true; } } if( typeof String.prototype.startsWith != 'function') { String.prototype.startsWith = function(str) { return this.indexOf(str) == 0; }; } var BloggerFunctions = { getComments : function(feedURL) { var paras = { alt : 'json-in-script' }; $.ajax({ url : feedURL, type : 'GET', dataType : "jsonp", success : BloggerFunctions.onGotCommentData, data : paras }); }, //Parse the JSON comment data returned by the Google Blogger API onGotCommentData : function(data) { var maxcount = 10; var minlength = 10; var maxlength = 20; var exclude_name = new Array("達MiNG"); var feed = data.feed; var entries = feed.entry || []; var title = ""; var content = ""; var url = ""; var authorname = ""; var published = ""; var cnt = 0; var html = ""; for(var i = 0; i < entries.length; ++i) { var entry = entries[i]; var title = entry.title.$t; var content = entry.content.$t; var url = entry.link[2].href; var authorname = entry.author[0].name.$t; var published = entry.published.$t.substring(0,10); if(!contains(exclude_name, authorname) && !content.startsWith('[...]') && title.length >= 10) { html += "<span style='font-family:Arial;color:#333;font-size:11px;font-weight:bold;'>" + "["+ published + "] " +authorname + " 說 : </span><br />" + "<span style='font-family:Arial;color:#666;font-size:11px;'>" + "<a href='" + url + "'>" + (content.length > maxlength ? content.substring(0, maxlength) + '...' : content) + "</a></span>" + "<br /><br />"; cnt++; } if(cnt == maxcount) break; } var dom = $(html); $('#recent_comments').append(dom); } } $(document).ready(function() { var feedURL = "http://tatmingstudio.blogspot.com/feeds/comments/default"; BloggerFunctions.getComments(feedURL); }); </script> <div id="recent_comments"></div>
2012年5月3日星期四
jQuery Cross-Domain Ajax w/XML = NO WAY!
今天製作Blogger小工具時,原以為會很順利的。
上Google Blogger API Reference Guide看到可以用GET方式得到Comments的XML。
當然二話不說,打開Aptana Studio立即工作。
基於jQuery Ajax,不到一小時已經搞定,在本機試行,沒有問題。
沾沾自喜地心想: (那會難得到我?)
那就把程式碼Copy & Paste至Blogger的HTML/JavaScript小工具,儲存,看一看。
OMFG~竟然什麼都沒有,打開IE9的F12 Developer Tool看看出現大概是這樣的Error。
根據一些討論區答案,解決方法是轉用JSONP,因為Google API 伺服器不支援CORS (Cross-origin resource sharing)。
其實Google API 既有提供JSON,jQuery亦可以解讀,當然問題其實老早已解決。
但我就是有點不服氣,深入理解一下CORS。
按照網上的高手建議,
可以在Http Headers (PHP/ASP.NET)或jQuery Ajax中加入:
之後又有人建議對jQuery設定
當然統統試過都沒有用,因為主導權是在Server那邊,要是好像Google般不容許Cross-Domain Request的話,無論如何在Headers出什麼古惑都沒有用。
以下就是我的Blogger Recent Comments的XML版本。
http://webapp.heliohost.org/html/blogger_recent_comments.htm
Save As另存新檔後,在本機用Browser打開,是沒有問題的。
但在線上看,就會出現我說的問題。
當然現在問題已經解決,我已經轉用JSONP方式去實現。
上Google Blogger API Reference Guide看到可以用GET方式得到Comments的XML。
當然二話不說,打開Aptana Studio立即工作。
基於jQuery Ajax,不到一小時已經搞定,在本機試行,沒有問題。
沾沾自喜地心想: (那會難得到我?)
那就把程式碼Copy & Paste至Blogger的HTML/JavaScript小工具,儲存,看一看。
OMFG~竟然什麼都沒有,打開IE9的F12 Developer Tool看看出現大概是這樣的Error。
XMLHttpRequest cannot load XXX.上Google搜尋一下,原來是Google防止Cross-Domain Request帶出的問題。
Origin XXX is not allowed by Access-Control-Allow-Origin.
根據一些討論區答案,解決方法是轉用JSONP,因為Google API 伺服器不支援CORS (Cross-origin resource sharing)。
其實Google API 既有提供JSON,jQuery亦可以解讀,當然問題其實老早已解決。
但我就是有點不服氣,深入理解一下CORS。
按照網上的高手建議,
可以在Http Headers (PHP/ASP.NET)或jQuery Ajax中加入:
Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET, POST, PUT, DELETE Access-Control-Allow-Headers: Authorization
之後又有人建議對jQuery設定
$.support.cors = true; crossDomain: true;
當然統統試過都沒有用,因為主導權是在Server那邊,要是好像Google般不容許Cross-Domain Request的話,無論如何在Headers出什麼古惑都沒有用。
以下就是我的Blogger Recent Comments的XML版本。
http://webapp.heliohost.org/html/blogger_recent_comments.htm
Save As另存新檔後,在本機用Browser打開,是沒有問題的。
但在線上看,就會出現我說的問題。
當然現在問題已經解決,我已經轉用JSONP方式去實現。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>blogger_recent_comments</title> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script type="text/javascript"> function contains(arr, obj) { for(var i = 0; i < arr.length; i++) { if(arr[i].toLowerCase() == obj.toLowerCase() && arr[i].length == obj.length) return true; } } if( typeof String.prototype.startsWith != 'function') { String.prototype.startsWith = function(str) { return this.indexOf(str) == 0; }; } $(document).ready(function() { var feedurl = "http://www.blogger.com/feeds/880240131395666753/comments/default"; var maxcount = 10; var minlength = 10; var exclude_name = new Array("達MiNG"); $.support.cors = true; $.ajax({ type : "GET", url : feedurl, dataType : "xml", crossDomain : true, headers : { "GData-Version" : "2" }, success : function(responseData, textStatus, jqXHR) { var cnt = 0; var html = ""; $(responseData).find('entry').each(function() { var title = $(this).find("title").text(); var content = $(this).find('content').text(); var url = $(this).find("link[rel='alternate']").attr('href'); var authorname = $(this).find("author").find('name').text(); if(!contains(exclude_name, authorname) && !content.startsWith('[...]') && title.length >= 10) { html += "<span style='font-family:Arial;color:#333;font-size:11px;font-weight:bold;'>" + authorname + " 說 : </span><br />" + "<span style='font-family:Arial;color:#666;font-size:11px;'>" + title + "</span><br /><br />"; cnt++; } if(cnt == maxcount) return false; }); var dom = $(html); $('#recent_comments').append(dom); }, error : function(responseData, textStatus, errorThrown) { console.log(textStatus); } }); }); </script> </head> <body> <div id="recent_comments"></div> </body> </html>