Index: inc/public/class.dc.template.php
===================================================================
--- inc/public/class.dc.template.php	(revision 415)
+++ inc/public/class.dc.template.php	(revision 270)
@@ -54,4 +54,18 @@
 		$this->addValue('ArchiveEntriesCount',array($this,'ArchiveEntriesCount'));
 		$this->addValue('ArchiveURL',array($this,'ArchiveURL'));
+		
+		# Attachments
+		$this->addBlock('Attachments',array($this,'Attachments'));
+		$this->addBlock('AttachmentsHeader',array($this,'AttachmentsHeader'));
+		$this->addBlock('AttachmentsFooter',array($this,'AttachmentsFooter'));
+		$this->addValue('AttachmentMimeType',array($this,'AttachmentMimeType'));
+		$this->addValue('AttachmentType',array($this,'AttachmentType'));
+		$this->addValue('AttachmentFileName',array($this,'AttachmentFileName'));
+		$this->addValue('AttachmentSize',array($this,'AttachmentSize'));
+		$this->addValue('AttachmentTitle',array($this,'AttachmentTitle'));
+		$this->addValue('AttachmentThumbnailURL',array($this,'AttachmentThumbnailURL'));
+		$this->addValue('AttachmentURL',array($this,'AttachmentURL'));
+		$this->addBlock('AttachmentIf',array($this,'AttachmentIf'));
+		$this->addValue('MediaURL',array($this,'MediaURL'));
 		
 		# Blog
@@ -127,4 +141,5 @@
 		$this->addBlock('EntriesHeader',array($this,'EntriesHeader'));
 		$this->addValue('EntryExcerpt',array($this,'EntryExcerpt'));
+		$this->addValue('EntryAttachmentCount',array($this,'EntryAttachmentCount'));
 		$this->addValue('EntryAuthorCommonName',array($this,'EntryAuthorCommonName'));
 		$this->addValue('EntryAuthorDisplayName',array($this,'EntryAuthorDisplayName'));
@@ -308,10 +323,4 @@
 		}
 		
-		if (($node instanceof tplNodeBlock) && !$node->isClosed()) {
-			$errors[] = sprintf(
-				__('Did not find closing tag for block <tpl:%s>. Content has been ignored.'),
-				html::escapeHTML($node->getTag()));
-		}
-		
 		$err = "";
 		if (count($errors) > 0) {
@@ -332,7 +341,4 @@
 		# --BEHAVIOR-- templateBeforeBlock
 		$res = $this->core->callBehavior('templateBeforeBlock',$this->core,$this->current_tag,$attr);
-		
-		# --BEHAVIOR-- templateInsideBlock
-		$this->core->callBehavior('templateInsideBlock',$this->core,$this->current_tag,$attr,array(&$content));
 		
 		if (isset($this->blocks[$this->current_tag])) {
@@ -557,5 +563,5 @@
 		}
 		
-		if (empty($attr['no_context']) && !isset($attr['category']))
+		if (empty($attr['no_context']))
 		{
 			$p .=
@@ -734,4 +740,173 @@
 	}
 	
+	/* Attachments ---------------------------------------- */
+	/*dtd
+	<!ELEMENT tpl:Attachments - - -- Post Attachments loop -->
+	*/
+	public function Attachments($attr,$content)
+	{
+		$res =
+		"<?php\n".
+		'if ($_ctx->posts !== null && $core->media) {'."\n".
+			'$_ctx->attachments = new ArrayObject($core->media->getPostMedia($_ctx->posts->post_id));'."\n".
+		"?>\n".
+		
+		'<?php foreach ($_ctx->attachments as $attach_i => $attach_f) : '.
+		'$GLOBALS[\'attach_i\'] = $attach_i; $GLOBALS[\'attach_f\'] = $attach_f;'.
+		'$_ctx->file_url = $attach_f->file_url; ?>'.
+		$content.
+		'<?php endforeach; $_ctx->attachments = null; unset($attach_i,$attach_f,$_ctx->file_url); ?>'.
+		
+		"<?php } ?>\n";
+		
+		return $res;
+	}
+	
+	/*dtd
+	<!ELEMENT tpl:AttachmentsHeader - - -- First attachments result container -->
+	*/
+	public function AttachmentsHeader($attr,$content)
+	{
+		return
+		"<?php if (\$attach_i == 0) : ?>".
+		$content.
+		"<?php endif; ?>";
+	}
+	
+	/*dtd
+	<!ELEMENT tpl:AttachmentsFooter - - -- Last attachments result container -->
+	*/
+	public function AttachmentsFooter($attr,$content)
+	{
+		return
+		"<?php if (\$attach_i+1 == count(\$_ctx->attachments)) : ?>".
+		$content.
+		"<?php endif; ?>";
+	}
+	
+	/*dtd
+	<!ELEMENT tpl:AttachmentsIf - - -- Test on attachment fields -->
+	<!ATTLIST tpl:AttachmentIf
+	is_image	(0|1)	#IMPLIED	-- test if attachment is an image (value : 1) or not (value : 0)
+	has_thumb	(0|1)	#IMPLIED	-- test if attachment has a square thumnail (value : 1) or not (value : 0)
+	is_mp3	(0|1)	#IMPLIED	-- test if attachment is a mp3 file (value : 1) or not (value : 0)
+	is_flv	(0|1)	#IMPLIED	-- test if attachment is a flv file (value : 1) or not (value : 0)
+	>
+	*/
+	public function AttachmentIf($attr,$content)
+	{
+		$if = array();
+		
+		$operator = isset($attr['operator']) ? $this->getOperator($attr['operator']) : '&&';
+		
+		if (isset($attr['is_image'])) {
+			$sign = (boolean) $attr['is_image'] ? '' : '!';
+			$if[] = $sign.'$attach_f->media_image';
+		}
+		
+		if (isset($attr['has_thumb'])) {
+			$sign = (boolean) $attr['has_thumb'] ? '' : '!';
+			$if[] = $sign.'isset($attach_f->media_thumb[\'sq\'])';
+		}
+		
+		if (isset($attr['is_mp3'])) {
+			$sign = (boolean) $attr['is_mp3'] ? '==' : '!=';
+			$if[] = '$attach_f->type '.$sign.' "audio/mpeg3"';
+		}
+		
+		if (isset($attr['is_flv'])) {
+			$sign = (boolean) $attr['is_flv'] ? '' : '!';
+			$if[] = $sign.
+				'($attach_f->type == "video/x-flv" || '.
+				'$attach_f->type == "video/mp4" || '.
+				'$attach_f->type == "video/x-m4v")';
+		}
+		
+		if (!empty($if)) {
+			return '<?php if('.implode(' '.$operator.' ',$if).') : ?>'.$content.'<?php endif; ?>';
+		} else {
+			return $content;
+		}
+	}
+	
+	/*dtd
+	<!ELEMENT tpl:AttachmentMimeType - O -- Attachment MIME Type -->
+	*/
+	public function AttachmentMimeType($attr)
+	{
+		$f = $this->getFilters($attr);
+		return '<?php echo '.sprintf($f,'$attach_f->type').'; ?>';
+	}
+	
+	/*dtd
+	<!ELEMENT tpl:AttachmentType - O -- Attachment type -->
+	*/
+	public function AttachmentType($attr)
+	{
+		$f = $this->getFilters($attr);
+		return '<?php echo '.sprintf($f,'$attach_f->media_type').'; ?>';
+	}
+	
+	/*dtd
+	<!ELEMENT tpl:AttachmentFileName - O -- Attachment file name -->
+	*/
+	public function AttachmentFileName($attr)
+	{
+		$f = $this->getFilters($attr);
+		return '<?php echo '.sprintf($f,'$attach_f->basename').'; ?>';
+	}
+	
+	/*dtd
+	<!ELEMENT tpl:AttachmentSize - O -- Attachment size -->
+	<!ATTLIST tpl:AttachmentSize
+	full	CDATA	#IMPLIED	-- if set, size is rounded to a human-readable value (in KB, MB, GB, TB)
+	>
+	*/
+	public function AttachmentSize($attr)
+	{
+		$f = $this->getFilters($attr);
+		if (!empty($attr['full'])) {
+			return '<?php echo '.sprintf($f,'$attach_f->size').'; ?>';
+		}
+		return '<?php echo '.sprintf($f,'files::size($attach_f->size)').'; ?>';
+	}
+	
+	/*dtd
+	<!ELEMENT tpl:AttachmentTitle - O -- Attachment title -->
+	*/
+	public function AttachmentTitle($attr)
+	{
+		$f = $this->getFilters($attr);
+		return '<?php echo '.sprintf($f,'$attach_f->media_title').'; ?>';
+	}
+	
+	/*dtd
+	<!ELEMENT tpl:AttachmentThumbnailURL - O -- Attachment square thumbnail URL -->
+	*/
+	public function AttachmentThumbnailURL($attr)
+	{
+		$f = $this->getFilters($attr);
+		return
+		'<?php '.
+		'if (isset($attach_f->media_thumb[\'sq\'])) {'.
+			'echo '.sprintf($f,'$attach_f->media_thumb[\'sq\']').';'.
+		'}'.
+		'?>';
+	}
+	
+	/*dtd
+	<!ELEMENT tpl:AttachmentURL - O -- Attachment URL -->
+	*/
+	public function AttachmentURL($attr)
+	{
+		$f = $this->getFilters($attr);
+		return '<?php echo '.sprintf($f,'$attach_f->file_url').'; ?>';
+	}
+	
+	public function MediaURL($attr)
+	{
+		$f = $this->getFilters($attr);
+		return '<?php echo '.sprintf($f,'$_ctx->file_url').'; ?>';
+	}
 	
 	/* Blog ----------------------------------------------- */
@@ -976,5 +1151,5 @@
 	public function CategoryIf($attr,$content)
 	{
-		$if = new ArrayObject();
+		$if = array();
 		$operator = isset($attr['operator']) ? $this->getOperator($attr['operator']) : '&&';
 		
@@ -999,8 +1174,6 @@
 		} 
 		
-		$this->core->callBehavior('tplIfConditions','CategoryIf',$attr,$content,$if);
-		
-		if (count($if) != 0) {
-			return '<?php if('.implode(' '.$operator.' ', (array) $if).') : ?>'.$content.'<?php endif; ?>';
+		if (!empty($if)) {
+			return '<?php if('.implode(' '.$operator.' ',$if).') : ?>'.$content.'<?php endif; ?>';
 		} else {
 			return $content;
@@ -1151,19 +1324,13 @@
 		if (empty($attr['no_context']))
 		{
-			if (!isset($attr['author']))
-			{
-				$p .=
-				'if ($_ctx->exists("users")) { '.
-					"\$params['user_id'] = \$_ctx->users->user_id; ".
-				"}\n";
-			}
+			$p .=
+			'if ($_ctx->exists("users")) { '.
+				"\$params['user_id'] = \$_ctx->users->user_id; ".
+			"}\n";
 			
-			if (!isset($attr['category']) && (!isset($attr['no_category']) || !$attr['no_category']))
-			{
-				$p .=
-				'if ($_ctx->exists("categories")) { '.
-					"\$params['cat_id'] = \$_ctx->categories->cat_id; ".
-				"}\n";
-			}
+			$p .=
+			'if ($_ctx->exists("categories")) { '.
+				"\$params['cat_id'] = \$_ctx->categories->cat_id; ".
+			"}\n";
 			
 			$p .=
@@ -1249,5 +1416,5 @@
 	selected	(0|1)	#IMPLIED	-- post is selected (value : 1) or not (value : 0)
 	has_category	(0|1)	#IMPLIED	-- post has a category (value : 1) or not (value : 0)
-	has_attachment	(0|1)	#IMPLIED	-- post has attachments (value : 1) or not (value : 0) (see Attachment plugin for code)
+	has_attachment	(0|1)	#IMPLIED	-- post has attachments (value : 1) or not (value : 0)
 	comments_active	(0|1)	#IMPLIED	-- comments are active for this post (value : 1) or not (value : 0)
 	pings_active	(0|1)	#IMPLIED	-- trackbacks are active for this post (value : 1) or not (value : 0)
@@ -1260,5 +1427,5 @@
 	public function EntryIf($attr,$content)
 	{
-		$if = new ArrayObject();
+		$if = array();
 		$extended = null;
 		$hascategory = null;
@@ -1317,4 +1484,9 @@
 		}
 		
+		if (isset($attr['has_attachment'])) {
+			$sign = (boolean) $attr['has_attachment'] ? '' : '!';
+			$if[] = $sign.'$_ctx->posts->countMedia()';
+		}
+		
 		if (isset($attr['comments_active'])) {
 			$sign = (boolean) $attr['comments_active'] ? '' : '!';
@@ -1353,8 +1525,6 @@
 		}
 		
-		$this->core->callBehavior('tplIfConditions','EntryIf',$attr,$content,$if);
-		
-		if (count($if) != 0) {
-			return '<?php if('.implode(' '.$operator.' ', (array) $if).') : ?>'.$content.'<?php endif; ?>';
+		if (!empty($if)) {
+			return '<?php if('.implode(' '.$operator.' ',$if).') : ?>'.$content.'<?php endif; ?>';
 		} else {
 			return $content;
@@ -1451,4 +1621,37 @@
 	}
 	
+	/*dtd
+	<!ELEMENT tpl:EntryAttachmentCount - O -- Number of attachments for entry -->
+	<!ATTLIST tpl:EntryAttachmentCount
+	none	CDATA	#IMPLIED	-- text to display for "no attachment" (default: no attachment)
+	one	CDATA	#IMPLIED	-- text to display for "one attachment" (default: one attachment)
+	more	CDATA	#IMPLIED	-- text to display for "more attachment" (default: %s attachment, %s is replaced by the number of attachments)
+	>
+	*/
+	public function EntryAttachmentCount($attr)
+	{
+		$none = 'no attachment';
+		$one = 'one attachment';
+		$more = '%d attachments';
+		
+		if (isset($attr['none'])) {
+			$none = addslashes($attr['none']);
+		}
+		if (isset($attr['one'])) {
+			$one = addslashes($attr['one']);
+		}
+		if (isset($attr['more'])) {
+			$more = addslashes($attr['more']);
+		}
+		
+		return
+		"<?php if (\$_ctx->posts->countMedia() == 0) {\n".
+		"  printf(__('".$none."'),(integer) \$_ctx->posts->countMedia());\n".
+		"} elseif (\$_ctx->posts->countMedia() == 1) {\n".
+		"  printf(__('".$one."'),(integer) \$_ctx->posts->countMedia());\n".
+		"} else {\n".
+		"  printf(__('".$more."'),(integer) \$_ctx->posts->countMedia());\n".
+		"} ?>";
+	}
 	
 	/*dtd
@@ -2006,8 +2209,6 @@
 		}
 		
-		$this->core->callBehavior('tplIfConditions','PaginationIf',$attr,$content,$if);
-		
-		if (count($if) != 0) {
-			return '<?php if('.implode(' && ', (array) $if).') : ?>'.$content.'<?php endif; ?>';
+		if (!empty($if)) {
+			return '<?php if('.implode(' && ',$if).') : ?>'.$content.'<?php endif; ?>';
 		} else {
 			return $content;
@@ -2281,8 +2482,6 @@
 		}
 		
-		$this->core->callBehavior('tplIfConditions','CommentIf',$attr,$content,$if);
-		
-		if (count($if) != 0) {
-			return '<?php if('.implode(' && ', (array) $if).') : ?>'.$content.'<?php endif; ?>';
+		if (!empty($if)) {
+			return '<?php if('.implode(' && ',$if).') : ?>'.$content.'<?php endif; ?>';
 		} else {
 			return $content;
@@ -2774,5 +2973,5 @@
 	current_mode		CDATA	#IMPLIED	-- tests if current URL mode is the one given in parameter
 	has_tpl			CDATA     #IMPLIED  -- tests if a named template exists
-	has_tag			CDATA     #IMPLIED  -- tests if a named template tag exists (see Tag plugin for code)
+	has_tag			CDATA     #IMPLIED  -- tests if a named template tag exists
 	blog_id			CDATA     #IMPLIED  -- tests if current blog ID is the one given in parameter
 	comments_active	(0|1)	#IMPLIED	-- test if comments are enabled blog-wide 
@@ -2784,5 +2983,5 @@
 	public function SysIf($attr,$content)
 	{
-		$if = new ArrayObject();
+		$if = array();
 		$is_ping = null;
 		
@@ -2830,4 +3029,13 @@
 		}
 		
+		if (isset($attr['has_tag'])) {
+			$sign = '';
+			if (substr($attr['has_tag'],0,1) == '!') {
+				$sign = '!';
+				$attr['has_tag'] = substr($attr['has_tag'],1);
+			}
+			$if[] =  $sign."(\$core->tpl->tagExists('".addslashes($attr['has_tag'])."') )";
+		}
+		
 		if (isset($attr['blog_id'])) {
 			$sign = '';
@@ -2859,8 +3067,6 @@
 		}
 		
-		$this->core->callBehavior('tplIfConditions','SysIf',$attr,$content,$if);
-		
-		if (count($if) != 0) {
-			return '<?php if('.implode(' '.$operator.' ', (array) $if).') : ?>'.$content.'<?php endif; ?>';
+		if (!empty($if)) {
+			return '<?php if('.implode(' '.$operator.' ',$if).') : ?>'.$content.'<?php endif; ?>';
 		} else {
 			return $content;
@@ -3024,7 +3230,4 @@
 		$this->closed = true;
 	}
-	public function isClosed() {
-		return $this->closed;
-	}
 	public function compile($tpl) {
 		if ($this->closed) {
Index: inc/public/default-templates/tag.html
===================================================================
--- inc/public/default-templates/tag.html	(revision 199)
+++ inc/public/default-templates/tag.html	(revision 199)
@@ -0,0 +1,153 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="{{tpl:BlogLanguage}}" lang="{{tpl:BlogLanguage}}">
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+  <meta name="ROBOTS" content="{{tpl:BlogMetaRobots}}" />
+  
+  <title>{{tpl:lang Tag}} - {{tpl:TagID}} - {{tpl:BlogName encode_html="1"}}<tpl:PaginationIf start="0"> - {{tpl:lang page}} {{tpl:PaginationCurrent}}</tpl:PaginationIf></title>
+  <meta name="copyright" content="{{tpl:BlogCopyrightNotice encode_html="1"}}" />
+  <meta name="author" content="{{tpl:BlogEditor encode_html="1"}}" />
+  <meta name="date" scheme="W3CDTF" content="{{tpl:BlogUpdateDate iso8601="1"}}" />
+  
+  <link rel="schema.dc" href="http://purl.org/dc/elements/1.1/" />
+  <meta name="dc.title" lang="{{tpl:BlogLanguage}}" content="{{tpl:lang Tag}} - {{tpl:TagID}} - {{tpl:BlogName encode_html="1"}}<tpl:PaginationIf start="0"> - {{tpl:lang page}} {{tpl:PaginationCurrent}}</tpl:PaginationIf>" />
+  <meta name="dc.language" content="{{tpl:BlogLanguage}}" />
+  <meta name="dc.publisher" content="{{tpl:BlogEditor encode_html="1"}}" />
+  <meta name="dc.rights" content="{{tpl:BlogCopyrightNotice encode_html="1"}}" />
+  <meta name="dc.date" scheme="W3CDTF" content="{{tpl:BlogUpdateDate iso8601="1"}}" />
+  <meta name="dc.type" content="text" />
+  <meta name="dc.format" content="text/html" />
+  
+  <link rel="top" href="{{tpl:BlogURL}}" title="{{tpl:lang Home}}" />
+  <link rel="contents" href="{{tpl:BlogArchiveURL}}" title="{{tpl:lang Archives}}" />
+  
+  <tpl:Entries no_content="1">
+    <tpl:EntriesHeader>
+      <tpl:Pagination>
+        <tpl:PaginationIf end="0">
+        <link rel="prev" title="{{tpl:lang previous entries}}" href="{{tpl:PaginationURL offset="1"}}" />
+        </tpl:PaginationIf>
+        
+        <tpl:PaginationIf start="0">
+        <link rel="next" title="{{tpl:lang next entries}}" href="{{tpl:PaginationURL offset="-1"}}" />
+        </tpl:PaginationIf>
+      </tpl:Pagination>
+    </tpl:EntriesHeader>
+    
+    <link rel="chapter" href="{{tpl:EntryURL}}" title="{{tpl:EntryTitle encode_html="1"}}" />
+  </tpl:Entries>
+  
+  <link rel="alternate" type="application/atom+xml" title="Atom 1.0" href="{{tpl:TagFeedURL type="atom"}}" />
+  <link rel="meta" type="application/xbel+xml" title="Blogroll" href="{{tpl:BlogrollXbelLink}}" />
+  
+  {{tpl:include src="_head.html"}}
+</head>
+
+<body class="dc-tag">
+<div id="page">
+{{tpl:include src="_top.html"}}
+
+<div id="wrapper">
+
+<div id="main">
+  <div id="content">
+  
+  <div id="content-info">
+    <h2>{{tpl:lang Tag}} - {{tpl:TagID}}</h2>
+    
+    <p><a type="application/atom+xml" href="{{tpl:TagFeedURL type="atom"}}"
+    title="{{tpl:lang This tag's entries Atom feed}}" class="feed">{{tpl:lang Entries feed}}</a>
+    
+    <tpl:SysIf operator="or" comments_active="1" pings_active="1">
+    - <a type="application/atom+xml" href="{{tpl:TagFeedURL type="atom"}}/comments"
+    title="{{tpl:lang This tag's comments Atom feed}}" class="feed">{{tpl:lang Comments feed}}</a>
+    </tpl:SysIf>
+    </p>
+  </div>
+  
+  <tpl:Entries>
+    <div id="p{{tpl:EntryID}}" class="post {{tpl:EntryIfOdd}} {{tpl:EntryIfFirst}}" lang="{{tpl:EntryLang}}" xml:lang="{{tpl:EntryLang}}">
+    <!-- # New day date -->
+    <tpl:DateHeader><p class="day-date">{{tpl:EntryDate}}</p></tpl:DateHeader>
+    
+    <h2 class="post-title"><a
+    href="{{tpl:EntryURL}}">{{tpl:EntryTitle encode_html="1"}}</a></h2>
+    
+    <p class="post-info">{{tpl:lang By}} {{tpl:EntryAuthorLink}}
+    {{tpl:lang on}} {{tpl:EntryDate}}, {{tpl:EntryTime}}
+    <tpl:EntryIf has_category="1">
+    - <a href="{{tpl:EntryCategoryURL}}">{{tpl:EntryCategory encode_html="1"}}</a>
+    </tpl:EntryIf>
+    </p>
+    
+    <tpl:EntryTags>
+    <tpl:TagsHeader><ul class="post-tags"></tpl:TagsHeader>
+    <li><a href="{{tpl:TagURL}}">{{tpl:TagID}}</a></li>
+    <tpl:TagsFooter></ul></tpl:TagsFooter>
+    </tpl:EntryTags>
+    
+    <!-- # --BEHAVIOR-- publicEntryBeforeContent -->
+    {{tpl:SysBehavior behavior="publicEntryBeforeContent"}}
+    
+    <!-- # Entry with an excerpt -->
+    <tpl:EntryIf extended="1">
+      <div class="post-content">{{tpl:EntryExcerpt}}</div>
+      <p class="read-it"><a href="{{tpl:EntryURL}}"
+      title="{{tpl:lang Continue reading}} {{tpl:EntryTitle encode_html="1"}}">{{tpl:lang Continue
+      reading}}</a>...</p>
+    </tpl:EntryIf>
+    
+    <!-- # Entry without excerpt -->
+    <tpl:EntryIf extended="0">
+      <div class="post-content">{{tpl:EntryContent}}</div>
+    </tpl:EntryIf>
+    
+    <!-- # --BEHAVIOR-- publicEntryAfterContent -->
+    {{tpl:SysBehavior behavior="publicEntryAfterContent"}}
+    
+    <!-- # Number of comments, trackbacks and attachments -->
+    <tpl:EntryIf operator="or" show_comments="1" show_pings="1" has_attachment="1">
+      <p class="post-info-co">
+    </tpl:EntryIf>
+    <tpl:EntryIf show_comments="1">
+      <a href="{{tpl:EntryURL}}#comments" class="comment_count">{{tpl:EntryCommentCount}}</a>
+    </tpl:EntryIf>
+    <tpl:EntryIf show_pings="1">
+      <a href="{{tpl:EntryURL}}#pings" class="ping_count">{{tpl:EntryPingCount}}</a></tpl:EntryIf>
+    <tpl:EntryIf has_attachment="1">
+      <a href="{{tpl:EntryURL}}#attachments" class="attach_count">{{tpl:EntryAttachmentCount}}</a></tpl:EntryIf>
+    <tpl:EntryIf operator="or" show_comments="1" show_pings="1" has_attachment="1">
+      </p>
+    </tpl:EntryIf>
+    </div>
+    
+    <tpl:EntriesFooter>
+      <tpl:Pagination>
+        <p class="pagination"><tpl:PaginationIf end="0"><a href="{{tpl:PaginationURL offset="+1"}}" class="prev">&#171;
+        {{tpl:lang previous entries}}</a> - </tpl:PaginationIf>
+        {{tpl:lang page}} {{tpl:PaginationCurrent}} {{tpl:lang of}} {{tpl:PaginationCounter}}
+        <tpl:PaginationIf start="0"> - <a href="{{tpl:PaginationURL offset="-1"}}" class="next">{{tpl:lang next entries}}
+        &#187;</a></tpl:PaginationIf></p>
+      </tpl:Pagination>
+    </tpl:EntriesFooter>
+  </tpl:Entries>
+  </div>
+</div> <!-- End #main -->
+
+<div id="sidebar">
+  <div id="blognav">
+    {{tpl:Widgets type="nav"}}
+  </div> <!-- End #blognav -->
+  
+  <div id="blogextra">
+    {{tpl:Widgets type="extra"}}
+  </div> <!-- End #blogextra -->
+</div>
+
+</div> <!-- End #wrapper -->
+
+{{tpl:include src="_footer.html"}}
+</div> <!-- End #page -->
+</body>
+</html>
Index: inc/public/default-templates/tags.html
===================================================================
--- inc/public/default-templates/tags.html	(revision 199)
+++ inc/public/default-templates/tags.html	(revision 199)
@@ -0,0 +1,69 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="{{tpl:BlogLanguage}}" lang="{{tpl:BlogLanguage}}">
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+  <meta name="ROBOTS" content="{{tpl:BlogMetaRobots robots="NOINDEX"}}" />
+  
+  <title>{{tpl:lang Tags}} - {{tpl:BlogName encode_html="1"}}</title>
+  <meta name="copyright" content="{{tpl:BlogCopyrightNotice encode_html="1"}}" />
+  <meta name="author" content="{{tpl:BlogEditor encode_html="1"}}" />
+  <meta name="date" scheme="W3CDTF" content="{{tpl:BlogUpdateDate iso8601="1"}}" />
+  
+  <link rel="schema.dc" href="http://purl.org/dc/elements/1.1/" />
+  <meta name="dc.title" lang="{{tpl:BlogLanguage}}" content="{{tpl:lang Tags}} - {{tpl:BlogName encode_html="1"}}" />
+  <meta name="dc.language" content="{{tpl:BlogLanguage}}" />
+  <meta name="dc.publisher" content="{{tpl:BlogEditor encode_html="1"}}" />
+  <meta name="dc.rights" content="{{tpl:BlogCopyrightNotice encode_html="1"}}" />
+  <meta name="dc.date" scheme="W3CDTF" content="{{tpl:BlogUpdateDate iso8601="1"}}" />
+  <meta name="dc.type" content="text" />
+  <meta name="dc.format" content="text/html" />
+  
+  <link rel="top" href="{{tpl:BlogURL}}" title="{{tpl:lang Home}}" />
+  <link rel="contents" href="{{tpl:BlogArchiveURL}}" title="{{tpl:lang Archives}}" />
+  
+  <link rel="meta" type="application/xbel+xml" title="Blogroll" href="{{tpl:BlogrollXbelLink}}" />
+  
+  {{tpl:include src="_head.html"}}
+</head>
+
+<body class="dc-tags">
+<div id="page">
+{{tpl:include src="_top.html"}}
+
+<div id="wrapper">
+
+<div id="main">
+  <div id="content">
+  
+  <div id="content-info">
+    <h2>{{tpl:lang Tags}}</h2>
+  </div>
+  
+  <div class="content-inner">  
+  <ul class="tags">
+    <tpl:Tags>
+      <li><a href="{{tpl:TagURL}}" class="tag{{tpl:TagRoundPercent}}">{{tpl:TagID}}</a></li>
+    </tpl:Tags>
+    </ul>
+  </div>
+  
+  </div>
+</div> <!-- End #main -->
+
+<div id="sidebar">
+  <div id="blognav">
+    {{tpl:Widgets type="nav"}}
+  </div> <!-- End #blognav -->
+  
+  <div id="blogextra">
+    {{tpl:Widgets type="extra"}}
+  </div> <!-- End #blogextra -->
+</div>
+
+</div> <!-- End #wrapper -->
+
+{{tpl:include src="_footer.html"}}
+</div> <!-- End #page -->
+</body>
+</html>
Index: inc/public/lib.urlhandlers.php
===================================================================
--- inc/public/lib.urlhandlers.php	(revision 306)
+++ inc/public/lib.urlhandlers.php	(revision 270)
@@ -204,9 +204,6 @@
 		
 		$n = self::getPageNumber($args);
-		$params = new ArrayObject(array(
-			'lang' => $args));
-		
-		$core->callBehavior('publicLangBeforeGetLangs',$params,$args);
-		
+		
+		$params['lang'] = $args;
 		$_ctx->langs = $core->blog->getLangs($params);
 		
@@ -238,9 +235,6 @@
 		else
 		{
-			$params = new ArrayObject(array(
-				'cat_url' => $args,
-				'post_type' => 'post'));
-			
-			$core->callBehavior('publicCategoryBeforeGetCategories',$params,$args);
+			$params['cat_url'] = $args;
+			$params['post_type'] = 'post';
 			
 			$_ctx->categories = $core->blog->getCategories($params);
@@ -273,11 +267,7 @@
 		elseif (preg_match('|^/([0-9]{4})/([0-9]{2})$|',$args,$m))
 		{
-			$params = new ArrayObject(array(
-				'year' => $m[1],
-				'month' => $m[2],
-				'type' => 'month'));
-			
-			$core->callBehavior('publicArchiveBeforeGetDates',$params,$args);
-			
+			$params['year'] = $m[1];
+			$params['month'] = $m[2];
+			$params['type'] = 'month';
 			$_ctx->archives = $core->blog->getDates($params);
 			
@@ -310,9 +300,7 @@
 			$core->blog->withoutPassword(false);
 			
-			$params = new ArrayObject(array(
-				'post_url' => $args));
-			
-			$core->callBehavior('publicPostBeforeGetPosts',$params,$args);
-
+			$params = new ArrayObject();
+			$params['post_url'] = $args;
+			
 			$_ctx->posts = $core->blog->getPosts($params);
 			
@@ -422,5 +410,5 @@
 						
 						$redir = $_ctx->posts->getURL();
-						$redir .= $core->blog->settings->system->url_scan == 'query_string' ? '&' : '?';
+						$redir .= strpos($redir,'?') !== false ? '&' : '?';
 						
 						try
@@ -493,4 +481,5 @@
 		$cat_url = false;
 		$post_id = null;
+		$params = array();
 		$subtitle = '';
 		
@@ -501,9 +490,6 @@
 		
 		if (preg_match('!^([a-z]{2}(-[a-z]{2})?)/(.*)$!',$args,$m)) {
-			$params = new ArrayObject(array('lang' => $m[1]));
-			
+			$params['lang'] = $m[1];
 			$args = $m[3];
-			
-			$core->callBehavior('publicFeedBeforeGetLangs',$params,$args);
 			
 			$_ctx->langs = $core->blog->getLangs($params);
@@ -549,10 +535,6 @@
 		if ($cat_url)
 		{
-			$params = new ArrayObject(array(
-				'cat_url' => $cat_url,
-				'post_type' => 'post'));
-			
-			$core->callBehavior('publicFeedBeforeGetCategories',$params,$args);
-			
+			$params['cat_url'] = $cat_url;
+			$params['post_type'] = 'post';
 			$_ctx->categories = $core->blog->getCategories($params);
 			
@@ -567,10 +549,6 @@
 		elseif ($post_id)
 		{
-			$params = new ArrayObject(array(
-				'post_id' => $post_id,
-				'post_type' => ''));
-				
-			$core->callBehavior('publicFeedBeforeGetPosts',$params,$args);
-			
+			$params['post_id'] = $post_id;
+			$params['post_type'] = '';
 			$_ctx->posts = $core->blog->getPosts($params);
 			
Index: inc/public/prepend.php
===================================================================
--- inc/public/prepend.php	(revision 270)
+++ inc/public/prepend.php	(revision 420)
@@ -113,4 +113,10 @@
 $core->themes->loadNsFile($__theme,'public');
 
+# Loading translations for selected theme
+if ($__parent_theme) {
+	$core->themes->loadModuleL10N($__parent_theme,$_lang,'main');
+}
+$core->themes->loadModuleL10N($__theme,$_lang,'main');
+
 # --BEHAVIOR-- publicPrepend
 $core->callBehavior('publicPrepend',$core);
