cleaner web cache code
diff --git a/erpnext/website/blog.py b/erpnext/website/blog.py
index 56bf8e4..f628338 100644
--- a/erpnext/website/blog.py
+++ b/erpnext/website/blog.py
@@ -52,9 +52,8 @@
 	
 	# since comments are embedded in the page, clear the web cache
 	import website.web_cache
-	website.web_cache.clear_web_cache(
-		args.get('comment_doctype'), args.get('comment_docname'),
-		args.get('page_name'))
+	website.web_cache.clear_cache(args.get('page_name'),
+		args.get('comment_doctype'), args.get('comment_docname'))
 	
 	import webnotes.utils
 	
@@ -62,7 +61,7 @@
 	template_args = { 'comment_list': [comment] }
 	
 	# get html of comment row
-	comment_html = website.web_cache.build_html(template_args, 'blog/comment.html')
+	comment_html = website.web_cache.build_html(template_args, 'html/comment.html')
 
 	return comment_html
 	
\ No newline at end of file
diff --git a/erpnext/website/doctype/website_settings/website_settings.py b/erpnext/website/doctype/website_settings/website_settings.py
index aec5a39..b08e674 100644
--- a/erpnext/website/doctype/website_settings/website_settings.py
+++ b/erpnext/website/doctype/website_settings/website_settings.py
@@ -28,43 +28,17 @@
 		self.validate_domain_list()	
 
 	def on_update(self):
-		self.rewrite_pages()
-		
-		from webnotes.session_cache import clear_cache
-		clear_cache('Guest')
-		
-	def rewrite_pages(self):
-		"""rewrite all web pages"""
-		import webnotes
-		from webnotes.model.doclist import DocList
-		from webnotes.model.code import get_obj
-		
-		# rewrite all web pages
-		for name in webnotes.conn.sql("""select name, modified from `tabWeb Page` 
-			where docstatus=0"""):
-			DocList('Web Page', name[0]).save()
-			webnotes.conn.set_value('Web Page', name[0], 'modified', name[1])
-
-		# rewrite all blog pages
-		for name in webnotes.conn.sql("""select name, modified from `tabBlog` 
-			where docstatus=0 and ifnull(published,0)=1"""):
-			DocList('Blog', name[0]).save()
-			webnotes.conn.set_value('Blog', name[0], 'modified', name[1])
-		
+		# make js and css
 		from webnotes.cms.make import make_web_core
 		make_web_core()
 		
+		# clear web cache
 		import website.web_cache
-		for page in ['blog', 'products']:
-			website.web_cache.delete_web_cache(page)
-			website.web_cache.clear_web_cache(None, None, page)
+		website.web_cache.refresh_cache()
 		
-		#get_obj('Page', 'blog').write_cms_page(force=True)
-		#get_obj('Page', 'Login Page').write_cms_page(force=True)
-		
-		webnotes.msgprint('Rebuilt all blogs and pages')
-		
-		
+		from webnotes.session_cache import clear_cache
+		clear_cache('Guest')
+
 	def set_home_page(self):
 
 		import webnotes
diff --git a/erpnext/website/js/product_category.js b/erpnext/website/js/product_category.js
deleted file mode 100644
index bed4d24..0000000
--- a/erpnext/website/js/product_category.js
+++ /dev/null
@@ -1,34 +0,0 @@
-// ERPNext - web based ERP (http://erpnext.com)
-// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
-// 
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-// 
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-erpnext.make_product_categories = function(wrapper) {
-	wrapper.category_list = new wn.ui.Listing({
-		parent: $(wrapper).find('.more-categories').get(0),
-		query: 'select count(name) as items, item_group \
-			from tabItem \
-			where is_sales_item="Yes" and \
-			ifnull(show_in_website, "No")="Yes" and \
-			docstatus = 0 \
-			group by item_group order by items desc',
-		hide_refresh: true,
-		render_row: function(parent, data) {
-			parent.innerHTML = repl('<a href="#!products/%(item_group)s">%(item_group)s</a> (%(items)s)', 
-				data);
-		}
-	});
-	wrapper.category_list.run();
-	console.log('product categories made');
-}
diff --git a/erpnext/website/js/topbar.js b/erpnext/website/js/topbar.js
deleted file mode 100644
index 88cbe8b..0000000
--- a/erpnext/website/js/topbar.js
+++ /dev/null
@@ -1,130 +0,0 @@
-// ERPNext - web based ERP (http://erpnext.com)
-// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
-// 
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-// 
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-wn.provide('erpnext.navbar');
-
-/*
-<li class="dropdown">\
-	<a class="dropdown-toggle" href="#" onclick="return false;"></a>\
-	<ul class="dropdown-menu" id="toolbar-user">\
-	</ul>\
-</li>\
-*/
-
-erpnext.navbar.Navbar = Class.extend({
-	init: function() {
-		this.make();
-		$('.brand').html(wn.boot.website_settings.brand_html || sys_defaults.company);
-		this.make_items();
-		$('.dropdown-toggle').dropdown();
-	},
-	make: function() {
-		$('header').append('<div class="navbar navbar-fixed-top">\
-			<div class="navbar-inner">\
-			<div class="container">\
-				<a class="brand">[brand]</a>\
-				<ul class="nav">\
-				</ul>\
-				<img src="images/lib/ui/spinner.gif" id="spinner"/>\
-				<ul class="nav pull-right">\
-					<li id="login-topbar-item"><a href="#!Login Page">Login</a></li>\
-				</ul>\
-			</div>\
-			</div>\
-			</div>');
-		$('.brand').attr('href', '#!' + (wn.boot.website_settings.home_page || 'Login Page'))
-	},
-	make_items: function() {
-		var items = wn.boot.website_menus;
-		
-		// parent labels
-		for(var i=0;i<items.length;i++) {
-			var item = items[i];
-			if(!item.parent_label && item.parentfield=='top_bar_items') {
-				erpnext.header_link_settings(item);
-				$('header .nav:first').append(repl('<li data-label="%(label)s">\
-					<a href="%(route)s" %(target)s>%(label)s</a></li>', item));
-			}
-		}
-		
-		// child labels
-		for(var i=0;i<items.length;i++) {
-			var item = items[i];
-			if(item.parent_label && item.parentfield=='top_bar_items') {
-				// check if parent label has class "dropdown"
-				$parent_li = $(repl('header li[data-label="%(parent_label)s"]', item));
-				if(!$parent_li.hasClass('dropdown')) {
-					$parent_li.addClass('dropdown');
-					$parent_li.find('a:first').addClass('dropdown-toggle')
-						.attr('data-toggle', 'dropdown')
-						.attr('href', '')
-						.append('<b class="caret"></b>')
-						.click(function() {
-							return false;
-						});
-					$parent_li.append('');
-				}
-				erpnext.header_link_settings(item);
-				$parent_li.find('.dropdown-menu').append(repl('<li data-label="%(label)s">\
-					<a href="%(route)s" %(target)s>%(label)s</a></li>', item))
-			}
-		}
-	}
-});
-
-// footer
-erpnext.Footer = Class.extend({
-	init: function() {
-		if(!wn.boot.website_settings.copyright) {
-			wn.boot.website_settings.copyright = sys_defaults.company;
-		}
-		if(!wn.boot.website_settings.address) {
-			wn.boot.website_settings.address = '';
-		}
-		$('footer').html(repl('<div class="web-footer">\
-			<div class="web-footer-menu"><ul></ul></div>\
-			<div class="web-footer-copyright">&copy; %(copyright)s</div>\
-		</div>', wn.boot.website_settings));
-		this.make_items();
-	},
-	make_items: function() {
-		var items = wn.boot.website_menus
-		for(var i=0;i<items.length;i++) {
-			var item = items[i];
-			if(!item.parent_label && item.parentfield=='footer_items') {
-				erpnext.header_link_settings(item);
-				$('.web-footer-menu ul').append(repl('<li><a href="%(route)s" %(target)s\
-					data-label="%(label)s">%(label)s</a></li>', item))
-			}
-		}
-	}
-});
-
-// customize hard / soft links
-erpnext.header_link_settings = function(item) {
-	item.route = item.url || item.custom_page;
-	if(item.route && item.route.substr(0,4)=='http') {
-		item.target = 'target="_blank"';				
-	} else {
-		item.target = '';
-		item.route = '#!' + item.route;
-	}	
-}
-
-$(document).bind('startup', function() {
-	erpnext.footer = new erpnext.Footer();
-	//erpnext.navbar.navbar = new erpnext.navbar.Navbar();	
-})
diff --git a/erpnext/website/page/about/__init__.py b/erpnext/website/page/about/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/website/page/about/__init__.py
+++ /dev/null
diff --git a/erpnext/website/page/about/about.txt b/erpnext/website/page/about/about.txt
deleted file mode 100644
index a106513..0000000
--- a/erpnext/website/page/about/about.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-# Page, about
-[
-
-	# These values are common in all dictionaries
-	{
-		'creation': '2012-01-27 11:37:57',
-		'docstatus': 0,
-		'modified': '2012-01-27 13:26:42',
-		'modified_by': 'Administrator',
-		'owner': 'Administrator'
-	},
-
-	# These values are common for all Page
-	{
-		'doctype': 'Page',
-		'module': 'Website',
-		'name': '__common__',
-		'page_name': 'about',
-		'standard': 'Yes',
-		'title': 'About Us'
-	},
-
-	# These values are common for all Page Role
-	{
-		'doctype': 'Page Role',
-		'name': '__common__',
-		'parent': 'about',
-		'parentfield': 'roles',
-		'parenttype': 'Page',
-		'role': 'Guest'
-	},
-
-	# Page, about
-	{
-		'doctype': 'Page',
-		'name': 'about'
-	},
-
-	# Page Role
-	{
-		'doctype': 'Page Role'
-	}
-]
\ No newline at end of file
diff --git a/erpnext/website/page/blog/__init__.py b/erpnext/website/page/blog/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/website/page/blog/__init__.py
+++ /dev/null
diff --git a/erpnext/website/page/blog/blog.html b/erpnext/website/page/blog/blog.html
deleted file mode 100644
index 8d7cd00..0000000
--- a/erpnext/website/page/blog/blog.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<div class="layout-wrapper layout-wrapper-background">
-	<div class="web-content" id="content-blog">
-		<div class="layout-main-section">
-			<h1>Blog</h1>
-			<br>
-			<div id="blog-list"></div>
-		</div>
-		<div class="layout-side-section">
-			<!-- for later
-			<h4>Get Updates</h4>
-			<p>
-			<input name="blog-subscribe">
-			<button class="btn" id="blog-subscribe">Subscribe</button>
-			</p>-->
-			<h4>Subscribe</h4>
-			<p>
-			<img src="images/feed.png" style="margin-right: 4px; margin-bottom: -4px">
-			<a href="rss.xml" target="_blank">RSS Feed</a>
-			</p>
-		</div>
-		<div style="clear: both"></div>
-	</div>
-</div>
\ No newline at end of file
diff --git a/erpnext/website/page/blog/blog.js b/erpnext/website/page/blog/blog.js
deleted file mode 100644
index 5a10998..0000000
--- a/erpnext/website/page/blog/blog.js
+++ /dev/null
@@ -1,59 +0,0 @@
-// ERPNext - web based ERP (http://erpnext.com)
-// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
-// 
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-// 
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-
-pscript.onload_blog = function(wrapper) {
-	wrapper.blog_list = new wn.ui.Listing({
-		parent: $(wrapper).find('#blog-list').get(0),
-		query: 'select tabBlog.name, title, left(content, 1000) as content, tabBlog.creation, \
-			ifnull(first_name, "") as first_name, ifnull(last_name, "") as last_name \
-			from tabProfile, tabBlog\
-		 	where ifnull(published,0)=1 and tabBlog.owner = tabProfile.name \
-			order by tabBlog.creation desc',
-		hide_refresh: true,
-		no_toolbar: true,
-		render_row: function(parent, data) {
-			if(data.content && data.content.length==1000) data.content += '... (read on)';
-			data.content = wn.markdown(data.content);
-			if(data.last_name) data.last_name = ' ' + data.last_name;
-			data.date = prettyDate(data.creation);
-			parent.innerHTML = repl('<h2>%(title)s</h2>\
-				<p><div class="help">By %(first_name)s%(last_name)s, %(date)s</div></p>\
-				<p>%(content)s</p>\
-				<a href="%(name)s.html">Read Full Text</a><br>', data);
-		},
-		page_length: 10
-	});
-	wrapper.blog_list.run();
-	
-	// subscribe button
-	$('#blog-subscribe').click(function() {
-		var email = $(wrapper).find('input[name="blog-subscribe"]').val();
-		if(!validate_email(email)) {
-			msgprint('Please enter a valid email!');
-		}
-		wn.call({
-			module:'website',
-			page:'blog',
-			method:'subscribe',
-			args:email,
-			btn: this,
-			callback: function() {
-				$(wrapper).find('input[name="blog-subscribe"]').val('');
-			}
-		});		
-	})
-}
\ No newline at end of file
diff --git a/erpnext/website/page/blog/blog.py b/erpnext/website/page/blog/blog.py
deleted file mode 100644
index 9790114..0000000
--- a/erpnext/website/page/blog/blog.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# ERPNext - web based ERP (http://erpnext.com)
-# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
-# 
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-# 
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-import webnotes
-
-@webnotes.whitelist()
-def subscribe(arg):
-	"""subscribe to blog (blog_subscriber)"""
-	if webnotes.conn.sql("""select name from `tabBlog Subscriber` where name=%s""", arg):
-		webnotes.msgprint("Already a subscriber. Thanks!")
-	else:
-		from webnotes.model.doc import Document
-		d = Document('Blog Subscriber')
-		d.name = arg
-		d.save()
-		webnotes.msgprint("Thank you for subscribing!")
\ No newline at end of file
diff --git a/erpnext/website/page/blog/blog.txt b/erpnext/website/page/blog/blog.txt
deleted file mode 100644
index 4443ec8..0000000
--- a/erpnext/website/page/blog/blog.txt
+++ /dev/null
@@ -1,44 +0,0 @@
-# Page, blog
-[
-
-	# These values are common in all dictionaries
-	{
-		'creation': '2012-01-27 15:47:52',
-		'docstatus': 0,
-		'modified': '2012-01-27 15:47:52',
-		'modified_by': 'Administrator',
-		'owner': 'Administrator'
-	},
-
-	# These values are common for all Page
-	{
-		'doctype': 'Page',
-		'module': 'Website',
-		'name': '__common__',
-		'page_name': 'blog',
-		'standard': 'Yes',
-		'title': 'Blog'
-	},
-
-	# These values are common for all Page Role
-	{
-		'__islocal': 1,
-		'doctype': 'Page Role',
-		'name': '__common__',
-		'parent': 'blog',
-		'parentfield': 'roles',
-		'parenttype': 'Page',
-		'role': 'Guest'
-	},
-
-	# Page, blog
-	{
-		'doctype': 'Page',
-		'name': 'blog'
-	},
-
-	# Page Role
-	{
-		'doctype': 'Page Role'
-	}
-]
\ No newline at end of file
diff --git a/erpnext/website/page/contact/__init__.py b/erpnext/website/page/contact/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/website/page/contact/__init__.py
+++ /dev/null
diff --git a/erpnext/website/page/contact/contact.js b/erpnext/website/page/contact/contact.js
deleted file mode 100644
index c794325..0000000
--- a/erpnext/website/page/contact/contact.js
+++ /dev/null
@@ -1,46 +0,0 @@
-// ERPNext - web based ERP (http://erpnext.com)
-// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
-// 
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-// 
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-pscript.onload_contact = function(wrapper) {
-	$('#content-contact-us .btn.primary').click(function() {
-		var me = this;
-		var args = {};
-		args.name = $('#content-contact-us [name="contact-name"]').val();
-		args.email = $('#content-contact-us [name="contact-email"]').val();
-		args.message = $('#content-contact-us [name="contact-message"]').val();
-		
-		if(!validate_email(args.email)) {
-			msgprint('Please enter a valid email id');
-			return;
-		}
-		
-		if(args.name && args.email && args.message) {
-			$(this).set_working();
-			$c_page('website', 'contact', 'send', args, function(r) {
-				$('#content-contact-us [name*="contact"]').val('');
-				$(me).done_working();
-			});
-		} else {
-			msgprint("Please enter info in all the fields.")
-		}
-	});
-	
-	$('#content-contact-us :input').keyup(function(ev) {
-		if(ev.which == 13) {
-			$('#content-contact-us .btn.primary').click();
-		}
-	});
-}
\ No newline at end of file
diff --git a/erpnext/website/page/contact/contact.py b/erpnext/website/page/contact/contact.py
deleted file mode 100644
index 1ee3ab9..0000000
--- a/erpnext/website/page/contact/contact.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# ERPNext - web based ERP (http://erpnext.com)
-# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
-# 
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-# 
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-import json, webnotes
-
-@webnotes.whitelist(allow_guest=True)
-def send(args):
-	"""create support ticket"""
-	args = json.loads(args)
-	
-	from webnotes.model.doc import Document
-	d = Document('Support Ticket')
-	d.raised_by = args['email']
-	d.description = 'From: ' + args['name'] + '\n\n' + args['message']
-	d.subject = 'Website Query'
-	d.status = 'Open'
-	d.owner = 'Guest'
-	d.save(1)
-	webnotes.msgprint("Thank you for your query. We will respond as soon as we can.")
\ No newline at end of file
diff --git a/erpnext/website/page/contact/contact.txt b/erpnext/website/page/contact/contact.txt
deleted file mode 100644
index 6051c6f..0000000
--- a/erpnext/website/page/contact/contact.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-# Page, contact
-[
-
-	# These values are common in all dictionaries
-	{
-		'creation': '2012-01-25 16:02:15',
-		'docstatus': 0,
-		'modified': '2012-01-25 16:02:15',
-		'modified_by': 'Administrator',
-		'owner': 'Administrator'
-	},
-
-	# These values are common for all Page
-	{
-		'doctype': 'Page',
-		'module': 'Website',
-		'name': '__common__',
-		'page_name': 'contact',
-		'standard': 'Yes'
-	},
-
-	# These values are common for all Page Role
-	{
-		'doctype': 'Page Role',
-		'name': '__common__',
-		'parent': 'contact',
-		'parentfield': 'roles',
-		'parenttype': 'Page',
-		'role': 'Guest'
-	},
-
-	# Page, contact
-	{
-		'doctype': 'Page',
-		'name': 'contact'
-	},
-
-	# Page Role
-	{
-		'doctype': 'Page Role'
-	}
-]
\ No newline at end of file
diff --git a/erpnext/website/page/products/README.md b/erpnext/website/page/products/README.md
deleted file mode 100644
index e40b446..0000000
--- a/erpnext/website/page/products/README.md
+++ /dev/null
@@ -1,27 +0,0 @@
-## Products
-
-Contains
-
-- List of Products tagged by Item master
-	- image
-	- short description (md)
-	- pricing info (if public) (public pricelist)
-	- stock info (website warehouse)
-- Search
-- Sidebar contains categories (# of items in each category)
-
-When Item is Saved, a page for that item is created with
-
-- Large image
-- Smaller images
-- Long Description
-- Pricing info
-- Stock info
-- Contact Button (instead of Buy / Add to cart)
-
-### Steps
-
-- update item master
-- update item category (show in web + priority) (or in a products settings page)
-- # of public items in each category
-- validation - item cannot have show in item if parent does not have it
\ No newline at end of file
diff --git a/erpnext/website/page/products/__init__.py b/erpnext/website/page/products/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/website/page/products/__init__.py
+++ /dev/null
diff --git a/erpnext/website/page/products/products.html b/erpnext/website/page/products/products.html
deleted file mode 100644
index 30eca4a..0000000
--- a/erpnext/website/page/products/products.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<div class="layout-wrapper layout-wrapper-background" id="content-products">
-	<div class="layout-main-section">
-		<h1 class="products-category"></h1>
-		<div class="products-search" style="margin-bottom: 15px;">
-			<input name="products-search" /><button class="btn" style="margin-left: 7px">Search</button>
-		</div>
-		<div class="products-list"></div>
-	</div>
-	<div class="layout-side-section">
-		<h3>Categories</h3>
-		<div class="more-categories"></div>
-	</div>
-	<div style="clear:both;">
-</div>
\ No newline at end of file
diff --git a/erpnext/website/page/products/products.js b/erpnext/website/page/products/products.js
deleted file mode 100644
index 1e8dcaa..0000000
--- a/erpnext/website/page/products/products.js
+++ /dev/null
@@ -1,109 +0,0 @@
-// ERPNext - web based ERP (http://erpnext.com)
-// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
-// 
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-// 
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-erpnext.products = {}
-
-wn.require('js/product_category.js');
-
-pscript.onload_products = function(wrapper) {
-	erpnext.make_product_categories(wrapper);
-	erpnext.products.wrapper = wrapper;	
-
-	// make lists
-	erpnext.products.make_product_list(wrapper);
-	
-	// button
-	$(wrapper).find('.products-search .btn').click(function() {
-		wrapper.mainlist.run();
-	});
-	
-	$(wrapper).find('.products-search input').keypress(function(ev) {
-		if(ev.which==13) $(wrapper).find('.products-search .btn').click();
-	});
-}
-
-pscript.onshow_products = function(wrapper) {
-	// show default product category
-	erpnext.products.set_group();
-}
-
-erpnext.products.get_group = function() {
-	route = wn.get_route();
-	if(route.length>1) {
-		// from url
-		var grp = route[1];
-		var label = route[1];
-	} else {
-		// default
-		var grp = wn.boot.website_settings.default_product_category;
-		var label = wn.boot.website_settings.default_product_category;
-	}
-	erpnext.products.cur_group = grp;
-	return {grp:grp, label:label};
-}
-
-erpnext.products.make_product_list = function(wrapper) {
-	wrapper.mainlist = new wn.ui.Listing({
-		parent: $(wrapper).find('.products-list').get(0),
-		run_btn: $(wrapper).find('.products-search .btn').get(0),
-		no_toolbar: true,
-		get_query: function() {
-			var srch = $('input[name="products-search"]').val()
-			var search_cond = 'and (description like "%%(srch)s%"\
-				or item_name like "%%(srch)s%")';
-			args = {
-				search_cond: srch ? repl(search_cond, {srch:srch}) : '',
-				cat: erpnext.products.cur_group
-			};
-			return repl('select name, item_name, website_image, \
-				description, page_name \
-				from tabItem \
-				where is_sales_item="Yes" \
-				and item_group="%(cat)s" \
-				%(search_cond)s', args)
-		},
-		render_row: function(parent, data) {
-			parent.innerHTML = repl('<div style="float:left; width: 115px;" class="img-area">\
-				</div>\
-				<div style="float:left; width: 400px">\
-					<p><b><a href="#!%(page_name)s">%(item_name)s</a></b></p>\
-					<p>%(description)s</p></div>\
-				<div style="clear: both;"></div>', data);
-				
-			if(data.website_image) {
-				$(parent).find('.img-area').append(repl(
-					'<img src="files/%(website_image)s" style="width:100px;">', data))
-			} else {
-				$(parent).find('.img-area').append(wn.dom.placeholder(70, 
-					data.item_name));
-			}
-		}
-	});
-}
-
-erpnext.products.set_group = function() {
-	var cat = erpnext.products.get_group();
-	if(!cat.grp) {
-		// still nothing
-		setTimeout('erpnext.products.set_group()', 1000);
-		return;		
-	}
-	// get erpnext.products.default_category
-	var wrapper = erpnext.products.wrapper;
-	
-	$(wrapper).find('h1').html(cat.label);
-	wrapper.mainlist.run();
-}
diff --git a/erpnext/website/page/products/products.txt b/erpnext/website/page/products/products.txt
deleted file mode 100644
index f00a05b..0000000
--- a/erpnext/website/page/products/products.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-# Page, products
-[
-
-	# These values are common in all dictionaries
-	{
-		'creation': '2012-01-30 10:49:01',
-		'docstatus': 0,
-		'modified': '2012-01-30 10:49:01',
-		'modified_by': 'Administrator',
-		'owner': 'Administrator'
-	},
-
-	# These values are common for all Page
-	{
-		'doctype': 'Page',
-		'module': 'Website',
-		'name': '__common__',
-		'page_name': 'products',
-		'standard': 'Yes',
-		'title': 'Products'
-	},
-
-	# These values are common for all Page Role
-	{
-		'doctype': 'Page Role',
-		'name': '__common__',
-		'parent': 'products',
-		'parentfield': 'roles',
-		'parenttype': 'Page',
-		'role': 'Guest'
-	},
-
-	# Page, products
-	{
-		'doctype': 'Page',
-		'name': 'products'
-	},
-
-	# Page Role
-	{
-		'doctype': 'Page Role'
-	}
-]
\ No newline at end of file
diff --git a/erpnext/website/templates/css/blog.css b/erpnext/website/templates/css/blog.css
new file mode 100644
index 0000000..199df1a
--- /dev/null
+++ b/erpnext/website/templates/css/blog.css
@@ -0,0 +1,7 @@
+	<style>
+		h2 > a, h2 > a:link, h2 > a:visited, h2 > a:active,
+		h2 > a:hover, h2 > a:focus {
+			text-decoration: none;
+			color: inherit;
+		}
+	</style>
\ No newline at end of file
diff --git a/erpnext/website/templates/css/blog_page.css b/erpnext/website/templates/css/blog_page.css
new file mode 100644
index 0000000..928b8ac
--- /dev/null
+++ b/erpnext/website/templates/css/blog_page.css
@@ -0,0 +1,9 @@
+	<style>
+		.comment-title {
+			color:#777;
+		}
+		
+		.comment-content {
+			margin-left: 20px;
+		}
+	</style>
\ No newline at end of file
diff --git a/erpnext/website/templates/css/login.css b/erpnext/website/templates/css/login.css
new file mode 100644
index 0000000..4e3e4b1
--- /dev/null
+++ b/erpnext/website/templates/css/login.css
@@ -0,0 +1,10 @@
+	<style>
+		#login_wrapper {
+			width: 300px !important;
+			margin: 20px auto;
+		}
+
+		.login-banner {
+			margin-bottom: 20px;
+		}
+	</style>
\ No newline at end of file
diff --git a/erpnext/website/templates/css/product_page.css b/erpnext/website/templates/css/product_page.css
new file mode 100644
index 0000000..2708625
--- /dev/null
+++ b/erpnext/website/templates/css/product_page.css
@@ -0,0 +1,34 @@
+	<style>
+		.web-long-description {
+			font-size: 18px;
+			line-height: 200%;
+		}
+		.product-page-content {
+			float: left;
+		}
+		/* product page image css */
+		.product-page-content img {
+			max-width: 100%;
+		}
+		
+		/* similar products listing */
+		.similar-products .img-area img {
+			max-width: 55px;
+			max-height: 55px;
+		}
+		
+		.similar-products .img-area {
+			float: left;
+			width: 30%;
+			margin-top: 0.3em;
+		}
+		
+		.similar-product-description {
+			float: left;
+			width: 70%;
+		}
+		
+		.similar-product-description span {
+			font-size: 12px;
+		}
+	</style>
\ No newline at end of file
diff --git a/erpnext/website/templates/css/products.css b/erpnext/website/templates/css/products.css
new file mode 100644
index 0000000..73289c4
--- /dev/null
+++ b/erpnext/website/templates/css/products.css
@@ -0,0 +1,11 @@
+	<style>
+		.img-area {
+			float:left;
+			width: 115px;
+		}
+		
+		.product-list-description {
+			float:left;
+			width: 400px;
+		}
+	</style>
\ No newline at end of file
diff --git a/erpnext/website/templates/base.html b/erpnext/website/templates/html/base.html
similarity index 100%
rename from erpnext/website/templates/base.html
rename to erpnext/website/templates/html/base.html
diff --git a/erpnext/website/templates/blog/blog.html b/erpnext/website/templates/html/blog_page.html
similarity index 72%
rename from erpnext/website/templates/blog/blog.html
rename to erpnext/website/templates/html/blog_page.html
index d87b128..c07706a 100644
--- a/erpnext/website/templates/blog/blog.html
+++ b/erpnext/website/templates/html/blog_page.html
@@ -1,26 +1,41 @@
-{% extends "blog/blog.js" %}
+{% extends "html/page.html" %}
+
+{% block javascript %}
+	{% include "js/blog_page.js" %}
+{% endblock %}
+
+{% block css %}
+	{% include "css/blog_page.css" %}
+{% endblock %}
 
 {% block content %}
 	<div class="layout-wrapper layout-wrapper-background">
 		<div class="web-content" id="blog-{{ name }}">
 
 			<div class="layout-main-section">
+				
 				<h2>{{ title }}</h2>
+
+				<!-- begin blog content -->
 				<div class="help">By {{ full_name }} on {{ updated }}</div>
 				<br>
 				{{ content_html }}
 				<hr>
 				<h3>Comments</h3><br>
 				<div class="blog-comments">
+					
+					{% if not comment_list %}
 					<div class="no-result help hide">
 						<p>Be the first one to comment</p>
 						<br />
 					</div>
-
-					{% include 'blog/comment.html' %}
-
-					<button class="btn add-comment">Add Comment</button>
+					{% endif %}
+					
+					{% include 'html/comment.html' %}
 				</div>
+				<!-- end blog content -->
+				
+				<button class="btn add-comment">Add Comment</button>
 			</div>
 
 			<div class="layout-side-section">
@@ -39,21 +54,4 @@
 			<div style="clear: both"></div>
 		</div>
 	</div>
-{% endblock %}
-
-{% block css %}
-	<style>
-		.comment-title {
-			color:#777;
-		}
-		
-		.comment-content {
-			margin-left: 20px;
-		}
-		
-/*		.comment-row {
-			padding: 5px 0px;
-		}
-*/	</style>
-	
 {% endblock %}
\ No newline at end of file
diff --git a/erpnext/website/templates/blog/comment.html b/erpnext/website/templates/html/comment.html
similarity index 100%
rename from erpnext/website/templates/blog/comment.html
rename to erpnext/website/templates/html/comment.html
diff --git a/erpnext/website/templates/outer.html b/erpnext/website/templates/html/outer.html
similarity index 91%
rename from erpnext/website/templates/outer.html
rename to erpnext/website/templates/html/outer.html
index 4b8c04d..47184fa 100644
--- a/erpnext/website/templates/outer.html
+++ b/erpnext/website/templates/html/outer.html
@@ -2,7 +2,7 @@
 	requires, brand, top_bar_items, footer_items, copyright, content
 #}
 
-{% extends "base.html" %}
+{% extends "html/base.html" %}
 
 {% block body %}
 
@@ -31,7 +31,7 @@
 				</ul>
 				<img src="images/lib/ui/spinner.gif" id="spinner"/>
 				<ul class="nav pull-right">
-					<li id="login-topbar-item"><a href="login-page.html">Login</a></li>
+					<li id="login-topbar-item"><a href="login.html">Login</a></li>
 				</ul>
 			</div>
 			</div>
@@ -50,7 +50,9 @@
 				data-label="{{ item.label }}">{{ item.label }}</a></li>
 		{% endfor %}
 		</ul></div>
+		{% if copyright %}
 		<div class="web-footer-copyright">&copy; {{ copyright }}
+		{% endif %}
 		</div>
 	</footer>
 
diff --git a/erpnext/website/templates/page.html b/erpnext/website/templates/html/page.html
similarity index 87%
rename from erpnext/website/templates/page.html
rename to erpnext/website/templates/html/page.html
index c6e0715..e2eb6f4 100644
--- a/erpnext/website/templates/page.html
+++ b/erpnext/website/templates/html/page.html
@@ -1,10 +1,9 @@
-{% extends "outer.html" %}
+{% extends "html/outer.html" %}
 
 {% block title %}{{ title }}{% endblock %}
 
 {% block header %}
 	{{ super() }}
-	{% if insert_code %}
 	<script>
 	window.page_name = "{{ name }}";
 
@@ -13,7 +12,6 @@
 	
 		// page script
 		{% block javascript %}
-		{{ javascript }}
 		{% endblock %}
 	
 		// trigger onload
@@ -23,7 +21,6 @@
 		wn.container.change_to(window.page_name);
 	});
 	</script>
-	{% endif %}
 	
 	{% block css %}
 	{% if insert_style %}
diff --git a/erpnext/website/templates/product/product.html b/erpnext/website/templates/html/product_page.html
similarity index 62%
rename from erpnext/website/templates/product/product.html
rename to erpnext/website/templates/html/product_page.html
index 6f33ec9..646bba9 100644
--- a/erpnext/website/templates/product/product.html
+++ b/erpnext/website/templates/html/product_page.html
@@ -1,4 +1,12 @@
-{% extends "product/product.js" %}
+{% extends "html/page.html" %}
+
+{% block javascript %}
+	{% include "js/product_page.js" %}
+{% endblock %}
+
+{% block css %}
+	{% include "css/product_page.css" %}
+{% endblock %}
 
 {% block title %}
 	{% if item_name != name %}
@@ -37,41 +45,4 @@
 			<div style="clear: both"></div>
 		</div>
 	</div>
-{% endblock %}
-
-{% block css %}
-	<style>
-		.web-long-description {
-			font-size: 18px;
-			line-height: 200%;
-		}
-		.product-page-content {
-			float: left;
-		}
-		/* product page image css */
-		.product-page-content img {
-			max-width: 100%;
-		}
-		
-		/* similar products listing */
-		.similar-products .img-area img {
-			max-width: 55px;
-			max-height: 55px;
-		}
-		
-		.similar-products .img-area {
-			float: left;
-			width: 30%;
-			margin-top: 0.3em;
-		}
-		
-		.similar-product-description {
-			float: left;
-			width: 70%;
-		}
-		
-		.similar-product-description span {
-			font-size: 12px;
-		}
-</style>
-{% endblock %}
+{% endblock %}
\ No newline at end of file
diff --git a/erpnext/website/templates/web_page.html b/erpnext/website/templates/html/web_page.html
similarity index 81%
rename from erpnext/website/templates/web_page.html
rename to erpnext/website/templates/html/web_page.html
index 8188e71..6fa7d27 100644
--- a/erpnext/website/templates/web_page.html
+++ b/erpnext/website/templates/html/web_page.html
@@ -1,4 +1,10 @@
-{% extends "page.html" %}
+{% extends "html/page.html" %}
+
+{% block javascript %}
+	{% if insert_code %}
+		{{ javascript }}
+	{% endif %}
+{% endblock %}
 
 {% block content %}
 	<div class="layout-wrapper layout-wrapper-background">
diff --git a/erpnext/website/templates/blog/blog_list.js b/erpnext/website/templates/js/blog.js
similarity index 95%
rename from erpnext/website/templates/blog/blog_list.js
rename to erpnext/website/templates/js/blog.js
index 70628c1..1212a84 100644
--- a/erpnext/website/templates/blog/blog_list.js
+++ b/erpnext/website/templates/js/blog.js
@@ -1,6 +1,3 @@
-{% extends "page.html" %}
-
-{% block javascript %}
 // ERPNext - web based ERP (http://erpnext.com)
 // Copyright (C) 2012 Web Notes Technologies Pvt Ltd
 // 
@@ -43,6 +40,4 @@
 		page_length: 10
 	});
 	erpnext.blog_list.run();
-}
-
-{% endblock %}
+}
\ No newline at end of file
diff --git a/erpnext/website/templates/blog/blog.js b/erpnext/website/templates/js/blog_page.js
similarity index 94%
rename from erpnext/website/templates/blog/blog.js
rename to erpnext/website/templates/js/blog_page.js
index 24d5033..7121677 100644
--- a/erpnext/website/templates/blog/blog.js
+++ b/erpnext/website/templates/js/blog_page.js
@@ -1,6 +1,3 @@
-{% extends "page.html" %}
-
-{% block javascript %}
 // ERPNext - web based ERP (http://erpnext.com)
 // Copyright (C) 2012 Web Notes Technologies Pvt Ltd
 // 
@@ -18,6 +15,7 @@
 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 // js inside blog page
+
 wn.provide('erpnext.blog');
 wn.pages['{{ name }}'].onload = function(wrapper) {
 	erpnext.blog.wrapper = wrapper;
@@ -79,6 +77,7 @@
 	var $blog_comments = $(wrapper).find('.blog-comments');
 	var $comment_rows = $blog_comments.find('.comment-row');
 	var $no_result = $blog_comments.find('.no-result');
+
 	if ($comment_rows.length == 0) {
 		$no_result.removeClass('hide');
 	} else {
@@ -156,9 +155,9 @@
 	$comment_rows = $blog_comments.find('.comment-row');
 	
 	if ($comment_rows.length) {
-		$comment_rows.last().after(comment);
+		$blog_comments.append(comment);
 	} else {
-		$blog_comments.find('.no-result').after(comment);
+		$blog_comments.append(comment);
 	}
 	
 	erpnext.blog.toggle_no_result(wrapper);
@@ -170,7 +169,12 @@
 	if ($wrapper.find('.blog-comments .comment-row').length > 50) {
 		var $comment_btn = $wrapper.find('button.add-comment');
 		$comment_btn.addClass('hide');
+		
+		// show comments are close
+		$wrapper.find('.blog-comments').append("\
+			<div class=\"help\"> \
+				<p>Comments Closed</p> \
+				<br /> \
+			</div>");
 	}
-}
-
-{% endblock %}
+}
\ No newline at end of file
diff --git a/erpnext/website/templates/js/login.js b/erpnext/website/templates/js/login.js
new file mode 100644
index 0000000..29e4922
--- /dev/null
+++ b/erpnext/website/templates/js/login.js
@@ -0,0 +1,91 @@
+// ERPNext - web based ERP (http://erpnext.com)
+// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
+// 
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+wn.provide('erpnext.login');
+
+wn.pages["{{ name }}"].onload = function(wrapper) {
+	wrapper.appframe = new wn.ui.AppFrame($(wrapper).find('.appframe-area'));
+	wrapper.appframe.title('Login');
+	wrapper.appframe.$w.find('.close').toggle(false);
+
+	var lw = $i('login_wrapper');
+	$bs(lw, '1px 1px 3px #888');
+
+	$('#login_btn').click(erpnext.login.doLogin)
+		
+	$('#password').keypress(function(ev){
+		if(ev.which==13 && $('#password').val()) {
+			$('form').submit(function() {
+				erpnext.login.doLogin();
+				return false;
+			});
+		}
+	});
+	$(document).trigger('login_rendered');
+}
+
+// Login Callback
+erpnext.login.onLoginReply = function(r, rtext) {
+	$('#login_btn').done_working();
+    if(r.message=="Logged In"){
+        window.location.href='app.html' + (get_url_arg('page') ? ('?page='+get_url_arg('page')) : '');
+    } else {
+        $i('login_message').innerHTML = '<span style="color: RED;">'+(r.message)+'</span>';
+        //if(r.exc)alert(r.exc);
+    }
+}
+
+
+// Login
+erpnext.login.doLogin = function(){
+
+    var args = {};
+    args['usr']=$i("login_id").value;
+    args['pwd']=$i("password").value;
+    if($i('remember_me').checked) 
+      args['remember_me'] = 1;
+
+	$('#login_btn').set_working();
+	
+    $c("login", args, erpnext.login.onLoginReply);
+
+	return false;
+}
+
+
+erpnext.login.show_forgot_password = function(){
+    // create dialog
+	var d = new wn.ui.Dialog({
+		title:"Forgot Password",
+		fields: [
+			{'label':'Email Id', 'fieldname':'email_id', 'fieldtype':'Data', 'reqd':true},
+			{'label':'Email Me A New Password', 'fieldname':'run', 'fieldtype':'Button'}
+		]
+	});
+
+	$(d.fields_dict.run.input).click(function() {
+		var values = d.get_values();
+		if(!values) return;
+		wn.call({
+			method:'reset_password',
+			args: { user: values.email_id },
+			callback: function() {
+				d.hide();
+			}
+		})
+	})
+	d.show();
+}
\ No newline at end of file
diff --git a/erpnext/website/templates/product/product_category.js b/erpnext/website/templates/js/product_category.js
similarity index 89%
rename from erpnext/website/templates/product/product_category.js
rename to erpnext/website/templates/js/product_category.js
index e1905ac..4229d00 100644
--- a/erpnext/website/templates/product/product_category.js
+++ b/erpnext/website/templates/js/product_category.js
@@ -1,7 +1,5 @@
-{% extends "page.html" %}
-
-{% block javascript %}
 wn.provide('erpnext.products');
+
 erpnext.products.make_product_categories = function(wrapper) {
 	if (!wrapper) { wrapper = erpnext.products.wrapper; }
 	if (!wrapper) { return; }
@@ -17,6 +15,4 @@
 		}
 	});
 	wrapper.category_list.run();
-}
-
-{% endblock %}
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/erpnext/website/templates/product/product.js b/erpnext/website/templates/js/product_page.js
similarity index 95%
rename from erpnext/website/templates/product/product.js
rename to erpnext/website/templates/js/product_page.js
index f7745d7..0c4abb4 100644
--- a/erpnext/website/templates/product/product.js
+++ b/erpnext/website/templates/js/product_page.js
@@ -1,7 +1,3 @@
-{% extends "product/product_category.js" %}
-
-{% block javascript %}
-{{ super() }}
 // ERPNext - web based ERP (http://erpnext.com)
 // Copyright (C) 2012 Web Notes Technologies Pvt Ltd
 // 
@@ -17,7 +13,9 @@
 // 
 // You should have received a copy of the GNU General Public License
 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
-wn.provide('erpnext.products');
+
+{% include "js/product_category.js" %}
+
 wn.pages['{{ name }}'].onload = function(wrapper) {
 	wrapper.product_group = "{{ item_group }}";
 	wrapper.product_name = "{{ name }}";
@@ -91,6 +89,4 @@
 		}
 	});
 	wrapper.similar.run();
-}
-
-{% endblock %}
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/erpnext/website/templates/product/product_list.js b/erpnext/website/templates/js/products.js
similarity index 95%
rename from erpnext/website/templates/product/product_list.js
rename to erpnext/website/templates/js/products.js
index 1c6f934..f4c68cb 100644
--- a/erpnext/website/templates/product/product_list.js
+++ b/erpnext/website/templates/js/products.js
@@ -1,8 +1,3 @@
-{% extends "product/product_category.js" %}
-
-{% block javascript %}
-{{ super() }}
-
 // ERPNext - web based ERP (http://erpnext.com)
 // Copyright (C) 2012 Web Notes Technologies Pvt Ltd
 // 
@@ -20,7 +15,8 @@
 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 // js inside blog page
-wn.provide('erpnext.products');
+
+{% include "js/product_category.js" %}
 
 wn.pages['{{ name }}'].onload = function(wrapper) {
 	erpnext.products.wrapper = wrapper;
@@ -107,6 +103,4 @@
 		erpnext.products.cur_group = null;
 	}
 	return {grp:grp, label:label};
-}
-
-{% endblock %}
+}
\ No newline at end of file
diff --git a/erpnext/website/templates/login/login.js b/erpnext/website/templates/login/login.js
deleted file mode 100644
index d6b6b24..0000000
--- a/erpnext/website/templates/login/login.js
+++ /dev/null
@@ -1,103 +0,0 @@
-{% extends "page.html" %}
-
-{% block javascript %}
-{{ super() }}
-// Copyright (c) 2012 Web Notes Technologies Pvt Ltd (http://erpnext.com)
-// 
-// MIT License (MIT)
-// 
-// Permission is hereby granted, free of charge, to any person obtaining a 
-// copy of this software and associated documentation files (the "Software"), 
-// to deal in the Software without restriction, including without limitation 
-// the rights to use, copy, modify, merge, publish, distribute, sublicense, 
-// and/or sell copies of the Software, and to permit persons to whom the 
-// Software is furnished to do so, subject to the following conditions:
-// 
-// The above copyright notice and this permission notice shall be included in 
-// all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 
-// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 
-// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 
-// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
-// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
-// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// 
-
-wn.provide('erpnext.login');
-
-wn.pages["{{ name }}"].onload = function(wrapper) {
-	wrapper.appframe = new wn.ui.AppFrame($(wrapper).find('.appframe-area'));
-	wrapper.appframe.title('Login');
-	wrapper.appframe.$w.find('.close').toggle(false);
-
-	var lw = $i('login_wrapper');
-	$bs(lw, '1px 1px 3px #888');
-
-	$('#login_btn').click(erpnext.login.doLogin)
-		
-	$('#password').keypress(function(ev){
-		if(ev.which==13 && $('#password').val()) {
-			$('form').submit(function() {
-				erpnext.login.doLogin();
-				return false;
-			});
-		}
-	});
-	$(document).trigger('login_rendered');
-}
-
-// Login Callback
-erpnext.login.onLoginReply = function(r, rtext) {
-	$('#login_btn').done_working();
-    if(r.message=="Logged In"){
-        window.location.href='app.html' + (get_url_arg('page') ? ('?page='+get_url_arg('page')) : '');
-    } else {
-        $i('login_message').innerHTML = '<span style="color: RED;">'+(r.message)+'</span>';
-        //if(r.exc)alert(r.exc);
-    }
-}
-
-
-// Login
-erpnext.login.doLogin = function(){
-
-    var args = {};
-    args['usr']=$i("login_id").value;
-    args['pwd']=$i("password").value;
-    if($i('remember_me').checked) 
-      args['remember_me'] = 1;
-
-	$('#login_btn').set_working();
-	
-    $c("login", args, erpnext.login.onLoginReply);
-
-	return false;
-}
-
-
-erpnext.login.show_forgot_password = function(){
-    // create dialog
-	var d = new wn.ui.Dialog({
-		title:"Forgot Password",
-		fields: [
-			{'label':'Email Id', 'fieldname':'email_id', 'fieldtype':'Data', 'reqd':true},
-			{'label':'Email Me A New Password', 'fieldname':'run', 'fieldtype':'Button'}
-		]
-	});
-
-	$(d.fields_dict.run.input).click(function() {
-		var values = d.get_values();
-		if(!values) return;
-		wn.call({
-			method:'reset_password',
-			args: { user: values.email_id },
-			callback: function() {
-				d.hide();
-			}
-		})
-	})
-	d.show();
-}
-
-{% endblock %}
\ No newline at end of file
diff --git a/erpnext/website/templates/404.html b/erpnext/website/templates/pages/404.html
similarity index 90%
rename from erpnext/website/templates/404.html
rename to erpnext/website/templates/pages/404.html
index 8a30892..0423608 100644
--- a/erpnext/website/templates/404.html
+++ b/erpnext/website/templates/pages/404.html
@@ -1,4 +1,4 @@
-{% extends "outer.html" %}
+{% extends "html/outer.html" %}
 
 {% block content %}
 <div class="content">
diff --git a/erpnext/website/templates/blog/blog_list.html b/erpnext/website/templates/pages/blog.html
similarity index 80%
rename from erpnext/website/templates/blog/blog_list.html
rename to erpnext/website/templates/pages/blog.html
index 242f814..40c90c2 100644
--- a/erpnext/website/templates/blog/blog_list.html
+++ b/erpnext/website/templates/pages/blog.html
@@ -1,17 +1,15 @@
-{% extends "blog/blog_list.js" %}
+{% extends "html/page.html" %}
 
-{% block title %}Blog{% endblock %}
+{% block javascript %}
+	{% include "js/blog.js" %}
+{% endblock %}
 
 {% block css %}
-	<style>
-		h2 > a, h2 > a:link, h2 > a:visited, h2 > a:active,
-		h2 > a:hover, h2 > a:focus {
-			text-decoration: none;
-			color: inherit;
-		}
-	</style>
+	{% include "css/blog.css" %}
 {% endblock %}
 
+{% block title %}Blog{% endblock %}
+
 {% block content %}
 	<div class="layout-wrapper layout-wrapper-background">
 		<div class="web-content" id="content-blog">
diff --git a/erpnext/website/templates/pages/index.html b/erpnext/website/templates/pages/index.html
new file mode 100644
index 0000000..1307872
--- /dev/null
+++ b/erpnext/website/templates/pages/index.html
@@ -0,0 +1 @@
+{% extends "html/web_page.html" %}
\ No newline at end of file
diff --git a/erpnext/website/templates/login/login.html b/erpnext/website/templates/pages/login.html
similarity index 86%
rename from erpnext/website/templates/login/login.html
rename to erpnext/website/templates/pages/login.html
index 62d252f..9bc3171 100644
--- a/erpnext/website/templates/login/login.html
+++ b/erpnext/website/templates/pages/login.html
@@ -1,4 +1,12 @@
-{% extends "login/login.js" %}
+{% extends "html/page.html" %}
+
+{% block javascript %}
+	{% include "js/login.js" %}
+{% endblock %}
+
+{% block css %}
+	{% include "css/login.css" %}
+{% endblock %}
 
 {% block title %}
 	Login Page
@@ -41,17 +49,4 @@
 	</div>
 	</div>
 
-{% endblock %}
-
-{% block css %}
-	<style>
-		#login_wrapper {
-			width: 300px !important;
-			margin: 20px auto;
-		}
-
-		.login-banner {
-			margin-bottom: 20px;
-		}
-	</style>
 {% endblock %}
\ No newline at end of file
diff --git a/erpnext/website/templates/product/product_list.html b/erpnext/website/templates/pages/products.html
similarity index 80%
rename from erpnext/website/templates/product/product_list.html
rename to erpnext/website/templates/pages/products.html
index c8dfd24..aa23ea2 100644
--- a/erpnext/website/templates/product/product_list.html
+++ b/erpnext/website/templates/pages/products.html
@@ -1,4 +1,12 @@
-{% extends "product/product_list.js" %}
+{% extends "html/page.html" %}
+
+{% block javascript %}
+	{% include "js/products.js" %}
+{% endblock %}
+
+{% block css %}
+	{% include "css/products.css" %}
+{% endblock %}
 
 {% block title %}
 	Products
@@ -26,18 +34,4 @@
 			<div style="clear: both"></div>
 		</div>
 	</div>
-{% endblock %}
-
-{% block css %}
-	<style>
-		.img-area {
-			float:left;
-			width: 115px;
-		}
-		
-		.product-list-description {
-			float:left;
-			width: 400px;
-		}
-	</style>
 {% endblock %}
\ No newline at end of file
diff --git a/erpnext/website/utils.py b/erpnext/website/utils.py
index 06bb60d..22fcce7 100644
--- a/erpnext/website/utils.py
+++ b/erpnext/website/utils.py
@@ -17,6 +17,12 @@
 import webnotes
 from webnotes.model.doc import Document
 
+def scrub_page_name(page_name):
+	if page_name.endswith('.html'):
+		page_name = page_name[:-5]
+
+	return page_name
+
 def make_template(doc, path, convert_fields = ['main_section', 'side_section']):
 	"""make template"""
 	import os, jinja2
@@ -35,82 +41,3 @@
 	name = title.lower()
 	name = re.sub('[~!@#$%^&*()<>,."\']', '', name)
 	return '-'.join(name.split()[:4])
-
-def get_header(page_name):
-	"""get page header"""
-
-	from webnotes.model.doc import Document
-	from jinja2 import Template
-	import webnotes.utils
-
-	def get_item(l, label):
-		for i in l:
-			if i['label']==label:
-				return i
-
-	top_bar_items = webnotes.conn.sql("""select * from `tabTop Bar Item`
-		where parent='Website Settings' and parentfield='top_bar_items'
-		order by idx asc""", as_dict=1)
-		
-	# build child items
-	for t in top_bar_items:
-		if t.get('parent_label'):
-			pi = get_item(top_bar_items, t['parent_label'])
-			if 'child_items' not in pi:
-				pi['child_items'] = []
-			pi['child_items'].append(t)
-
-	website_settings = Document('Website Settings', 'Website Settings')
-	
-	return Template("""<div class="navbar navbar-fixed-top">
-		<div class="navbar-inner">
-		<div class="container">
-			<a class="brand" href="index.html">{{ brand }}</a>
-			<ul class="nav">
-				{% for page in top_bar_items %}
-					{% if not page.parent_label %}
-					<li data-label="{{ page.label }}">
-						<a href="{{ page.url }}" {{ page.target }}>
-						{{ page.label }}
-						{% if page.child_items %}
-							<ul class="dropdown-menu">
-							{% for child in page.child_items %}
-								<li data-label="{{ child.label }}">
-									<a href="{{ child.url }}" {{ child.target }}>
-							{% endfor %}
-							</ul>
-						{% endif %}
-						</a></li>
-					{% endif %}
-				{% endfor %}
-			</ul>
-			<img src="images/lib/ui/spinner.gif" id="spinner"/>
-			<ul class="nav pull-right">
-				<li id="login-topbar-item"><a href="login-page.html">Login</a></li>
-			</ul>
-		</div>
-		</div>
-		</div>""").render(top_bar_items = top_bar_items, 
-			brand=website_settings.brand_html or webnotes.utils.get_defaults('company') or 'ERPNext')
-			
-def get_footer(page_name):
-	"""get page footer"""
-	
-	from webnotes.model.doc import Document
-	from jinja2 import Template
-
-	website_settings = Document('Website Settings', 'Website Settings')
-
-	website_settings.footer_items = webnotes.conn.sql("""select * from `tabTop Bar Item`
-		where parent='Website Settings' and parentfield='footer_items'
-		order by idx asc""", as_dict=1)
-
-	return Template("""<div class="web-footer">
-		<div class="web-footer-menu"><ul>
-		{% for item in footer_items %}
-			<li><a href="{{ item.url }}" {{ item.target }}
-				data-label="{{ item.label }}">{{ item.label }}</a></li>
-		{% endfor %}
-		</ul></div>
-		<div class="web-footer-copyright">&copy; {{ copyright }}
-		</div>""").render(website_settings.fields)
\ No newline at end of file
diff --git a/erpnext/website/web_cache.py b/erpnext/website/web_cache.py
index 0221f47..d332802 100644
--- a/erpnext/website/web_cache.py
+++ b/erpnext/website/web_cache.py
@@ -14,108 +14,136 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-page_exception_list = ['404', 'blog', 'products', 'login-page']
+# html generation functions
 
-# used by web.py
-def load_from_web_cache(page_name, comments, template):
-	"""
-		* search for page in cache
-		* if html exists, return
-		* if not, build html, store it in cache, return
-	"""
-	import webnotes
+template_map = {
+	'Web Page': 'html/web_page.html',
+	'Blog': 'html/blog_page.html',
+	'Item': 'html/product_page.html',
+}
+
+def get_html(page_name, comments=''):
 	import conf
+	
+	html = ''
+	
+	# load from cache, if auto cache clear is falsy
+	if not (hasattr(conf, 'auto_cache_clear') and conf.auto_cache_clear or 0):
+		html = load_from_cache(page_name)
 
-	res = webnotes.conn.sql("""\
-		select html, doc_type, doc_name from `tabWeb Cache`
-		where name = %s""", page_name)
-	
-	# if page doesn't exist, raise exception
-	if not res and page_name not in page_exception_list + ['index']:
-		raise Exception, "Page %s not found" % page_name
-	
-	html, doc_type, doc_name = res and res[0] or (None, None, None)
-	auto_cache_clear = hasattr(conf, 'auto_cache_clear') and conf.auto_cache_clear or 0
-	if not html or auto_cache_clear:
+	if not html:
+		html = load_into_cache(page_name)
 		comments += "\n\npage load status: fresh"
-		html = load_into_web_cache(page_name, template, doc_type, doc_name)
-	else:
-		comments += "\n\npage load status: cached"
-
-	from webnotes.utils import cstr
-	html += """\n<!-- %s -->""" % cstr(comments)
+	
+	# insert comments
+	import webnotes.utils
+	html += """\n<!-- %s -->""" % webnotes.utils.cstr(comments)
 	
 	return html
 
-def load_into_web_cache(page_name, template, doc_type, doc_name):
-	"""build html and store it in web cache"""
+def load_from_cache(page_name):
 	import webnotes
+	
+	result = search_cache(page_name)
 
-	args = prepare_args(page_name, doc_type, doc_name)
+	if not result:
+		if page_name in get_predefined_pages():
+			# if a predefined page doesn't exist, load it into cache
+			return None
+		else:
+			# if page doesn't exist, raise exception
+			raise Exception, "Page %s not found" % page_name
+
+	return result[0][0]
+
+def load_into_cache(page_name):
+	args = prepare_args(page_name)
 	
-	# decide template and update args
-	if doc_type == 'Web Page':
-		template = 'web_page.html'
-	else:
-		args.update({ 'insert_code': 1 })
-		if doc_type == 'Blog':
-			template = 'blog/blog.html'
-		elif doc_type == 'Item':
-			template = 'product/product.html'
-		elif page_name == 'blog':
-			template = 'blog/blog_list.html'
-		elif page_name == 'products':
-			template = 'product/product_list.html'
-		elif page_name == 'login-page':
-			template = 'login/login.html'
+	html = build_html(args)
 	
-	html = build_html(args, template)
+	# create cache entry for predefined pages, if not exists
+	if page_name in get_predefined_pages():
+		create_cache(page_name)
 	
-	# save html in web cache
+	import webnotes
 	webnotes.conn.begin()
-	if page_name in page_exception_list + ['index']:
-		clear_web_cache(doc_type, doc_name, page_name)
 	webnotes.conn.set_value('Web Cache', page_name, 'html', html)
 	webnotes.conn.commit()
 	
 	return html
-	
-def prepare_args(page_name, doc_type, doc_name, with_outer_env=1):
-	if page_name == 'index':
-		page_name, doc_type, doc_name = get_index_page()
 
-	if page_name in page_exception_list:
+def get_predefined_pages():
+	"""
+		gets a list of predefined pages
+		they do not exist in `tabWeb Page`
+	"""
+	import os
+	import conf
+	import website.utils
+	
+	pages_path = os.path.join(conf.modules_path, 'website', 'templates', 'pages')
+	
+	page_list = []
+	
+	for page in os.listdir(pages_path):
+		page_list.append(website.utils.scrub_page_name(page))
+
+	return page_list
+
+def prepare_args(page_name):
+	if page_name == 'index':
+		page_name = get_home_page()
+
+	if page_name in get_predefined_pages():
 		args = {
+			'template': 'pages/%s.html' % page_name,
 			'name': page_name,
 		}
 	else:
-		from webnotes.model.code import get_obj
-		obj = get_obj(doc_type, doc_name)
-		if hasattr(obj, 'prepare_template_args'):
-			obj.prepare_template_args()
-		args = obj.doc.fields
+		args = get_doc_fields(page_name)
+	
+	args.update(get_outer_env())
+	
+	return args
+	
+def get_home_page():
+	import webnotes
+	doc_name = webnotes.conn.get_value('Website Settings', None, 'home_page')
+	if doc_name:
+		page_name = webnotes.conn.get_value('Web Page', doc_name, 'page_name')
+	else:
+		page_name = 'login'
 
-	outer_env_dict = with_outer_env and get_outer_env() or {}
-	args.update(outer_env_dict)
+	return page_name
+
+def get_doc_fields(page_name):
+	import webnotes
+	doc_type, doc_name = webnotes.conn.get_value('Web Cache', page_name, ['doc_type', 'doc_name'])
+	
+	import webnotes.model.code
+	obj = webnotes.model.code.get_obj(doc_type, doc_name)
+	
+	if hasattr(obj, 'prepare_template_args'):
+		obj.prepare_template_args()
+		
+	args = obj.doc.fields
+	args['template'] = template_map[doc_type]
 	
 	return args
 
-def build_html(args, template):
-	"""build html using jinja2 templates"""
-	from jinja2 import Environment, FileSystemLoader
-	jenv = Environment(loader = FileSystemLoader('../erpnext/website/templates'))
-	html = jenv.get_template(template).render(args)
-	return html
-
 def get_outer_env():
-	"""env dict for outer template"""
+	"""
+		env dict for outer template
+	"""
 	import webnotes
 	return {
-		'top_bar_items': webnotes.conn.sql("""select * from `tabTop Bar Item`
+		'top_bar_items': webnotes.conn.sql("""\
+			select * from `tabTop Bar Item`
 			where parent='Website Settings' and parentfield='top_bar_items'
 			order by idx asc""", as_dict=1),
 	
-		'footer_items': webnotes.conn.sql("""select * from `tabTop Bar Item`
+		'footer_items': webnotes.conn.sql("""\
+			select * from `tabTop Bar Item`
 			where parent='Website Settings' and parentfield='footer_items'
 			order by idx asc""", as_dict=1),
 			
@@ -124,44 +152,62 @@
 		'favicon': webnotes.conn.get_value('Website Settings', None, 'favicon')
 	}
 
-def get_index_page():
-	import webnotes
-	doc_type = 'Web Page'
-	doc_name = webnotes.conn.get_value('Website Settings', None, 'home_page')
-	page_name = webnotes.conn.get_value(doc_type, doc_name, 'page_name')
-	if not page_name:
-		page_name = 'login-page'
-	return page_name, doc_type, doc_name
+def build_html(args):
+	"""
+		build html using jinja2 templates
+	"""
+	import os
+	import conf
+	templates_path = os.path.join(conf.modules_path, 'website', 'templates')
+	
+	from jinja2 import Environment, FileSystemLoader
+	jenv = Environment(loader = FileSystemLoader(templates_path))
+	html = jenv.get_template(args['template']).render(args)
+	return html
 
 # cache management
-def clear_web_cache(doc_type, doc_name, page_name):
-	"""
-		* check if a record corresponding to (type, name) exists
-		* if exists, just clear html column
-		* if does not exist, create a record for (type, name)
-		* if a record like (some other type, name) exists, raise exception that the page name is not unique
-	"""
+def search_cache(page_name):
 	import webnotes
-	res = webnotes.conn.get_value('Web Cache', page_name, ['doc_type', 'name'])
-	if not res:
-		import webnotes.model.doc
-		d = webnotes.model.doc.Document('Web Cache')
-		d.name = page_name
-		d.doc_type = doc_type
-		d.doc_name = doc_name
-		d.html = None
-		d.save()
-	elif not doc_type or res[0] == doc_type:
-		webnotes.conn.set_value('Web Cache', page_name, 'html', None)
+	return webnotes.conn.sql("""\
+		select html, doc_type, doc_name
+		from `tabWeb Cache`
+		where name = %s""", page_name)
+
+def create_cache(page_name, doc_type=None, doc_name=None):
+	# check if a record already exists
+	result = search_cache(page_name)
+	if result: return
+	
+	# create a Web Cache record
+	import webnotes.model.doc
+	d = webnotes.model.doc.Document('Web Cache')
+	d.name = page_name
+	d.doc_type = doc_type
+	d.doc_name = doc_name
+	d.html = None
+	d.save()
+
+def clear_cache(page_name, doc_type=None, doc_name=None):
+	"""
+		* if no page name, clear whole cache
+		* if page_name, doc_type and doc_name match, clear cache's copy
+		* else, raise exception that such a page already exists
+	"""
+	if not page_name:
+		webnotes.conn.sql("""update `tabWeb Cache` set html = ''""")
+		return
+	
+	result = search_cache(page_name)
+	
+	import webnotes
+	if not doc_type or (result and result[0][1] == doc_type and result[0][2] == doc_name):
+		webnotes.conn.set_value('Web Cache', page_name, 'html', '')
 	else:
 		webnotes.msgprint("""Page with name "%s" already exists as a %s.
-			Please save it with another name.""" % (page_name, res[0]), raise_exception=1)
-		
-def clear_all_web_cache():
-	import webnotes
-	webnotes.conn.sql("update `tabWeb Cache` set html = NULL")
-		
-def delete_web_cache(page_name):
+			Please save it with another name.""" % (page_name, result[0][1]),
+			raise_exception=1)
+
+def delete_cache(page_name):
 	"""
 		delete entry of page_name from Web Cache
 		used when:
@@ -169,33 +215,29 @@
 			* blog is un-published
 	"""
 	import webnotes
-	webnotes.conn.sql("""\
-		delete from `tabWeb Cache`
-		where name=%s""", page_name)
-		
-def rebuild_web_cache():
-	"""build web cache entries"""
+	webnotes.conn.sql("""delete from `tabWeb Cache` where name=%s""", page_name)
+
+def refresh_cache():
+	"""delete and re-create web cache entries"""
 	import webnotes
-	from webnotes.model.doclist import DocList
-	save_list = [
-		{
-			'doctype': 'Web Page',
-			'query': """select name from `tabWeb Page` where docstatus=0"""
-		},
-		{
-			'doctype': 'Blog',
-			'query': """\
-				select name from `tabBlog`
-				where docstatus = 0 and ifnull(published, 0) = 1"""
-		},
-		{
-			'doctype': 'Item',
-			'query': """\
-				select name from `tabItem`
-				where docstatus = 0 and ifnull(show_in_website, 0) = 1"""
-		}
-	]
 	
-	for s in save_list:
-		for p in webnotes.conn.sql(s['query'], as_dict=1):
-			DocList(s['doctype'], p['name']).save()
\ No newline at end of file
+	webnotes.conn.sql("delete from `tabWeb Cache`")
+	
+	query_map = {
+		'Web Page': """select page_name, name from `tabWeb Page` where docstatus=0""",
+		'Blog': """\
+			select page_name, name from `tabBlog`
+			where docstatus = 0 and ifnull(published, 0) = 1""",
+		'Item': """\
+			select page_name, name from `tabItem`
+			where docstatus = 0 and ifnull(show_in_website, 0) = 1""",
+	}
+
+	for dt in query_map:
+		for result in webnotes.conn.sql(query_map[dt], as_dict=1):
+			create_cache(result['page_name'], dt, result['name'])
+			clear_cache(result['page_name'], dt, result['name'])
+			
+	for page_name in get_predefined_pages():
+		create_cache(page_name, None, None)
+		clear_cache(page_name, None, None)
\ No newline at end of file
diff --git a/erpnext/website/web_page.py b/erpnext/website/web_page.py
index 58ff40b..e03ff0d 100644
--- a/erpnext/website/web_page.py
+++ b/erpnext/website/web_page.py
@@ -64,11 +64,12 @@
 				self.old_page_name != self.doc.page_name:
 			self.delete_web_cache(self.old_page_name)
 		
-		website.web_cache.clear_web_cache(self.doctype, self.doc.name, self.doc.page_name)
+		website.web_cache.create_cache(self.doc.page_name, self.doc.doctype, self.doc.name)
+		website.web_cache.clear_cache(self.doc.page_name, self.doc.doctype, self.doc.name)
 		
 	def delete_web_cache(self, page_name):
 		"""delete entry of page name from Web Cache"""
-		website.web_cache.delete_web_cache(page_name)
+		website.web_cache.delete_cache(page_name)
 
 	def markdown_to_html(self, fields_list):
 		"""convert fields from markdown to html"""