Just in Chronicles

Life as a Voyage

Archive for the ‘For Web’ Category

Setting Up Classic ASP Websites on IIS 7.5 with Visual Studio 2010

with 12 comments

There are still many websites built and maintained with classic ASP because of many reasons. This post will cover two topics – how to setup classic ASP websites on IIS 7.5 and how to manage codes using Visual Studio 2010.


  • OS: Windows 7 Professional SP1
  • Web Server: IIS 7.5
  • IDE: Visual Studio 2010 Professional SP1

I haven’t tested it any other than above. So, if you have a little bit different environment from mine, please bear in mind.

How to Setup Classic ASP Websites on IIS 7.5

Firstly, your IIS must turn on ASP features. Go to Control Panel > Programs and Features > Turn Windows features on or off. Then, tick the checkbox next to ASP and click OK.


Now, your IIS is able to run ASP websites. The next step is that your IIS needs a new Application Pool for the ASP websites. Go to Control Panel > Administration Tools and open Internet Information Services (IIS) Manager. Then create a new Application Pool.



Make sure that an administrator account as a Custom account for the Application Pool Identity must be selected. From the diagram above, Administrator is selected.

Once the new Application Pool is added, a new website using this Application Pool needs to be created to host classic ASP pages.


A new website for classic ASP is now created. It’s time for the website to recognise ASP script. Go to the website you’ve just created and find ASP item under the IIS section. Click it and set the below four to “TRUE“.


Once you finish the steps above, your classic ASP website should be up and running. This IIS setting also helps your Visual Studio 2010 debug the web page script.

Now, it’s time for Visual Studio 2010 to setup to manage the classic ASP codes.

How to Manage Classic ASP Codes Using Visual Studio 2010

In order for your VS 2010 to manage the classic ASP codes, three things must be done before starting to code.

First of all, register .asp file extension to your VS 2010.


This enables you to see syntax highlighting and code intellisence feature. Now, open the website by clicking File > Open Web Site…. Make sure that it’s “File System“, not anything else.



Depending on your preference, create a new solution and add a new website project under the solution. By doing so, the website will be more manageable.

Now, it’s time to create a web page. Create a new item and select an HTML Page. As a default, the filename will be HTMLPage.htm. Rename it to default.asp.



A new default.asp page is created. Type some classic ASP code into the page.


As we have already setup the syntax highlighting and code intellisense feature, in order to enjoy them, put the code <%@ Language="VBScript" %> at the first line and you will see the result like above.

Open your web browser and open the page you just created.


Please note that you can see the break point at the left next to the line number. That means we can also debug the classic ASP codes. As usual, in order to utilise the debug functions, you have to run VS 2010 as an administrator privilege. Before starting to debug, the website property must be configured.


As VS built-in web server doesn’t support classic ASP, we have to use our local IIS for debug. So, setup the property like above. And use “Attach to Process” from the Debug menu. Once you run the “Attach to Process” command, you’ll get the screen like below. Find w3wp.exe bound by the account that we setup on IIS previously (that is Administrator here in this post).


Now, try to run the website again and you’ll get the break point highlighted.


So far, we have setup and reviewed how to set up classic ASP website to run on IIS 7.5 and code it on VS 2010. By default, classic ASP is not chosen by IIS and VS 2010. So, some configuration change must be performed in order for that.

Try it and enjoy your ASP coding.

Written by Justin Yoo

12/12/2012 at 15:48

How to Install the Latest Version of Mercurial Web Repository on Windows 2008 Server R2

with 6 comments

It’s a super pain to install HG on Windows 2008 Server R2. This post is based on Firegarden’s article and has additional information from other resources.


  • Windows 2008 Server R2
  • The latest version of Python: 2.7.3 (at the moment of writing)
  • The latest version of PyWin32: Build 217 (at the moment of writing)
  • The latest version of Mercurial: 2.2.2 (at the moment of writing)

Setup Process

Please note that if your choice of Python has to be consistent. In other words, if you choose Python of x86 version, all other applications have to be x86 version; if you choose Python of x64 version, all other applications have to be x64 version; otherwise, this will not be working for your system.

1. Installing Python.

As Mercurial doesn’t support Python 3.x, the latest version of Python we can use is 2.7.x.

  1. Go to the Python download page. http://www.python.org/download/releases
  2. Download the latest 2.7.x version of Python. Choose the platform carefully, if to be x86 or x64.
  3. Install Python downloaded. Make sure that the installation must be conducted by an administrator permission. During the installation process, let the installer set the default installation directory, which will be C:\Python2x.
  4. Add the Python path to the system environment path.
    1. Open “Control Panel” > “System and Security” > “System” > “Advanced System Settings
    2. Click “Environment Variables...” and find the “Path” variable under “System variables” section.
    3. Append “;C:\Python2x;” to the “Path” value. Make sure that the path value is delimited by semi-colons.
    4. Open a command prompt and type “python” at any directory and you will get into the python console. Press CTRL+Z to exit from the console.
    5. If you can’t run the “python” command on the command prompt, check the step 4.3 again. If the path has been correctly set, your server might need to reboot.

2. Installing PyWin32

Again, your choice of platform has to be consistant; if you have installed Python of x86 version, this also has to be x86 version; if you have installed Python of x64 version, this also has to be x64 version.

  1. Go to the Python for Windows Extensions download page. http://sourceforge.net/projects/pywin32/files/pywin32
  2. Go to the latest build and download an appropriate one corresponding to your Python version and platform. The filename looks like “pywin32-xxx.win32-py2.7.exe”
  3. Install the PyWin32 downloaded. Make sure that the installation must be conducted by an administrator permission.
  4. In case of error you might face at the end of the installation process. The message will look like:

    close failed in file object destructor:
    sys.excepthook is missing
    lost sys.stderr

    This is because of your administrator permission. For workaround of this: http://sourceforge.net/mailarchive/message.php?msg_id=29300152

    1. Click “Start Menu” > Right click on “Computer” > Click “Manage“.
    2. Go to “System Tools” > “Local Users and Groups” > “Users
    3. Create a new account named “Admin” and assign it to the “Administrators” group.
    4. Open a command prompt as an administrator and type

      runas /user:Admin pywin32-xxx.win32-py2.7.exe

      and type password you set previously.

    5. If you get an error “Access is denied“, close the command prompt and open it again as an administrator.

3. Building and Installing Mercurial from the Source Code.

As the latest version of Mercurial installer (2.2.2 at the moment of writing) is built with Python 2.6.6, the installer will not be running on our server. So, we need to build the source with Python that we have installed into our system.

  1. Go to the Mercurial download page. http://mercurial.selenic.com/downloads
  2. Download the source code and unzip it. We assume that the unzipped directory is “C:\hg-source“.
  3. Open a command prompte as an administrator and move to the unzipped directory.
  4. Run the following command to build Mercurial

    python setup.py --pure build_py -c -d . build_ext -i build_mo --force

    Even if you meet a warning like “warning: hgbuildmo: could not find msgfmt executable, no translations will be built“, just ignore it.

  5. Run the following command to install Mercurial

    python setup.py --pure install --force

    Mercurial will have been installed at “C:\Python2x\Lib\site-packages\mercurial

  6. In order to execute to “hg” command at anywhere, try the followings:
    1. Copy “c:\python2x\scripts\hg.bat” to “c:\python2x
    2. Open hg.bat and modify the line

      "%~dp0..\python" "%~dp0hg" %*


      "%~dp0python" "%~dp0\scripts\hg" %*

4. Installing ISAPI-WSGI Module

For better performance, we need to install ISAPI-WSGI module to build a DLL file.

  1. Go to the ISAPI-WSGI download page. http://code.google.com/p/isapi-wsgi/downloads/list
  2. Download the latest version of the source code. The precompiled version will not work for our setup.
  3. Unzip it. We assume that the unzipped directory is “C:\isapi-wsgi-source“.
  4. Run the following command to compile the source

    python setup.py install

5. Seting up IIS for the Mercurial Web Repository

As IIS doesn’t recognise Python and Hg natively, we need to setup IIS manually.

  1. Open IIS Manager.
  2. Create an application pool called “Mercurial” with the following configurations:
    1. Set “.NET Framework Version” to “No Managed Code
    2. Set “Enable 32-Bit Applications” to “True“, only if you have installed x86 version of Python.
  3. Create a website on IIS for the web repository. We assume that the directory is “C:\inetpub\hg” and its URL is “hg.myserver.com“. This has to point the application pool “Mercurial“.
  4. Copy the “hgwebdir_wsgi.py” file from the Mercurial source code downloaded to “C:\inetpub\hg“. It is located in “C:\hg-source\contrib\win32“.
  5. Open the “hgwebdir_wsgi.py“, find and edit the parameters below:

    hgweb_config = r'c:\inetpub\hg\hgweb.config'
    path_prefix = 0

  6. Create a new “hgweb.config” file in “C:\inetpub\hg” and place the following into it.

    / = c:\Repositories\*

  7. Open a command prompt as an administrator and move to the directory “C:\inetpub\hg“.
  8. Run the following command to build the ISAPI-WSGI library.

    python hgwebdir_wsgi.py

  9. Open Handler Mappings and click “Add Wildcard Script Map...” with followings:
    1. Set “Executable” to “c:\inutpub\hg\_hgwebdir_wsgi.dll” that has been created from the step 5.8.
    2. Set “Name” to “Mercurial-ISAPI“.
    3. If you are asked to allow the ISAPI extension, click “YES“.

So far, if everything is done smoothly, you can browse the web repository by typing the URL “http://mg.myserver.com” into your brower’s lcation bar.

This is optional. If you want to tie basic authentication function to the web repository, try the following steps.

6. Setting up Basic Authentication of IIS onto the Web Repository

  1. Create users and a user group.
    1. Click “Start Menu” > Right click on “Computer” > Click “Manage“.
    2. Go to “System Tools” > “Local Users and Groups” > “User Groups
    3. Create a user group, named “Mercurial Users
    4. Go to “System Tools” > “Local Users and Groups” > “Users
    5. Create as many users as you want and assign the users to the “Mercurial Users” group.
  2. Set the permission for the “Mercurial Users” group to only allow the access to “C:\inetpub\hg“.
  3. Create a self-signed certificate and bind the HTTPS protocol with “hg.myserver.com“.

Once everything is done, type “https://hg.myserver.com” and you will be asked to login to the site.

It would be great if you guys who are reading this article share your experiences regardless of success or failure.

Written by Justin Yoo

02/07/2012 at 18:16

When Getting 404 Error While Using FancyBox 1.3.4 jQuery Plugin

leave a comment »

According to the article http://stackoverflow.com/questions/6591288/im-getting-404-errors-with-fancybox-images, there are 404 errors occur while using the FancyBox 1.3.4 jQuery plugin. I had the exact same errors and, because of this, my IIS has almost gone down to write server error logs.

In order to fix this issue, without modifying the plugin core, simply add the URL rewrite rule into your web.config.

				<rule name="Fancybox image path correction" stopProcessing="true">
						- the page URL is http://yoursite.com/contents/pagename.html
						- the 404 error happens when the server tries to access to http://yoursite.com/contents/fancybox/image_file_name.png
						- FancyBox jQuery plugin is located under /scripts/jquery.fancybox-1.3.4
					<match url="^contents/fancybox/(.+).png$" />
					<action type="Rewrite" url="/scripts/jquery.fancybox-1.3.4/fancybox/{R:1}.png" />

Node that this is just a workaround, not the solution. The best thing is modifying the plugin core.

Written by Justin Yoo

10/05/2012 at 12:37

Posted in For Web

Tagged with , ,

Confirm Password vs Confirm Email

leave a comment »

During the signup process at a certain website, candidates are usually required to fill username, password and email at least. Traditionally, in order to avoid typing wrong password, a “Password Confirm” field has been used so far. It doesn’t let users only confirm their password, also let them make sure how they put their correct password and remember it easily.

Nowadays, a lot of websites do not request users to confirm their password while signing up. The reason is that additional field to fill in hurts user experiences. According to Munroe, It takes more time for users to complete the action and, as a result, the website will lose the users retention. That sounds very reasonable. “Forgot Password” function is to support users who forgot their password when they don’t remember the one.

Well, then there is another issue arising. How can we assure if users put their correct email address? If they put misspelled email address, the password reset email or authentication email will not be sent to the user. Website developer cannot guarantee if the users type the correct ones or not.

Of course, keeping the “Password Confirm” field won’t help users enter correct password. Instead, Appleseed argues in his article that we need to provide “Email Confirm” field to make users sure to put correct email address. Appleseed ends his post with:

A misspelled password is annoying. A misspelled e-mail address is hazardous.

If I am asked to put additional field, I’ll rather choose the extra “Email Confirm” field as the quotation above. If I can, I will not put any extra field but email and password (optionally username or nickname).

How do you guys think of this?

Written by Justin Yoo

14/03/2012 at 10:29

How to Get URL Hash Programmatically with Javascript

leave a comment »

URL hash is not part of official URL fragments (RFC 2396), but is widely used for page navigation purposes. As this is not a part of web standards, even though most web browsers support this, there is no way to pass this value to server-side scripts, unless Javascript helps.

<script type="text/javascript">
	(function ($) {
		$(document).ready(function () {
			//	Appends the URL hash, if exists.
			var hash = window.location.hash;
			$("div.pagination a").each(function (i) {
				//var href = $(this).attr("href") + hash;
				$(this).attr("href", $(this).attr("href") + hash);
			});	//	$.each
		}); //	$.ready

Let’s see the Javascript code above. The highlighted line is the key to get the hash URL. With this approach, we can easily get the hash URL and append it to any anchor tag programmatically.

Written by Justin Yoo

08/03/2012 at 17:06

Posted in For Web

Tagged with ,

Javascript Error: functionName() is not a function

Reference: In my Javascript I keep getting “submit is not a function”. What did I do?

Developers often meet a javascript error that says “functionName() is not a function”, even though functionName() is the actual function and coded correctly. That message usually comes up when functionName() is not defined.

How come does this happen? There is a secret. Shhhh~

	onclick="javascript:btnCheck();" />

	onclick="javascript:checkSomething();" />

As seen above, there are two button controls. ID, name and onclick attribute on the first control are the same as each other. While as, the name attribute on the second control, is different from the onclick attribute.

The first one will not work and the second one will work. This is the secret. When an HTML tag calls javascript, the function name must be different from the control’s ID and name; otherwise it displays the error “functionName() is not a function”.

This is pretty basic understanding of using javascript. But sometimes developers overlook the basic. Let’s back to basic! 🙂

Written by Justin Yoo

28/09/2009 at 06:31

Posted in For Web

Tagged with ,

Capturing TAB Keystroke with Javascript in Web Browsers


Users on the Web don’t only use mouse for navigation, but also use their keyboard for fast and quick browsing. As a simple example, once they visit Google and type a keyword in the textbox, then they press the Enter key, rather than clicking the “Search” button. As another example, they use the TAB key to navigate menus.

These user actions sometimes cause unexpected results. Before the web 2.0 era, developers simply ignored these actions or prevented them from keyboard typing navigation. However, nowadays all user actions are allowed as far as they don’t break the web site, in terms of “user experience” or “usability”, or sometimes “accessibility”.

Therefore, developers need to identify what users do in a particular situation and prepare its reaction. Identifying the TAB keystroke is one of them.

Assuming that there are fields to be filled and validated before a certain transaction. When users enter nothing and press the TAB key, developers expect an error message appears and stay focused on the field. However, in our reality, regardless of the validation result, the focus moves onto the next field. That’s not what developers expect. In order for users to stay focused on the field, therefore, the following javascript code might be useful.

function checkTabKey(obj, e)
	var charCode = null;
	if ("which" in e) // NN4 & FF & Opera
		charCode = e.which;
	else if ("keyCode" in e) // Safari & IE4+
		charCode = e.keyCode;
	else if ("keyCode" in window.event) // IE4+
		charCode = window.event.keyCode;
	else if ("which" in window.event) // Other browsers support events
		charCode = window.event.which;
		alert("the browser doesn't support");
	if (charCode == 9)
		setTimeout("document.getElementById(\"" + obj.id + "\").focus()", 1);

First of all, the code identifies what key has been typed. The keystroke event is stored in a different place, depending on browser types, so we need to detect it. Then, leave the focus to move onto the next field. After that, by using the setTimeOut() method, the focus is set back to the first field that the TAB key is typed.

That’s it for the TAB key detection. Let’s play with this!

자바스크립트로 탭키 잡아내는 방법. 탭키를 잡아내도 다음 필드로 이동하는 것을 막을 수가 없었지만, setTimeOut() 메서드를 이용하면 시간차로 잡아낼 수 있다.

Written by Justin Yoo

08/09/2009 at 01:13

Vertically Aligning Text Using CSS, CSS를 활용한 텍스트 수직정렬

References: Understanding vertical-align or How (Not) To Vertically Center Content

For navigation or layout purpose, navigation text needs to be vertically centred. According to the web standard, vertical-align property is responsible for that. However, in practice, it doesn’t work properly and even though it works, it requires other settings and hacks, which I hate it.

Well, there is a simple approach to vertically centre the single line text. It doesn’t use vertical-align property. Instead, it uses line-height property like following:

   1: <div>

   2:     This is the text NOT vertically centred.

   3: </div>


   5: <div style="line-height: 50px;">

   6:     This is the text vertically centred.

   7: </div>

The results of these are:

This is the text NOT vertically centred.

This is the text vertically centred.

Are they different from each other? Make sure, both have fixed height outer tag element. Usually, each navigation element has fixed height, so this trick is useful. If the height is dynamically changing, a different approach should be considered.

네비게이션 레이아웃을 CSS로 구현하다 보면 텍스트를 수직으로 정렬시켜야 하는 경우가 종종 있게 마련이다. 보통 vertical-align 속성을 써서 하게 마련인데, 내공부족인지 어쩐지 몰라도 이게 잘 먹히지 않더라. 아니면 열라 복잡하게 다른 속성까지 건드려가면서 해야하거나…

근데, 위에서처럼 line-height 속성을 주게 되면 그 안의 텍스트들은 자동으로 가운데 정렬이 이루어진다. 물론, line-height 속성을 준다는 것은 고정적인 높이를 가지고 있다는 말이기 때문에 일반적으로 쓰기에는 무리가 있다만 그래도 네비게이션 레이아웃에서는 꽤 쓸만한 팁이 아닐까 싶다.

Written by Justin Yoo

12/06/2009 at 04:42

Replacing Menu in Korean with English for TextCube – 텍스트큐브에서 한글메뉴 영문으로 바꾸기

Even though menu titles written in Korean within the skin file, AKA theme in WordPress, TextCube still provides hard-coded Korean menu titles at some sections such as comments, trackbacks, and so on. They cannot be modified by end-users. In order to replace those menus, Javascript is the only option.

   1: <!-- for language conversion from Korean to English -->

   2: <script type="text/javascript" language="javascript">

   3:     var h3s = null;

   4:     var spans = null;

   5:     var labels = null;

   6:     h3s = document.getElementsByTagName("h3");

   7:     for (i = 0; i < h3s.length; i++)

   8:     {

   9:         if (h3s[i].innerHTML == "연관글")

  10:             h3s[i].innerHTML = "What others think is ...";

  11:     }

  12:     spans = document.getElementById("replyList").getElementsByTagName("span");

  13:     for (i = 0; i < spans.length; i++)

  14:     {

  15:         if (spans[i].innerHTML == "답글")

  16:             spans[i].innerHTML = "[Reply]";

  17:         if (spans[i].innerHTML == "수정")

  18:             spans[i].innerHTML = "[Modify]";

  19:         if (spans[i].innerHTML == "삭제")

  20:             spans[i].innerHTML = "[Delete]";

  21:     }

  22:     spans = document.getElementById("replySend").getElementsByTagName("span");

  23:     for (i = 0; i < spans.length; i++)

  24:     {

  25:         if (spans[i].innerHTML == "트랙백 주소")

  26:             spans[i].innerHTML = "Trackbacks";

  27:         if (spans[i].innerHTML == "댓글 달기")

  28:             spans[i].innerHTML = "<Submit";

  29:     }

  30:     labels = document.getElementById("replySend").getElementsByTagName("label");

  31:     for (i = 0; i < labels.length; i++)

  32:     {

  33:         if (labels[i].innerHTML.indexOf("이름") > -1)

  34:             labels[i].innerHTML = "Name";

  35:         if (labels[i].innerHTML.indexOf("패스워드") > -1)

  36:             labels[i].innerHTML = "Password";

  37:         if (labels[i].innerHTML.indexOf("홈페이지") > -1)

  38:             labels[i].innerHTML = "URL";

  39:         if (labels[i].innerHTML.indexOf("내용") > -1)

  40:             labels[i].innerHTML = "Comment";

  41:         if (labels[i].innerHTML.indexOf("비밀글") > -1)

  42:             labels[i].innerHTML = "Private";

  43:     }

  44: </script>

In order to apply the Javascript above, follow the steps below.

  1. Find <div> tag that holds the class, "replyList" and add id="replyList".
  2. Find <div> tag that holds the class, "replySend" and add id="replySend".
  3. Place the Javascript code above at the just before the </body> tag.

Well, it’s not the perfect way of coping with the Korean-written menu titles because the menu can be changed whenever TextCube wants. As well as, the HTML source still holds Korean menu titles because Javascript only replaces the menus after all contents is loaded.

Nevertheless, it is worth trying.

If there is any alternative, please let me know. 🙂

텍스트큐브의 스킨을 바꾼다 하더라도, 여전히 한국어로 하드코딩된 메뉴들이 존재한다. 이부분은 절대로 스킨상에서 바꿀 수 없는 내용이기 때문에, 자바스크립트로 바꿀 수 밖에 없다.

위의 자바스크립트 소스를 적용시키기 위해서는 스킨의 내용을 약간 수정해서 적용시켜야 한다. 그 순서는 아래와 같다.

  1. "replyList" 라는 클라스 이름이 있는 <div> 태그를 찾아서 id="replyList"를 추가한다.
  2. "replySend" 라는 클라스 이름이 있는 <div> 태그를 찾아서 id="replySend"를 추가한다.
  3. </body> 태그 바로 윗부분에 위의 자바스크립트 소스를 추가한다.

텍스트큐브에서 언제든 한글메뉴 구조를 바꿀 수 있기 때문에 이 방법이 완벽한 것은 아니다. 또한, HTML 소스를 완전히 브라우저로 로드한 다음에 영문메뉴로 바꿔치기를 하는 것이다보니 HTML 소스보기를 하면 여전히 한글메뉴가 보인다.

그럼에도 불구하고 바꿔보는 것도 나쁘진 않겠지.

Written by Justin Yoo

26/05/2009 at 01:57

Added the Retweet Link


Because TextCube (TC) lacks its flexibility and extendibility (http://justinchronicles.net/4), I did do the "trial and error" method millions of times for whole weekend. In order to add some functionalities, using javascript is the only option for TC.

Well, it brings about critical deficiency for non-javascript (non-JS) users from whatever reasons not to allow them to browse easily, even though javascript (JS) features can provide rich and interactive way of browsing. Anyway, the fact that JS is the only option to add "Retweet" link made me more creative, such as thinking out of the box or inventing wheels, hehe. 🙂

The first thing I would want to implement was URL shortening. Due to the limitation of 140 characters on Twitter, using shortened URL is inevitable. There are heaps of URL shortening service providers such as tinyurl.com, bit.ly, is.gd, tr.im, ur.ly, and so on. Each service has its own strengths and weaknesses, so I chose the ur.ly API for my URL shortening purpose.

In order to get data from ur.ly, first of all, I tried to use TC-built-in AJAX functions because it might be the easiest way to enable it. However, javascript doesn’t allow cross-domain access, which drove me crazy, so I had to find another solution.

The second option was jQuery. jQuery provides a lot of functionalities which can minimise developers’ efforts. I knew AJAX in jQuery would not work because of the same reason using TC-built-in AJAX one. So, I had to use JSONP to get data. However, $.ajax, $.get(), and $.getJSON() won’t get data properly. There was data I could see, but browsers couldn’t parse it. So, I had to give up using jQuery, too.

Damn it! How could I make it work? I spent all weekend to figure this out. I reluctantly had to make another page that parses an HTML tag made by javascript codes. I’m looking after a web site belongs to one of my friends. Because of this, I could implement my own API page to create an HTML tag to display the Retweet link. That was my third, and the last, option.

retweet link

See? I did it!

Well, it’s time to bed. Long weekend. Get tired.

Written by Justin Yoo

17/05/2009 at 14:26