diff --git a/botanjs/src/Astro/Blog/AstroEdit/SmartInput/CandidateAction/ArticleReference.js b/botanjs/src/Astro/Blog/AstroEdit/SmartInput/CandidateAction/ArticleReference.js
new file mode 100644
index 00000000..a87f8fe2
--- /dev/null
+++ b/botanjs/src/Astro/Blog/AstroEdit/SmartInput/CandidateAction/ArticleReference.js
@@ -0,0 +1,61 @@
+(function ()
+{
+	var ns = __namespace( "Astro.Blog.AstroEdit.SmartInput.CandidateAction" );
+
+	/** @type {System.utils.IKey} */
+	var IKey                             = __import( "System.utils.IKey" );
+	/** @type {System.utils.DataKey} */
+	var DataKey                          = __import( "System.utils.DataKey" );
+	/** @type {Dandelion.IDOMElement} */
+	var IDOMElement                      = __import( "Dandelion.IDOMElement" );
+	/** @type {Dandelion} */
+	var Dand                             = __import( "Dandelion" );
+	/** @type {Astro.Blog.Config} */
+	var Config                           = __import( "Astro.Blog.Config" );
+
+	var getData                          = __import( "System.Net.getData" );
+	var prettyDate                       = __import( "Astro.utils.Date.pretty" );
+
+	/** @type {_AstConf_.AstroEdit} */
+	var Conf = Config.get( "AstroEdit" );
+
+	/** @type {Astro.Blog.AstroEdit.SmartInput.ICandidateAction} */
+	var ArticleRefs = function ( visualizer, key )
+	{
+		this.visualizer = visualizer;
+		this.key = key;
+		this.__cands = {};
+	};
+
+	ArticleRefs.prototype.GetCandidates = function( handler )
+	{
+		var _self = this;
+		getData( Conf.paths.list_articles, function( e ) {
+			e = JSON.parse( e );
+
+			for( var i in e.entries )
+			{
+				var ent = e.entries[i];
+				_self.__cands[ ent.title ] = { "desc": ent.content, id: ent.id };
+			}
+
+			handler( _self.__cands );
+		} );
+	};
+
+	ArticleRefs.prototype.Process = function( key )
+	{
+		var cand = this.__cands[ key ];
+		if( !cand ) return false;
+
+		this.visualizer.insertSnippet( "articlelink", { value: cand.id } );
+		return true;
+	};
+
+	ArticleRefs.prototype.Retreat = function( sender, e )
+	{
+		return sender.value == "" && e.keyCode == 8; // Backspace
+	};
+
+	ns[ NS_EXPORT ]( EX_CLASS, "ArticleReference", ArticleRefs );
+})();
diff --git a/botanjs/src/Astro/Blog/AstroEdit/SmartInput/CandidateAction/Heading.js b/botanjs/src/Astro/Blog/AstroEdit/SmartInput/CandidateAction/Heading.js
index 22620ab3..aea1df35 100644
--- a/botanjs/src/Astro/Blog/AstroEdit/SmartInput/CandidateAction/Heading.js
+++ b/botanjs/src/Astro/Blog/AstroEdit/SmartInput/CandidateAction/Heading.js
@@ -20,7 +20,7 @@
 
 	Heading.prototype.GetCandidates = function( handler )
 	{
-		return null;
+		handler( false );
 	};
 
 	Heading.prototype.Process = function( content )
diff --git a/botanjs/src/Astro/Blog/AstroEdit/SmartInput/_this.js b/botanjs/src/Astro/Blog/AstroEdit/SmartInput/_this.js
index 284810e2..35169ba5 100644
--- a/botanjs/src/Astro/Blog/AstroEdit/SmartInput/_this.js
+++ b/botanjs/src/Astro/Blog/AstroEdit/SmartInput/_this.js
@@ -248,7 +248,7 @@
 					// No candidates, directly pass the input text to the processor
 					if( ModLevels.Cands().Empty && 1 < ModLevels.length )
 					{
-						ModLevels.Action()( sender.value );
+						ModLevels.Action()( sender.value.substr( 1 ) );
 						sender.BindingBox.close();
 						break;
 					}
@@ -258,7 +258,8 @@
 					if( selected )
 					{
 						insert = undefined;
-						ModLevels.Action()( selected.getDAttribute( "key" ) );
+						var close = ModLevels.Action()( selected.getDAttribute( "key" ) );
+						if( close ) sender.BindingBox.close();
 					}
 					else
 					{
@@ -386,7 +387,7 @@
 			{
 				stage( Candidates );
 				title( true );
-				stage()[0].value = "";
+				stage()[0].value = "`";
 				stage()[0].setAttribute( "placeholder", ModLevels.Cands().desc );
 			}
 		};
@@ -454,7 +455,7 @@
 	var MasterInput = function( visualizer )
 	{
 		var Cands = {
-			"Article Reference": { module: "ArticleReference", desc: "Article reference link" }
+			"Article Reference": { module: "ArticleReference", desc: "Links to other article" }
 			, "facts": { module: "Facts", desc: "Facts, a fact bubble popup when mouseover" }
 			, "footnote": { module: "Footnote", desc: "Footnote, a footnote displayed at the end of article" }
 			, "h1": { module: "Heading", options: 1, desc: "Heading, size 1" }
@@ -478,11 +479,14 @@
 			var module = new ( __import( e ) )( visualizer, sender );
 
 			var ModItem = Cands[ sender ];
-			InputBox.advanceLevel(
-				new Candidates( ModItem.module, ModItem.desc, module.GetCandidates() )
-				, module.Process.bind( module )
-				, module.Retreat.bind( module )
-			);
+
+			module.GetCandidates( function( x ) {
+				InputBox.advanceLevel(
+					new Candidates( ModItem.module, ModItem.desc, x )
+					, module.Process.bind( module )
+					, module.Retreat.bind( module )
+				);
+			} );
 		};
 
 		var BackQuoteBinding = function ( sender, e )
diff --git a/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/ArticleLink.css b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/ArticleLink.css
new file mode 100644
index 00000000..f158a390
--- /dev/null
+++ b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/ArticleLink.css
@@ -0,0 +1,9 @@
+.v_boundary[data-type="ArticleLink"]:before {
+	content: "[";
+}
+.v_boundary[data-type="ArticleLink"] {
+	color: #f15a24;
+}
+.v_boundary[data-type="ArticleLink"]:after {
+	content: "]";
+}
diff --git a/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/ArticleLink.js b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/ArticleLink.js
new file mode 100644
index 00000000..5d1398a1
--- /dev/null
+++ b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/ArticleLink.js
@@ -0,0 +1,175 @@
+(function ()
+{
+	var ns = __namespace( "Astro.Blog.AstroEdit.Visualizer.Snippet" );
+
+	/** @type {System.utils.IKey} */
+	var IKey                              = __import( "System.utils.IKey" );
+	/** @type {System.utils.DataKey} */
+	var DataKey                           = __import( "System.utils.DataKey" );
+	/** @type {Dandelion.IDOMElement} */
+	var IDOMElement                       = __import( "Dandelion.IDOMElement" );
+	/** @type {Dandelion} */
+	var Dand                              = __import( "Dandelion" );
+	/** @type {Components.MessageBox} */
+	var MessageBox                        = __import( "Components.MessageBox" );
+	/** @type {Astro.Blog.Config} */
+	var Config                            = __import( "Astro.Blog.Config" );
+	/** @type {System.utils.Perf} */
+	var Perf                              = __import( "System.utils.Perf" );
+	/** @type {Astro.utils.Date} */
+	var XDate                             = __import( "Astro.utils.Date" );
+
+	var escapeStr = ns[ NS_INVOKE ]( "escapeStr" );
+	var compileProp = ns[ NS_INVOKE ]( "compileProp" );
+
+	var postData = __import( "System.Net.postData" );
+
+	/** @type {_AstConf_.AstroEdit} */
+	var config = null;
+
+	var ArticleLink = function ( insertSnippet, snippetWrap, createContext, override )
+	{
+		config = Config.get( "AstroEdit" );
+		if( !config ) throw new Error( "config is not defined" );
+
+		var temp, i, j
+
+		, handler = function ()
+		{
+			// Input fields
+			var v_snippetInput = Dand.wrap( "input", null, "v_snippet_input_single", null, new IKey( "type", "text" ) )
+				, input_title = Dand.wrap( "input", null, "v_snippet_input_single", null, new IKey( "type", "text" ) )
+				;
+
+			if ( this._stage )
+			{
+				v_snippetInput.value = this._id;
+				input_title.value = this._title;
+			}
+
+			// Popup MessageBox
+			new MessageBox(
+				"Insert site file"
+				, Dand.wrape([
+					Dand.wrapc( "v_instruction", "Article id:" )
+					, v_snippetInput
+					, Dand.wrapc( "v_instruction", "Title override:" )
+					, input_title
+				])
+				, "OK", "Cancel"
+				, visualizer.bind({
+					id: v_snippetInput
+					, title: input_title
+					, stage: this._stage
+				})
+			).show();
+		}
+
+		, visualizer = function ( submitted, override )
+		{
+
+			var id, stage = this.stage;
+
+			if( override )
+			{
+				id = override.value;
+				title = override.title || "";
+			}
+			else
+			{
+				id = this.id.value;
+				title = this.title.value;
+			}
+
+			if ( submitted && id )
+			{
+				// Visualize component
+				if (!stage)
+				{
+					temp =  Dand.wrapne( "span"
+						, title || "ArticleLink[" + id + "]"
+						, [
+							new DataKey( "value", id )
+							, new DataKey( "title", title )
+						]
+					);
+
+					insertSnippet(
+						j = snippetWrap( "ArticleLink", temp, false, "span" )
+						, !!override
+					);
+				}
+				else
+				{
+					stage.firstChild.textContent = title || "ArticleLink[" + id + "]";
+
+					IDOMElement( stage ).setAttribute([
+						new DataKey( "value", id )
+						, new DataKey( "title", title )
+					]);
+				}
+
+				// Get the default title if not defined
+				if( !title )
+				{
+					postData(
+						config.paths.get_article
+						, { article_id: id }
+
+						/** @param {_AstJson_.AJaxGetArticle} */
+						, function( e )
+						{
+							j.firstChild.textContent = e.entry.title;
+						}
+						, function()
+						{
+							j.firstChild.textContent = "ArticleLink[ ERROR ]";
+						} );
+				}
+
+				i = {
+					_id: id
+					, _title: title
+					, _stage: temp
+				};
+
+				// Set context menu
+				createContext( i, j, handler );
+
+			}
+		};
+
+		if ( override )
+		{
+			visualizer( true, override );
+			override = false;
+		}
+		else
+		{
+			return handler;
+		}
+		return true;
+
+	};
+
+	var compile = function ( stage )
+	{
+		stage = IDOMElement( stage );
+		var options = "";
+		var opt;
+
+		if( opt = stage.getDAttribute( "title" ) )
+		{
+			options += " title=\"" + opt + "\"";
+		}
+
+		return "[articlelink" + options + "]"
+			+ escapeStr( stage.getDAttribute( "value" ) )
+			+ "[/articlelink]";
+	};
+
+	__static_method( ArticleLink, "compile", compile );
+
+	ns[ NS_EXPORT ]( EX_CLASS, "ArticleLink", ArticleLink );
+
+})();
diff --git a/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Link.css b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Link.css
new file mode 100644
index 00000000..6d1c0231
--- /dev/null
+++ b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Link.css
@@ -0,0 +1,3 @@
+.v_boundary[data-type="Link"] {
+	color: #f15a24;
+}
diff --git a/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Link.js b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Link.js
index 3fe3c5bd..0d776b98 100644
--- a/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Link.js
+++ b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Link.js
@@ -20,8 +20,8 @@
 		, handler = function ()
 		{
 			// Input fields
-			var input_text = Dand.wrap('input', null, "v_snippet_input_single", null, new IKey("type", "text"))
-			, input_a = Dand.wrap('input', null, "v_snippet_input_single", null, new IKey("type", "text"));
+			var input_text = Dand.wrap("input", null, "v_snippet_input_single", null, new IKey("type", "text"))
+			, input_a = Dand.wrap("input", null, "v_snippet_input_single", null, new IKey("type", "text"));
 			
 			if (this._stage)
 			{
@@ -69,13 +69,13 @@
 					
 					// Visualize component
 					temp =  
-						Dand.wrapne('span', src
+						Dand.wrapne("span", src
 							, [
 								new DataKey("value", src)
 								, new DataKey("href", href)
 							]
 						);
-					insertSnippet(j = snippetWrap("Link", temp, false, 'span'), Boolean(override));
+					insertSnippet(j = snippetWrap("Link", temp, false, "span"), Boolean(override));
 				}
 				else
 				{
diff --git a/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/SiteFile.js b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/SiteFile.js
index 073bbe4b..adc7fc5e 100644
--- a/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/SiteFile.js
+++ b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/SiteFile.js
@@ -241,7 +241,6 @@
 	var compile = function ( stage )
 	{
 		stage = IDOMElement( stage );
-		// [html][/html]
 		var options = "";
 		var opt;
 		if( opt = stage.getDAttribute( "collection" ) )
diff --git a/botanjs/src/Astro/Blog/AstroEdit/Visualizer/_this.js b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/_this.js
index 8941ac13..a771c025 100644
--- a/botanjs/src/Astro/Blog/AstroEdit/Visualizer/_this.js
+++ b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/_this.js
@@ -27,17 +27,18 @@
 	var Config                                  = __import( "Astro.Blog.Config" );
 
 	var snippetList = IKey.quickDef(
-		  "Code"       , "background: white; color: cornflowerblue;"
-		, "Image"      , "background: #ff0084;"
-		, "Sound"      , "background: YellowGreen;"
-		, "Video"      , "background: Crimson;"
-		, "Spoiler"    , "background: cornflowerblue;"
-		, "Swf"        , "background: #333;"
-		, "Link"       , "background: blue;"
-		, "AcquireLib" , "background: black;"
-		, "Html"       , "background: coral;"
-		, "SiteFile"   , "background: royalblue;"
-		, "Heading"    , ""
+		  "Code"         , "background: white; color: cornflowerblue;"
+		 , "Image"       , "background: #ff0084;"
+		 , "Sound"       , "background: YellowGreen;"
+		 , "Video"       , "background: Crimson;"
+		 , "Spoiler"     , "background: cornflowerblue;"
+		 , "Swf"         , "background: #333;"
+		 , "Link"        , "background: blue;"
+		 , "AcquireLib"  , "background: black;"
+		 , "Html"        , "background: coral;"
+		 , "SiteFile"    , "background: royalblue;"
+		 , "Heading"     , ""
+		 , "ArticleLink" , ""
 	);
 
 	var snippetNs = "Astro.Blog.AstroEdit.Visualizer.Snippet.";
diff --git a/botanjs/src/externs/_AstConf_.AstroEdit.js b/botanjs/src/externs/_AstConf_.AstroEdit.js
index ac4fddb8..0f8e6e42 100644
--- a/botanjs/src/externs/_AstConf_.AstroEdit.js
+++ b/botanjs/src/externs/_AstConf_.AstroEdit.js
@@ -9,6 +9,8 @@ _AstConf_.AstroEdit.paths = {};
 	/** @type {string} */
 	_AstConf_.AstroEdit.paths.get_article;
 	/** @type {string} */
+	_AstConf_.AstroEdit.paths.list_articles;
+	/** @type {string} */
 	_AstConf_.AstroEdit.paths.get_drafts;
 	/** @type {string} */
 	_AstConf_.AstroEdit.paths.get_files;