Explorar el Código

refactoring away RainTPL and templating, resolves #36

El RIDO hace 10 años
padre
commit
c5606a47fe

+ 0 - 1164
lib/RainTPL.php

@@ -1,1164 +0,0 @@
-<?php
-/**
- * RainTPL
- *
- * Realized by Federico Ulfo & maintained by the Rain Team
- * Distributed under GNU/LGPL 3 License
- *
- * @version 2.7.2
- */
-
-
-/**
- * RainTPL
- */
-class RainTPL{
-
-	// -------------------------
-	// 	CONFIGURATION
-	// -------------------------
-
-		/**
-		 * Template directory
-		 *
-		 * @var string
-		 */
-		static $tpl_dir = 'tpl/';
-
-
-		/**
-		 * Cache directory
-		 *
-		 * Is the directory where RainTPL will compile the template and save the cache
-		 *
-		 * @var string
-		 */
-		static $cache_dir = 'tmp/';
-
-
-		/**
-		 * Template base URL
-		 *
-		 * RainTPL will add this URL to the relative paths of element selected in $path_replace_list.
-		 *
-		 * @var string
-		 */
-		static $base_url = null;
-
-
-		/**
-		 * Template extension
-		 *
-		 * @var string
-		 */
-		static $tpl_ext = "html";
-
-
-		/**
-		 * Should the path be replaced
-		 *
-		 * Path replace is a cool features that replace all relative paths of images (&lt;img src="..."&gt;), stylesheet (&lt;link href="..."&gt;), script (&lt;script src="..."&gt;) and link (&lt;a href="..."&gt;)
-		 * Set true to enable the path replace.
-		 *
-		 * @var boolean
-		 */
-		static $path_replace = true;
-
-
-		/**
-		 * You can set what the path_replace method will replace.
-		 * Avaible options: a, img, link, script, input
-		 *
-		 * @var array
-		 */
-		static $path_replace_list = array( 'a', 'img', 'link', 'script', 'input' );
-
-
-		/**
-		 * You can define in the black list what string are disabled into the template tags
-		 *
-		 * @var array
-		 */
-		static $black_list = array( '\$this', 'raintpl::', 'self::', '_SESSION', '_SERVER', '_ENV',  'eval', 'exec', 'unlink', 'rmdir' );
-
-
-		/**
-		 * Check template
-		 *
-		 * true: checks template update time, if changed it compile them
-		 * false: loads the compiled template. Set false if server doesn't have write permission for cache_directory.
-		 *
-		 * @var bool
-		 */
-		static $check_template_update = true;
-
-
-		/**
-		 * PHP tags <? ?>
-		 *
-		 * True: php tags are enabled into the template
-		 * False: php tags are disabled into the template and rendered as html
-		 *
-		 * @var bool
-		 */
-		static $php_enabled = false;
-
-
-		/**
-		 * Debug mode flag
-		 *
-		 * True: debug mode is used, syntax errors are displayed directly in template. Execution of script is not terminated.
-		 * False: exception is thrown on found error.
-		 *
-		 * @var bool
-		 */
-		static $debug = false;
-
-	// -------------------------
-
-
-	// -------------------------
-	// 	RAINTPL VARIABLES
-	// -------------------------
-
-		/**
-		 * Is the array where RainTPL keep the variables assigned
-		 *
-		 * @var array
-		 */
-		public $var = array();
-
-		/**
-		 * variables to keep the template directories and info
-		 *
-		 * @var array
-		 */
-		protected $tpl = array();		//
-
-		/**
-		 * static cache enabled / disabled
-		 *
-		 * @var bool
-		 */
-		protected $cache = false;
-
-		/**
-		 * identify only one cache
-		 *
-		 * @var string
-		 */
-		protected $cache_id = '';
-
-		/**
-		 * takes all the config to create the md5 of the file
-		 *
-		 * @var array the file
-		 */
-		protected static $config_name_sum = array();
-
-	// -------------------------
-
-
-
-	/**
-	 * default cache expire time = hour
-	 *
-	 * @const int
-	 */
-	const CACHE_EXPIRE_TIME = 3600;
-
-
-
-	/**
-	 * Assign variable
-	 * eg. 	$t->assign('name','mickey');
-	 *
-	 * @access public
-	 * @param  mixed $variable_name Name of template variable or associative array name/value
-	 * @param  mixed $value value assigned to this variable. Not set if variable_name is an associative array
-	 */
-	public function assign( $variable, $value = null ){
-		if( is_array( $variable ) )
-			$this->var += $variable;
-		else
-			$this->var[ $variable ] = $value;
-	}
-
-
-
-	/**
-	 * Draw the template
-	 * eg. 	$html = $tpl->draw( 'demo', TRUE ); // return template in string
-	 * or 	$tpl->draw( $tpl_name ); // echo the template
-	 *
-	 * @access public
-	 * @param  string $tpl_name  template to load
-	 * @param  boolean $return_string  true=return a string, false=echo the template
-	 * @return string
-	 */
-	public function draw( $tpl_name, $return_string = false ){
-
-		try {
-			// compile the template if necessary and set the template filepath
-			$this->check_template( $tpl_name );
-		} catch (RainTpl_Exception $e) {
-			$output = $this->printDebug($e);
-			die($output);
-		}
-
-		// Cache is off and, return_string is false
-		// Rain just echo the template
-
-		if( !$this->cache && !$return_string ){
-			extract( $this->var );
-			include $this->tpl['compiled_filename'];
-			unset( $this->tpl );
-		}
-
-
-		// cache or return_string are enabled
-		// rain get the output buffer to save the output in the cache or to return it as string
-
-		else{
-
-			//----------------------
-			// get the output buffer
-			//----------------------
-				ob_start();
-				extract( $this->var );
-				include $this->tpl['compiled_filename'];
-				$raintpl_contents = ob_get_clean();
-			//----------------------
-
-
-			// save the output in the cache
-			if( $this->cache )
-				file_put_contents( $this->tpl['cache_filename'], "<?php if(!class_exists('raintpl')){exit;}?>" . $raintpl_contents );
-
-			// free memory
-			unset( $this->tpl );
-
-			// return or print the template
-			if( $return_string ) return $raintpl_contents; else echo $raintpl_contents;
-
-		}
-
-	}
-
-
-
-	/**
-	 * If exists a valid cache for this template it returns the cache
-	 *
-	 * @access public
-	 * @param  string $tpl_name Name of template (set the same of draw)
-	 * @param  int $expiration_time Set after how many seconds the cache expire and must be regenerated
-	 * @param  string $cache_id Suffix to be used when writing file to cache (optional)
-	 * @return string it return the HTML or null if the cache must be recreated
-	 */
-	public function cache( $tpl_name, $expire_time = self::CACHE_EXPIRE_TIME, $cache_id = '' ){
-
-		// set the cache_id
-		$this->cache_id = $cache_id;
-
-		if( !$this->check_template( $tpl_name ) && file_exists( $this->tpl['cache_filename'] ) && ( time() - filemtime( $this->tpl['cache_filename'] ) < $expire_time ) )
-			return substr( file_get_contents( $this->tpl['cache_filename'] ), 43 );
-		else{
-			//delete the cache of the selected template
-			if (file_exists($this->tpl['cache_filename']))
-			unlink($this->tpl['cache_filename'] );
-			$this->cache = true;
-		}
-	}
-
-
-
-	/**
-	 * Configure the settings of RainTPL
-	 *
-	 * @access public
-	 * @static
-	 * @param  array|string $setting array of settings or setting name
-	 * @param  mixed $value content to set in the setting (optional)
-	 */
-	public static function configure( $setting, $value = null ){
-		if( is_array( $setting ) )
-			foreach( $setting as $key => $value )
-				self::configure( $key, $value );
-		else if( property_exists( __CLASS__, $setting ) ){
-			self::$$setting = $value;
-			self::$config_name_sum[ $setting ] = $value; // take trace of all config
-		}
-	}
-
-
-
-	/**
-	 * Check if has to compile the template
-	 *
-	 * @access protected
-	 * @param  string $tpl_name template name to check
-	 * @throws RainTpl_NotFoundException
-	 * @return bool return true if the template has changed
-	 */
-	protected function check_template( $tpl_name ){
-
-		if( !isset($this->tpl['checked']) ){
-
-			$tpl_basename					   = basename( $tpl_name );														// template basename
-			$tpl_basedir						= strpos($tpl_name,"/") ? dirname($tpl_name) . '/' : null;						// template basedirectory
-			$tpl_dir							= PATH . self::$tpl_dir . $tpl_basedir;								// template directory
-			$this->tpl['tpl_filename']		  = $tpl_dir . $tpl_basename . '.' . self::$tpl_ext;	// template filename
-			$temp_compiled_filename			 = PATH . self::$cache_dir . $tpl_basename . "." . md5( $tpl_dir . serialize(self::$config_name_sum));
-			$this->tpl['compiled_filename']	 = $temp_compiled_filename . '.rtpl.php';	// cache filename
-			$this->tpl['cache_filename']		= $temp_compiled_filename . '.s_' . $this->cache_id . '.rtpl.php';	// static cache filename
-
-			// if the template doesn't exsist throw an error
-			if( self::$check_template_update && !file_exists( $this->tpl['tpl_filename'] ) ){
-				$e = new RainTpl_NotFoundException( 'Template '. $tpl_basename .' not found!' );
-				throw $e->setTemplateFile($this->tpl['tpl_filename']);
-			}
-
-			// file doesn't exsist, or the template was updated, Rain will compile the template
-			if( !file_exists( $this->tpl['compiled_filename'] ) || ( self::$check_template_update && filemtime($this->tpl['compiled_filename']) < filemtime( $this->tpl['tpl_filename'] ) ) ){
-				$this->compileFile( $tpl_basedir, $this->tpl['tpl_filename'], PATH . self::$cache_dir, $this->tpl['compiled_filename'] );
-				return true;
-			}
-			$this->tpl['checked'] = true;
-		}
-	}
-
-
-
-	/**
-	 * execute stripslaches() on the xml block. Invoqued by preg_replace_callback function below
-	 *
-	 * @access protected
-	 * @param string $capture
-	 * @return string
-	 */
-	protected function xml_reSubstitution($capture) {
-			return "<?php echo '<?xml ".stripslashes($capture[1])." ?>'; ?>";
-	}
-
-
-
-	/**
-	 * Compile and write the compiled template file
-	 *
-	 * @access protected
-	 * @param  string $tpl_basedir
-	 * @param  string $tpl_filename
-	 * @param  string $cache_dir
-	 * @param  string $compiled_filename
-	 * @throws RainTpl_Exception
-	 * @return void
-	 */
-	protected function compileFile( $tpl_basedir, $tpl_filename, $cache_dir, $compiled_filename ){
-
-		//read template file
-		$this->tpl['source'] = $template_code = file_get_contents( $tpl_filename );
-
-		//xml substitution
-		$template_code = preg_replace( "/<\?xml(.*?)\?>/s", "##XML\\1XML##", $template_code );
-
-		//disable php tag
-		if( !self::$php_enabled )
-			$template_code = str_replace( array("<?","?>"), array("&lt;?","?&gt;"), $template_code );
-
-		//xml re-substitution
-		$template_code = preg_replace_callback ( "/##XML(.*?)XML##/s", array($this, 'xml_reSubstitution'), $template_code );
-
-		//compile template
-		$template_compiled = "<?php if(!class_exists('raintpl')){exit;}?>" . $this->compileTemplate( $template_code, $tpl_basedir );
-
-
-		// fix the php-eating-newline-after-closing-tag-problem
-		$template_compiled = str_replace( "?>\n", "?>\n\n", $template_compiled );
-
-		// create directories
-		if( !is_dir( $cache_dir ) )
-			mkdir( $cache_dir, 0755, true );
-
-		if( !is_writable( $cache_dir ) )
-			throw new RainTpl_Exception ('Cache directory ' . $cache_dir . ' doesn\'t have write permission. Set write permission or set RAINTPL_CHECK_TEMPLATE_UPDATE to false. More details on http://www.raintpl.com/Documentation/Documentation-for-PHP-developers/Configuration/');
-
-		//write compiled file
-		file_put_contents( $compiled_filename, $template_compiled );
-	}
-
-
-
-	/**
-	 * Compile template
-	 *
-	 * @access protected
-	 * @param  string $template_code
-	 * @param  string $tpl_basedir
-	 * @return string
-	 */
-	protected function compileTemplate( $template_code, $tpl_basedir ){
-
-		//tag list
-		$tag_regexp = array( 'loop'		 => '(\{loop(?: name){0,1}="\${0,1}[^"]*"\})',
-							 'loop_close'   => '(\{\/loop\})',
-							 'if'		   => '(\{if(?: condition){0,1}="[^"]*"\})',
-							 'elseif'	   => '(\{elseif(?: condition){0,1}="[^"]*"\})',
-							 'else'		 => '(\{else\})',
-							 'if_close'	 => '(\{\/if\})',
-							 'function'	 => '(\{function="[^"]*"\})',
-							 'noparse'	  => '(\{noparse\})',
-							 'noparse_close'=> '(\{\/noparse\})',
-							 'ignore'	   => '(\{ignore\}|\{\*)',
-							 'ignore_close'	=> '(\{\/ignore\}|\*\})',
-							 'include'	  => '(\{include="[^"]*"(?: cache="[^"]*")?\})',
-							 'template_info'=> '(\{\$template_info\})',
-							 'function'		=> '(\{function="(\w*?)(?:.*?)"\})'
-							);
-
-		$tag_regexp = "/" . join( "|", $tag_regexp ) . "/";
-
-		//split the code with the tags regexp
-		$template_code = preg_split ( $tag_regexp, $template_code, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY );
-
-		//path replace (src of img, background and href of link)
-		$template_code = $this->path_replace( $template_code, $tpl_basedir );
-
-		//compile the code
-		$compiled_code = $this->compileCode( $template_code );
-
-		//return the compiled code
-		return $compiled_code;
-
-	}
-
-
-
-	/**
-	 * Compile the code
-	 *
-	 * @access protected
-	 * @param  string $parsed_code
-	 * @throws RainTpl_SyntaxException
-	 * @return string
-	 */
-	protected function compileCode( $parsed_code ){
-
-		//variables initialization
-		$compiled_code = $open_if = $comment_is_open = $ignore_is_open = null;
-		$loop_level = 0;
-
-		//read all parsed code
-		while( $html = array_shift( $parsed_code ) ){
-
-			//close ignore tag
-			if( !$comment_is_open && ( strpos( $html, '{/ignore}' ) !== FALSE || strpos( $html, '*}' ) !== FALSE ) )
-				$ignore_is_open = false;
-
-			//code between tag ignore id deleted
-			elseif( $ignore_is_open ){
-				//ignore the code
-			}
-
-			//close no parse tag
-			elseif( strpos( $html, '{/noparse}' ) !== FALSE )
-				$comment_is_open = false;
-
-			//code between tag noparse is not compiled
-			elseif( $comment_is_open )
-				$compiled_code .= $html;
-
-			//ignore
-			elseif( strpos( $html, '{ignore}' ) !== FALSE || strpos( $html, '{*' ) !== FALSE )
-				$ignore_is_open = true;
-
-			//noparse
-			elseif( strpos( $html, '{noparse}' ) !== FALSE )
-				$comment_is_open = true;
-
-			//include tag
-			elseif( preg_match( '/\{include="([^"]*)"(?: cache="([^"]*)"){0,1}\}/', $html, $code ) ){
-
-				//variables substitution
-				$include_var = $this->var_replace( $code[ 1 ], $left_delimiter = null, $right_delimiter = null, $php_left_delimiter = '".' , $php_right_delimiter = '."', $loop_level );
-
-				// if the cache is active
-				if( isset($code[ 2 ]) ){
-
-					//dynamic include
-					$compiled_code .= '<?php $tpl = new '.get_class($this).';' .
-								 'if( $cache = $tpl->cache( $template = basename("'.$include_var.'") ) )' .
-								 '	echo $cache;' .
-								 'else{' .
-								 '	$tpl_dir_temp = self::$tpl_dir;' .
-								 '	$tpl->assign( $this->var );' .
-									( !$loop_level ? null : '$tpl->assign( "key", $key'.$loop_level.' ); $tpl->assign( "value", $value'.$loop_level.' );' ).
-								 '	$tpl->draw( dirname("'.$include_var.'") . ( substr("'.$include_var.'",-1,1) != "/" ? "/" : "" ) . basename("'.$include_var.'") );'.
-								 '} ?>';
-				}
-				else{
-
-					//dynamic include
-					$compiled_code .= '<?php $tpl = new '.get_class($this).';' .
-									  '$tpl_dir_temp = self::$tpl_dir;' .
-									  '$tpl->assign( $this->var );' .
-									  ( !$loop_level ? null : '$tpl->assign( "key", $key'.$loop_level.' ); $tpl->assign( "value", $value'.$loop_level.' );' ).
-									  '$tpl->draw( dirname("'.$include_var.'") . ( substr("'.$include_var.'",-1,1) != "/" ? "/" : "" ) . basename("'.$include_var.'") );'.
-									  '?>';
-
-
-				}
-
-			}
-
-			//loop
-			elseif( preg_match( '/\{loop(?: name){0,1}="\${0,1}([^"]*)"\}/', $html, $code ) ){
-
-				//increase the loop counter
-				$loop_level++;
-
-				//replace the variable in the loop
-				$var = $this->var_replace( '$' . $code[ 1 ], $tag_left_delimiter=null, $tag_right_delimiter=null, $php_left_delimiter=null, $php_right_delimiter=null, $loop_level-1 );
-
-				//loop variables
-				$counter = "\$counter$loop_level";	   // count iteration
-				$key = "\$key$loop_level";			   // key
-				$value = "\$value$loop_level";		   // value
-
-				//loop code
-				$compiled_code .=  "<?php $counter=-1; if( isset($var) && is_array($var) && sizeof($var) ) foreach( $var as $key => $value ){ $counter++; ?>";
-
-			}
-
-			//close loop tag
-			elseif( strpos( $html, '{/loop}' ) !== FALSE ) {
-
-				//iterator
-				$counter = "\$counter$loop_level";
-
-				//decrease the loop counter
-				$loop_level--;
-
-				//close loop code
-				$compiled_code .=  "<?php } ?>";
-
-			}
-
-			//if
-			elseif( preg_match( '/\{if(?: condition){0,1}="([^"]*)"\}/', $html, $code ) ){
-
-				//increase open if counter (for intendation)
-				$open_if++;
-
-				//tag
-				$tag = $code[ 0 ];
-
-				//condition attribute
-				$condition = $code[ 1 ];
-
-				// check if there's any function disabled by black_list
-				$this->function_check( $tag );
-
-				//variable substitution into condition (no delimiter into the condition)
-				$parsed_condition = $this->var_replace( $condition, $tag_left_delimiter = null, $tag_right_delimiter = null, $php_left_delimiter = null, $php_right_delimiter = null, $loop_level );
-
-				//if code
-				$compiled_code .=   "<?php if( $parsed_condition ){ ?>";
-
-			}
-
-			//elseif
-			elseif( preg_match( '/\{elseif(?: condition){0,1}="([^"]*)"\}/', $html, $code ) ){
-
-				//tag
-				$tag = $code[ 0 ];
-
-				//condition attribute
-				$condition = $code[ 1 ];
-
-				//variable substitution into condition (no delimiter into the condition)
-				$parsed_condition = $this->var_replace( $condition, $tag_left_delimiter = null, $tag_right_delimiter = null, $php_left_delimiter = null, $php_right_delimiter = null, $loop_level );
-
-				//elseif code
-				$compiled_code .=   "<?php }elseif( $parsed_condition ){ ?>";
-			}
-
-			//else
-			elseif( strpos( $html, '{else}' ) !== FALSE ) {
-
-				//else code
-				$compiled_code .=   '<?php }else{ ?>';
-
-			}
-
-			//close if tag
-			elseif( strpos( $html, '{/if}' ) !== FALSE ) {
-
-				//decrease if counter
-				$open_if--;
-
-				// close if code
-				$compiled_code .=   '<?php } ?>';
-
-			}
-
-			//function
-			elseif( preg_match( '/\{function="(\w*)(.*?)"\}/', $html, $code ) ){
-
-				//tag
-				$tag = $code[ 0 ];
-
-				//function
-				$function = $code[ 1 ];
-
-				// check if there's any function disabled by black_list
-				$this->function_check( $tag );
-
-				if( empty( $code[ 2 ] ) )
-					$parsed_function = $function . "()";
-				else
-					// parse the function
-					$parsed_function = $function . $this->var_replace( $code[ 2 ], $tag_left_delimiter = null, $tag_right_delimiter = null, $php_left_delimiter = null, $php_right_delimiter = null, $loop_level );
-
-				//if code
-				$compiled_code .=   "<?php echo $parsed_function; ?>";
-			}
-
-			// show all vars
-			elseif ( strpos( $html, '{$template_info}' ) !== FALSE ) {
-
-				//tag
-				$tag  = '{$template_info}';
-
-				//if code
-				$compiled_code .=   '<?php echo "<pre>"; print_r( $this->var ); echo "</pre>"; ?>';
-			}
-
-
-			//all html code
-			else{
-
-				//variables substitution (es. {$title})
-				$html = $this->var_replace( $html, $left_delimiter = '\{', $right_delimiter = '\}', $php_left_delimiter = '<?php ', $php_right_delimiter = ';?>', $loop_level, $echo = true );
-				//const substitution (es. {#CONST#})
-				$html = $this->const_replace( $html, $left_delimiter = '\{', $right_delimiter = '\}', $php_left_delimiter = '<?php ', $php_right_delimiter = ';?>', $loop_level, $echo = true );
-				//functions substitution (es. {"string"|functions})
-				$compiled_code .= $this->func_replace( $html, $left_delimiter = '\{', $right_delimiter = '\}', $php_left_delimiter = '<?php ', $php_right_delimiter = ';?>', $loop_level, $echo = true );
-			}
-		}
-
-		if( $open_if > 0 ) {
-			$e = new RainTpl_SyntaxException('Error! You need to close an {if} tag in ' . $this->tpl['tpl_filename'] . ' template');
-			throw $e->setTemplateFile($this->tpl['tpl_filename']);
-		}
-		return $compiled_code;
-	}
-
-
-
-	/**
-	 * Reduce a path
-	 *
-	 * eg. www/library/../filepath//file => www/filepath/file
-	 *
-	 * @param string $path
-	 * @return string
-	 */
-	protected function reduce_path( $path ){
-		$path = str_replace( "://", "@not_replace@", $path );
-		$path = str_replace( "//", "/", $path );
-		$path = str_replace( "@not_replace@", "://", $path );
-		return preg_replace('/\w+\/\.\.\//', '', $path );
-	}
-
-
-
-	/**
-	 * replace the path of image src, link href and a href
-	 *
-	 * url => template_dir/url
-	 * url# => url
-	 * http://url => http://url
-	 *
-	 * @access protected
-	 * @param  string $html
-	 * @param  string $tpl_basedir
-	 * @return string html substitution
-	 */
-	protected function path_replace( $html, $tpl_basedir ){
-
-		if( self::$path_replace ){
-
-			$tpl_dir = self::$base_url . PATH . self::$tpl_dir . $tpl_basedir;
-
-			// reduce the path
-			$path = $this->reduce_path($tpl_dir);
-
-			$exp = $sub = array();
-
-			if( in_array( "img", self::$path_replace_list ) ){
-				$exp = array( '/<img(.*?)src=(?:")(http|https)\:\/\/([^"]+?)(?:")/i', '/<img(.*?)src=(?:")([^"]+?)#(?:")/i', '/<img(.*?)src="(.*?)"/', '/<img(.*?)src=(?:\@)([^"]+?)(?:\@)/i' );
-				$sub = array( '<img$1src=@$2://$3@', '<img$1src=@$2@', '<img$1src="' . $path . '$2"', '<img$1src="$2"' );
-			}
-
-			if( in_array( "script", self::$path_replace_list ) ){
-				$exp = array_merge( $exp , array( '/<script(.*?)src=(?:")(http|https)\:\/\/([^"]+?)(?:")/i', '/<script(.*?)src=(?:")([^"]+?)#(?:")/i', '/<script(.*?)src="(.*?)"/', '/<script(.*?)src=(?:\@)([^"]+?)(?:\@)/i' ) );
-				$sub = array_merge( $sub , array( '<script$1src=@$2://$3@', '<script$1src=@$2@', '<script$1src="' . $path . '$2"', '<script$1src="$2"' ) );
-			}
-
-			if( in_array( "link", self::$path_replace_list ) ){
-				$exp = array_merge( $exp , array( '/<link(.*?)href=(?:")(http|https)\:\/\/([^"]+?)(?:")/i', '/<link(.*?)href=(?:")([^"]+?)#(?:")/i', '/<link(.*?)href="(.*?)"/', '/<link(.*?)href=(?:\@)([^"]+?)(?:\@)/i' ) );
-				$sub = array_merge( $sub , array( '<link$1href=@$2://$3@', '<link$1href=@$2@' , '<link$1href="' . $path . '$2"', '<link$1href="$2"' ) );
-			}
-
-			if( in_array( "a", self::$path_replace_list ) ){
-				$exp = array_merge( $exp , array( '/<a(.*?)href=(?:")(http\:\/\/|https\:\/\/|javascript:)([^"]+?)(?:")/i', '/<a(.*?)href="(.*?)"/', '/<a(.*?)href=(?:\@)([^"]+?)(?:\@)/i'  ) );
-				$sub = array_merge( $sub , array( '<a$1href=@$2$3@', '<a$1href="' . self::$base_url . '$2"', '<a$1href="$2"' ) );
-			}
-
-			if( in_array( "input", self::$path_replace_list ) ){
-				$exp = array_merge( $exp , array( '/<input(.*?)src=(?:")(http|https)\:\/\/([^"]+?)(?:")/i', '/<input(.*?)src=(?:")([^"]+?)#(?:")/i', '/<input(.*?)src="(.*?)"/', '/<input(.*?)src=(?:\@)([^"]+?)(?:\@)/i' ) );
-				$sub = array_merge( $sub , array( '<input$1src=@$2://$3@', '<input$1src=@$2@', '<input$1src="' . $path . '$2"', '<input$1src="$2"' ) );
-			}
-
-			return preg_replace( $exp, $sub, $html );
-
-		}
-		else
-			return $html;
-
-	}
-
-
-
-	/**
-	 * replace constants
-	 *
-	 * @access public
-	 * @param  string $html
-	 * @param  string $tag_left_delimiter
-	 * @param  string $tag_right_delimiter
-	 * @param  string $php_left_delimiter (optional)
-	 * @param  string $php_right_delimiter (optional)
-	 * @param  string $loop_level (optional)
-	 * @param  string $echo (optional)
-	 * @return string
-	 */
-	public function const_replace( $html, $tag_left_delimiter, $tag_right_delimiter, $php_left_delimiter = null, $php_right_delimiter = null, $loop_level = null, $echo = null ){
-		// const
-		return preg_replace( '/\{\#(\w+)\#{0,1}\}/', $php_left_delimiter . ( $echo ? " echo " : null ) . '\\1' . $php_right_delimiter, $html );
-	}
-
-
-
-	/**
-	 * replace functions/modifiers on constants and strings
-	 *
-	 * @access public
-	 * @param  string $html
-	 * @param  string $tag_left_delimiter
-	 * @param  string $tag_right_delimiter
-	 * @param  string $php_left_delimiter (optional)
-	 * @param  string $php_right_delimiter (optional)
-	 * @param  string $loop_level (optional)
-	 * @param  string $echo (optional)
-	 * @return string
-	 */
-	public function func_replace( $html, $tag_left_delimiter, $tag_right_delimiter, $php_left_delimiter = null, $php_right_delimiter = null, $loop_level = null, $echo = null ){
-
-		preg_match_all( '/' . '\{\#{0,1}(\"{0,1}.*?\"{0,1})(\|\w.*?)\#{0,1}\}' . '/', $html, $matches );
-
-		for( $i=0, $n=count($matches[0]); $i<$n; $i++ ){
-
-			//complete tag ex: {$news.title|substr:0,100}
-			$tag = $matches[ 0 ][ $i ];
-
-			//variable name ex: news.title
-			$var = $matches[ 1 ][ $i ];
-
-			//function and parameters associate to the variable ex: substr:0,100
-			$extra_var = $matches[ 2 ][ $i ];
-
-			// check if there's any function disabled by black_list
-			$this->function_check( $tag );
-
-			$extra_var = $this->var_replace( $extra_var, null, null, null, null, $loop_level );
-
-
-			// check if there's an operator = in the variable tags, if there's this is an initialization so it will not output any value
-			$is_init_variable = preg_match( "/^(\s*?)\=[^=](.*?)$/", $extra_var );
-
-			//function associate to variable
-			$function_var = ( $extra_var and $extra_var[0] == '|') ? substr( $extra_var, 1 ) : null;
-
-			//variable path split array (ex. $news.title o $news[title]) or object (ex. $news->title)
-			$temp = preg_split( "/\.|\[|\-\>/", $var );
-
-			//variable name
-			$var_name = $temp[ 0 ];
-
-			//variable path
-			$variable_path = substr( $var, strlen( $var_name ) );
-
-			//parentesis transform [ e ] in [" e in "]
-			$variable_path = str_replace( '[', '["', $variable_path );
-			$variable_path = str_replace( ']', '"]', $variable_path );
-
-			//transform .$variable in ["$variable"]
-			$variable_path = preg_replace('/\.\$(\w+)/', '["$\\1"]', $variable_path );
-
-			//transform [variable] in ["variable"]
-			$variable_path = preg_replace('/\.(\w+)/', '["\\1"]', $variable_path );
-
-			//if there's a function
-			if( $function_var ){
-
-				// check if there's a function or a static method and separate, function by parameters
-				$function_var = str_replace("::", "@double_dot@", $function_var );
-
-				// get the position of the first :
-				if( $dot_position = strpos( $function_var, ":" ) ){
-
-					// get the function and the parameters
-					$function = substr( $function_var, 0, $dot_position );
-					$params = substr( $function_var, $dot_position+1 );
-
-				}
-				else{
-
-					//get the function
-					$function = str_replace( "@double_dot@", "::", $function_var );
-					$params = null;
-
-				}
-
-				// replace back the @double_dot@ with ::
-				$function = str_replace( "@double_dot@", "::", $function );
-				$params = str_replace( "@double_dot@", "::", $params );
-
-
-			}
-			else
-				$function = $params = null;
-
-			$php_var = $var_name . $variable_path;
-
-			// compile the variable for php
-			if( isset( $function ) ){
-				if( $php_var )
-					$php_var = $php_left_delimiter . ( !$is_init_variable && $echo ? 'echo ' : null ) . ( $params ? "( $function( $php_var, $params ) )" : "$function( $php_var )" ) . $php_right_delimiter;
-				else
-					$php_var = $php_left_delimiter . ( !$is_init_variable && $echo ? 'echo ' : null ) . ( $params ? "( $function( $params ) )" : "$function()" ) . $php_right_delimiter;
-			}
-			else
-				$php_var = $php_left_delimiter . ( !$is_init_variable && $echo ? 'echo ' : null ) . $php_var . $extra_var . $php_right_delimiter;
-
-			$html = str_replace( $tag, $php_var, $html );
-
-		}
-
-		return $html;
-
-	}
-
-
-
-	/**
-	 * replace variables
-	 *
-	 * @access public
-	 * @param  string $html
-	 * @param  string $tag_left_delimiter
-	 * @param  string $tag_right_delimiter
-	 * @param  string $php_left_delimiter (optional)
-	 * @param  string $php_right_delimiter (optional)
-	 * @param  string $loop_level (optional)
-	 * @param  string $echo (optional)
-	 * @return string
-	 */
-	public function var_replace( $html, $tag_left_delimiter, $tag_right_delimiter, $php_left_delimiter = null, $php_right_delimiter = null, $loop_level = null, $echo = null ){
-
-		//all variables
-		if( preg_match_all( '/' . $tag_left_delimiter . '\$(\w+(?:\.\${0,1}[A-Za-z0-9_]+)*(?:(?:\[\${0,1}[A-Za-z0-9_]+\])|(?:\-\>\${0,1}[A-Za-z0-9_]+))*)(.*?)' . $tag_right_delimiter . '/', $html, $matches ) ){
-
-			for( $parsed=array(), $i=0, $n=count($matches[0]); $i<$n; $i++ )
-				$parsed[$matches[0][$i]] = array('var'=>$matches[1][$i],'extra_var'=>$matches[2][$i]);
-
-			foreach( $parsed as $tag => $array ){
-
-				//variable name ex: news.title
-				$var = $array['var'];
-
-				//function and parameters associate to the variable ex: substr:0,100
-				$extra_var = $array['extra_var'];
-
-				// check if there's any function disabled by black_list
-				$this->function_check( $tag );
-
-				$extra_var = $this->var_replace( $extra_var, null, null, null, null, $loop_level );
-
-				// check if there's an operator = in the variable tags, if there's this is an initialization so it will not output any value
-				$is_init_variable = preg_match( "/^[a-z_A-Z\.\[\](\-\>)]*=[^=]*$/", $extra_var );
-
-				//function associate to variable
-				$function_var = ( $extra_var and $extra_var[0] == '|') ? substr( $extra_var, 1 ) : null;
-
-				//variable path split array (ex. $news.title o $news[title]) or object (ex. $news->title)
-				$temp = preg_split( "/\.|\[|\-\>/", $var );
-
-				//variable name
-				$var_name = $temp[ 0 ];
-
-				//variable path
-				$variable_path = substr( $var, strlen( $var_name ) );
-
-				//parentesis transform [ e ] in [" e in "]
-				$variable_path = str_replace( '[', '["', $variable_path );
-				$variable_path = str_replace( ']', '"]', $variable_path );
-
-				//transform .$variable in ["$variable"] and .variable in ["variable"]
-				$variable_path = preg_replace('/\.(\${0,1}\w+)/', '["\\1"]', $variable_path );
-
-				// if is an assignment also assign the variable to $this->var['value']
-				if( $is_init_variable )
-					$extra_var = "=\$this->var['{$var_name}']{$variable_path}" . $extra_var;
-
-
-
-				//if there's a function
-				if( $function_var ){
-
-					// check if there's a function or a static method and separate, function by parameters
-					$function_var = str_replace("::", "@double_dot@", $function_var );
-
-
-					// get the position of the first :
-					if( $dot_position = strpos( $function_var, ":" ) ){
-
-						// get the function and the parameters
-						$function = substr( $function_var, 0, $dot_position );
-						$params = substr( $function_var, $dot_position+1 );
-
-					}
-					else{
-
-						//get the function
-						$function = str_replace( "@double_dot@", "::", $function_var );
-						$params = null;
-
-					}
-
-					// replace back the @double_dot@ with ::
-					$function = str_replace( "@double_dot@", "::", $function );
-					$params = str_replace( "@double_dot@", "::", $params );
-				}
-				else
-					$function = $params = null;
-
-				//if it is inside a loop
-				if( $loop_level ){
-					//verify the variable name
-					if( $var_name == 'key' )
-							$php_var = '$key' . $loop_level;
-					elseif( $var_name == 'value' )
-							$php_var = '$value' . $loop_level . $variable_path;
-					elseif( $var_name == 'counter' )
-							$php_var = '$counter' . $loop_level;
-					else
-							$php_var = '$' . $var_name . $variable_path;
-				}else
-					$php_var = '$' . $var_name . $variable_path;
-
-				// compile the variable for php
-				if( isset( $function ) )
-					$php_var = $php_left_delimiter . ( !$is_init_variable && $echo ? 'echo ' : null ) . ( $params ? "( $function( $php_var, $params ) )" : "$function( $php_var )" ) . $php_right_delimiter;
-				else
-					$php_var = $php_left_delimiter . ( !$is_init_variable && $echo ? 'echo ' : null ) . $php_var . $extra_var . $php_right_delimiter;
-
-				$html = str_replace( $tag, $php_var, $html );
-
-
-			}
-		}
-
-		return $html;
-	}
-
-
-
-	/**
-	 * Check if function is in black list (sandbox)
-	 *
-	 * @access protected
-	 * @param  string $code
-	 * @throws RainTpl_SyntaxException
-	 * @return void
-	 */
-	protected function function_check( $code ){
-
-		$preg = '#(\W|\s)' . implode( '(\W|\s)|(\W|\s)', self::$black_list ) . '(\W|\s)#';
-
-		// check if the function is in the black list (or not in white list)
-		if( count(self::$black_list) && preg_match( $preg, $code, $match ) ){
-
-			// find the line of the error
-			$line = 0;
-			$rows=explode("\n",$this->tpl['source']);
-			while( !strpos($rows[$line],$code) )
-				$line++;
-
-			// stop the execution of the script
-			$e = new RainTpl_SyntaxException('Unallowed syntax in ' . $this->tpl['tpl_filename'] . ' template');
-			throw $e->setTemplateFile($this->tpl['tpl_filename'])
-				->setTag($code)
-				->setTemplateLine($line);
-		}
-
-	}
-
-
-
-	/**
-	 * Prints debug info about exception or passes it further if debug is disabled.
-	 *
-	 * @access protected
-	 * @param  RainTpl_Exception $e
-	 * @return string
-	 */
-	protected function printDebug(RainTpl_Exception $e){
-		if (!self::$debug) {
-			throw $e;
-		}
-		$output = sprintf('<h2>Exception: %s</h2><h3>%s</h3><p>template: %s</p>',
-			get_class($e),
-			$e->getMessage(),
-			$e->getTemplateFile()
-		);
-		if ($e instanceof RainTpl_SyntaxException) {
-			if (null !== $e->getTemplateLine()) {
-				$output .= '<p>line: ' . $e->getTemplateLine() . '</p>';
-			}
-			if (null !== $e->getTag()) {
-				$output .= '<p>in tag: ' . htmlspecialchars($e->getTag()) . '</p>';
-			}
-			if (null !== $e->getTemplateLine() && null !== $e->getTag()) {
-				$rows=explode("\n",  htmlspecialchars($this->tpl['source']));
-				$rows[$e->getTemplateLine()] = '<font color=red>' . $rows[$e->getTemplateLine()] . '</font>';
-				$output .= '<h3>template code</h3>' . implode('<br />', $rows) . '</pre>';
-			}
-		}
-		$output .= sprintf('<h3>trace</h3><p>In %s on line %d</p><pre>%s</pre>',
-			$e->getFile(), $e->getLine(),
-			nl2br(htmlspecialchars($e->getTraceAsString()))
-		);
-		return $output;
-	}
-}
-
-
-
-/**
- * Basic Rain tpl exception.
- */
-class RainTpl_Exception extends Exception{
-	/**
-	 * Path of template file with error.
-	 */
-	protected $templateFile = '';
-
-	/**
-	 * Returns path of template file with error.
-	 *
-	 * @return string
-	 */
-	public function getTemplateFile()
-	{
-		return $this->templateFile;
-	}
-
-	/**
-	 * Sets path of template file with error.
-	 *
-	 * @param string $templateFile
-	 * @return RainTpl_Exception
-	 */
-	public function setTemplateFile($templateFile)
-	{
-		$this->templateFile = (string) $templateFile;
-		return $this;
-	}
-}
-
-
-
-/**
- * Exception thrown when template file does not exists.
- */
-class RainTpl_NotFoundException extends RainTpl_Exception{
-}
-
-/**
- * Exception thrown when syntax error occurs.
- */
-class RainTpl_SyntaxException extends RainTpl_Exception{
-	/**
-	 * Line in template file where error has occured.
-	 *
-	 * @var int | null
-	 */
-	protected $templateLine = null;
-
-	/**
-	 * Tag which caused an error.
-	 *
-	 * @var string | null
-	 */
-	protected $tag = null;
-
-	/**
-	 * Returns line in template file where error has occured
-	 * or null if line is not defined.
-	 *
-	 * @return int | null
-	 */
-	public function getTemplateLine()
-	{
-		return $this->templateLine;
-	}
-
-	/**
-	 * Sets  line in template file where error has occured.
-	 *
-	 * @param int $templateLine
-	 * @return RainTpl_SyntaxException
-	 */
-	public function setTemplateLine($templateLine)
-	{
-		$this->templateLine = (int) $templateLine;
-		return $this;
-	}
-
-	/**
-	 * Returns tag which caused an error.
-	 *
-	 * @return string
-	 */
-	public function getTag()
-	{
-		return $this->tag;
-	}
-
-	/**
-	 * Sets tag which caused an error.
-	 *
-	 * @param string $tag
-	 * @return RainTpl_SyntaxException
-	 */
-	public function setTag($tag)
-	{
-		$this->tag = (string) $tag;
-		return $this;
-	}
-}
-
-// -- end

+ 2 - 4
lib/privatebin.php

@@ -423,10 +423,8 @@ class privatebin
             setcookie('lang', $languageselection);
             setcookie('lang', $languageselection);
         }
         }
 
 
-        $page = new RainTPL;
-        $page::$path_replace = false;
-        // we escape it here because ENT_NOQUOTES can't be used in RainTPL templates
-        $page->assign('CIPHERDATA', htmlspecialchars($this->_data, ENT_NOQUOTES));
+        $page = new view;
+        $page->assign('CIPHERDATA', $this->_data);
         $page->assign('ERROR', i18n::_($this->_error));
         $page->assign('ERROR', i18n::_($this->_error));
         $page->assign('STATUS', i18n::_($this->_status));
         $page->assign('STATUS', i18n::_($this->_status));
         $page->assign('VERSION', self::VERSION);
         $page->assign('VERSION', self::VERSION);

+ 59 - 0
lib/view.php

@@ -0,0 +1,59 @@
+<?php
+/**
+ * PrivateBin
+ *
+ * a zero-knowledge paste bin
+ *
+ * @link      https://github.com/PrivateBin/PrivateBin
+ * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
+ * @license   http://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
+ * @version   0.22
+ */
+
+/**
+ * view
+ *
+ * Displays the templates
+ */
+class view
+{
+    /**
+     * variables available in the template
+     *
+     * @access private
+     * @var    array
+     */
+    private $_variables = array();
+
+    /**
+     * assign variables to be used inside of the template
+     *
+     * @access public
+     * @param  string $name
+     * @param  mixed  $value
+     * @return void
+     */
+    public function assign($name, $value)
+    {
+        $this->_variables[$name] = $value;
+    }
+
+    /**
+     * render a template
+     *
+     * @access public
+     * @param  string $template
+     * @throws Exception
+     * @return void
+     */
+    public function draw($template)
+    {
+        $path = PATH . 'tpl' . DIRECTORY_SEPARATOR . $template . '.php';
+        if (!file_exists($path))
+        {
+            throw new Exception('Template ' . $template . ' not found!', 80);
+        }
+        extract($this->_variables);
+        include $path;
+    }
+}

+ 127 - 87
tpl/bootstrap-compact.html → tpl/bootstrap-compact.php

@@ -5,29 +5,37 @@
 		<meta http-equiv="X-UA-Compatible" content="IE=edge">
 		<meta http-equiv="X-UA-Compatible" content="IE=edge">
 		<meta name="viewport" content="width=device-width, initial-scale=1">
 		<meta name="viewport" content="width=device-width, initial-scale=1">
 		<meta name="robots" content="noindex" />
 		<meta name="robots" content="noindex" />
-		<title>{function="i18n::_('PrivateBin')"}</title>
+		<title><?php echo i18n::_('PrivateBin'); ?></title>
 		<link type="text/css" rel="stylesheet" href="css/bootstrap/bootstrap-3.3.5.css" />
 		<link type="text/css" rel="stylesheet" href="css/bootstrap/bootstrap-3.3.5.css" />
 		<link type="text/css" rel="stylesheet" href="css/bootstrap/bootstrap-theme-3.3.5.css" />
 		<link type="text/css" rel="stylesheet" href="css/bootstrap/bootstrap-theme-3.3.5.css" />
-		<link type="text/css" rel="stylesheet" href="css/bootstrap/privatebin.css?{$VERSION|rawurlencode}" />{if="$SYNTAXHIGHLIGHTING"}
-		<link type="text/css" rel="stylesheet" href="css/prettify/prettify.css?{$VERSION|rawurlencode}" />{if="strlen($SYNTAXHIGHLIGHTINGTHEME)"}
-		<link type="text/css" rel="stylesheet" href="css/prettify/{$SYNTAXHIGHLIGHTINGTHEME}.css?{$VERSION|rawurlencode}" />{/if}{/if}
+		<link type="text/css" rel="stylesheet" href="css/bootstrap/privatebin.css?<?php echo rawurlencode($VERSION); ?>" /><?php
+if ($SYNTAXHIGHLIGHTING): ?>
+		<link type="text/css" rel="stylesheet" href="css/prettify/prettify.css?<?php echo rawurlencode($VERSION); ?>" /><?php
+	if (strlen($SYNTAXHIGHLIGHTINGTHEME)): ?>
+		<link type="text/css" rel="stylesheet" href="css/prettify/<?php echo rawurlencode($SYNTAXHIGHLIGHTINGTHEME); ?>.css?<?php echo rawurlencode($VERSION); ?>" /><?php
+	endif;
+endif; ?>
 		<script type="text/javascript" src="js/jquery-1.11.3.js"></script>
 		<script type="text/javascript" src="js/jquery-1.11.3.js"></script>
 		<script type="text/javascript" src="js/sjcl-1.0.4.js"></script>
 		<script type="text/javascript" src="js/sjcl-1.0.4.js"></script>
-		<script type="text/javascript" src="js/base64-{$BASE64JSVERSION}.js"></script>
+		<script type="text/javascript" src="js/base64-<?php echo rawurlencode($BASE64JSVERSION); ?>.js"></script>
 		<script type="text/javascript" src="js/rawdeflate-0.5.js"></script>
 		<script type="text/javascript" src="js/rawdeflate-0.5.js"></script>
 		<script type="text/javascript" src="js/rawinflate-0.3.js"></script>
 		<script type="text/javascript" src="js/rawinflate-0.3.js"></script>
-		<script type="text/javascript" src="js/bootstrap-3.3.5.js"></script>{if="$SYNTAXHIGHLIGHTING"}
-		<script type="text/javascript" src="js/prettify.js?{$VERSION|rawurlencode}"></script>{/if}{if="$MARKDOWN"}
-		<script type="text/javascript" src="js/showdown-1.4.1.js"></script>{/if}
-		<script type="text/javascript" src="js/privatebin.js?{$VERSION|rawurlencode}"></script>
+		<script type="text/javascript" src="js/bootstrap-3.3.5.js"></script><?php
+if ($SYNTAXHIGHLIGHTING): ?>
+		<script type="text/javascript" src="js/prettify.js?<?php echo rawurlencode($VERSION); ?>"></script><?php
+endif;
+if ($MARKDOWN): ?>
+		<script type="text/javascript" src="js/showdown-1.4.1.js"></script><?php
+endif; ?>
+		<script type="text/javascript" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>"></script>
 		<!--[if lt IE 10]>
 		<!--[if lt IE 10]>
-		<style type="text/css">#ienotice {display:block !important;} #oldienotice {display:block !important;}</style>
+		<style type="text/css">body {padding-left:60px;padding-right:60px;} #ienotice {display:block;} #oldienotice {display:block;}</style>
 		<![endif]-->
 		<![endif]-->
-		<link rel="apple-touch-icon" href="apple-touch-icon.png?{$VERSION|rawurlencode}" sizes="180x180" />
-		<link rel="icon" type="image/png" href="favicon-32x32.png?{$VERSION|rawurlencode}" sizes="32x32" />
-		<link rel="icon" type="image/png" href="favicon-16x16.png?{$VERSION|rawurlencode}" sizes="16x16" />
-		<link rel="manifest" href="manifest.json?{$VERSION|rawurlencode}" />
-		<link rel="mask-icon" href="safari-pinned-tab.svg?{$VERSION|rawurlencode}" color="#ffcc00" />
+		<link rel="apple-touch-icon" href="apple-touch-icon.png?<?php echo rawurlencode($VERSION); ?>" sizes="180x180" />
+		<link rel="icon" type="image/png" href="favicon-32x32.png?<?php echo rawurlencode($VERSION); ?>" sizes="32x32" />
+		<link rel="icon" type="image/png" href="favicon-16x16.png?<?php echo rawurlencode($VERSION); ?>" sizes="16x16" />
+		<link rel="manifest" href="manifest.json?<?php echo rawurlencode($VERSION); ?>" />
+		<link rel="mask-icon" href="safari-pinned-tab.svg?<?php echo rawurlencode($VERSION); ?>" color="#ffcc00" />
 		<link rel="shortcut icon" href="favicon.ico">
 		<link rel="shortcut icon" href="favicon.ico">
 		<meta name="msapplication-config" content="browserconfig.xml">
 		<meta name="msapplication-config" content="browserconfig.xml">
 		<meta name="theme-color" content="#ffe57e" />
 		<meta name="theme-color" content="#ffe57e" />
@@ -37,83 +45,102 @@
 			<div class="container">
 			<div class="container">
 				<div class="navbar-header">
 				<div class="navbar-header">
 					<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
 					<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
-						<span class="sr-only">{function="i18n::_('Toggle navigation')"}</span>
+						<span class="sr-only"><?php echo i18n::_('Toggle navigation'); ?></span>
 						<span class="icon-bar"></span>
 						<span class="icon-bar"></span>
 						<span class="icon-bar"></span>
 						<span class="icon-bar"></span>
 						<span class="icon-bar"></span>
 						<span class="icon-bar"></span>
 					</button>
 					</button>
 					<a class="reloadlink navbar-brand" href="/">
 					<a class="reloadlink navbar-brand" href="/">
-						<img alt="{function="i18n::_('PrivateBin')"}" src="favicon-32x32.png" width="20" />
+						<img alt="<?php echo i18n::_('PrivateBin'); ?>" src="favicon-32x32.png" width="20" />
 					</a>
 					</a>
 				</div>
 				</div>
 				<div id="navbar" class="navbar-collapse collapse">
 				<div id="navbar" class="navbar-collapse collapse">
 					<ul class="nav navbar-nav">
 					<ul class="nav navbar-nav">
 						<li>
 						<li>
 							<button id="sendbutton" type="button" class="hidden btn btn-default navbar-btn">
 							<button id="sendbutton" type="button" class="hidden btn btn-default navbar-btn">
-								<span class="glyphicon glyphicon-upload" aria-hidden="true"></span> {function="i18n::_('Send')"}
-							</button>{if="$EXPIRECLONE"}
+								<span class="glyphicon glyphicon-upload" aria-hidden="true"></span> <?php echo i18n::_('Send'); ?>
+							</button><?php
+if ($EXPIRECLONE): ?>
 							<button id="clonebutton" type="button" class="hidden btn btn-default navbar-btn">
 							<button id="clonebutton" type="button" class="hidden btn btn-default navbar-btn">
-								<span class="glyphicon glyphicon-duplicate" aria-hidden="true"></span> {function="i18n::_('Clone')"}
-							</button>{/if}
+								<span class="glyphicon glyphicon-duplicate" aria-hidden="true"></span> <?php echo i18n::_('Clone'); ?>
+							</button><?php
+endif; ?>
 							<button id="rawtextbutton" type="button" class="hidden btn btn-default navbar-btn">
 							<button id="rawtextbutton" type="button" class="hidden btn btn-default navbar-btn">
-								<span class="glyphicon glyphicon-text-background" aria-hidden="true"></span> {function="i18n::_('Raw text')"}
+								<span class="glyphicon glyphicon-text-background" aria-hidden="true"></span> <?php echo i18n::_('Raw text'); ?>
 							</button>
 							</button>
 						</li>
 						</li>
 						<li class="dropdown">
 						<li class="dropdown">
-							<select id="pasteExpiration" name="pasteExpiration" class="hidden">
-{loop="EXPIRE"}
-								<option value="{$key}"{if="$key == $EXPIREDEFAULT"} selected="selected"{/if}>{$value}</option>{/loop}
+							<select id="pasteExpiration" name="pasteExpiration" class="hidden"><?php
+foreach ($EXPIRE as $key => $value): ?>
+								<option value="<?php echo $key; ?>"<?php
+	if ($key == $EXPIREDEFAULT): ?> selected="selected"<?php
+	endif; ?>><?php echo $value; ?></option><?php
+endforeach; ?>
 							</select>
 							</select>
-							<a id="expiration" href="#" class="hidden dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{function="i18n::_('Expires')"}: <span id="pasteExpirationDisplay">{$EXPIRE[$EXPIREDEFAULT]}</span> <span class="caret"></span></a>
-							<ul class="dropdown-menu">
-{loop="EXPIRE"}
+							<a id="expiration" href="#" class="hidden dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><?php echo i18n::_('Expires'); ?>: <span id="pasteExpirationDisplay"><?php echo $EXPIRE[$EXPIREDEFAULT]; ?></span> <span class="caret"></span></a>
+							<ul class="dropdown-menu"><?php
+foreach ($EXPIRE as $key => $value): ?>
 								<li>
 								<li>
-									<a href="#" onclick="$('#pasteExpiration').val('{$key}');$('#pasteExpirationDisplay').text('{$value}');return false;">
-										{$value}
+									<a href="#" onclick="$('#pasteExpiration').val('<?php echo $key; ?>');$('#pasteExpirationDisplay').text('<?php echo $value; ?>');return false;">
+										<?php echo $value; ?>
 									</a>
 									</a>
-								</li>{/loop}
+								</li><?php
+endforeach; ?>
 							</ul>
 							</ul>
 						</li>
 						</li>
 						<li id="formatter" class="dropdown">
 						<li id="formatter" class="dropdown">
-							<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{function="i18n::_('Options')"} <span class="caret"></span></a>
+							<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><?php echo i18n::_('Options'); ?> <span class="caret"></span></a>
 							<ul class="dropdown-menu">
 							<ul class="dropdown-menu">
 								<li id="burnafterreadingoption" class="checkbox hidden">
 								<li id="burnafterreadingoption" class="checkbox hidden">
 									<label>
 									<label>
-										<input type="checkbox" id="burnafterreading" name="burnafterreading" {if="$BURNAFTERREADINGSELECTED"} checked="checked"{/if} />
-										{function="i18n::_('Burn after reading')"}
+										<input type="checkbox" id="burnafterreading" name="burnafterreading" <?php
+if ($BURNAFTERREADINGSELECTED): ?> checked="checked"<?php
+endif; ?> />
+										<?php echo i18n::_('Burn after reading'); ?>
 									</label>
 									</label>
-								</li>{if="$DISCUSSION"}
+								</li><?php
+if ($DISCUSSION): ?>
 								<li id="opendisc" class="checkbox hidden">
 								<li id="opendisc" class="checkbox hidden">
 									<label>
 									<label>
-										<input type="checkbox" id="opendiscussion" name="opendiscussion" {if="$OPENDISCUSSION"} checked="checked"{/if} />
-										{function="i18n::_('Open discussion')"}
+										<input type="checkbox" id="opendiscussion" name="opendiscussion" <?php
+	if ($OPENDISCUSSION): ?> checked="checked"<?php
+	endif; ?> />
+										<?php echo i18n::_('Open discussion'); ?>
 									</label>
 									</label>
-								</li>{/if}
+								</li><?php
+endif; ?>
 								<li role="separator" class="divider"></li>
 								<li role="separator" class="divider"></li>
 								<li>
 								<li>
 									<div>
 									<div>
-										{function="i18n::_('Format')"}: <span id="pasteFormatterDisplay">{$FORMATTER[$FORMATTERDEFAULT]}</span> <span class="caret"></span>
+										<?php echo i18n::_('Format'); ?>: <span id="pasteFormatterDisplay"><?php echo $FORMATTER[$FORMATTERDEFAULT]; ?></span> <span class="caret"></span>
 									</div>
 									</div>
-								</li>
-{loop="FORMATTER"}
+								</li><?php
+foreach ($FORMATTER as $key => $value): ?>
 								<li>
 								<li>
-									<a href="#" onclick="$('#pasteFormatter').val('{$key}');$('#pasteFormatterDisplay').text('{$value}');return false;">
-										{$value}
+									<a href="#" onclick="$('#pasteFormatter').val('<?php echo $key; ?>');$('#pasteFormatterDisplay').text('<?php echo $value; ?>');return false;">
+										<?php echo $value; ?>
 									</a>
 									</a>
-								</li>{/loop}
+								</li><?php
+endforeach; ?>
 							</ul>
 							</ul>
-							<select id="pasteFormatter" name="pasteFormatter" class="hidden">
-{loop="FORMATTER"}
-								<option value="{$key}"{if="$key == $FORMATTERDEFAULT"} selected="selected"{/if}>{$value}</option>{/loop}
+							<select id="pasteFormatter" name="pasteFormatter" class="hidden"><?php
+foreach ($FORMATTER as $key => $value): ?>
+								<option value="<?php echo $key; ?>"<?php
+	if ($key == $FORMATTERDEFAULT): ?> selected="selected"<?php
+	endif; ?>><?php echo $value; ?></option><?php
+endforeach; ?>
 							</select>
 							</select>
-						</li>{if="$PASSWORD"}
+						</li><?php
+if ($PASSWORD): ?>
 						<li>
 						<li>
 							<div id="password" class="navbar-form hidden">
 							<div id="password" class="navbar-form hidden">
-								<input type="password" id="passwordinput" placeholder="{function="i18n::_('Password (recommended)')"}" class="form-control" size="19"/>
+								<input type="password" id="passwordinput" placeholder="<?php echo i18n::_('Password (recommended)'); ?>" class="form-control" size="19"/>
 							</div>
 							</div>
-						</li>{/if}{if="$FILEUPLOAD"}
+						</li><?php
+endif;
+if ($FILEUPLOAD): ?>
 						<li id="attach" class="hidden dropdown">
 						<li id="attach" class="hidden dropdown">
-							<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{function="i18n::_('Attach a file')"} <span class="caret"></span></a>
+							<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><?php echo i18n::_('Attach a file'); ?> <span class="caret"></span></a>
 							<ul class="dropdown-menu">
 							<ul class="dropdown-menu">
 								<li id="filewrap">
 								<li id="filewrap">
 									<div>
 									<div>
@@ -122,68 +149,81 @@
 								</li>
 								</li>
 								<li>
 								<li>
 									<a id="fileremovebutton"  href="#">
 									<a id="fileremovebutton"  href="#">
-										{function="i18n::_('Remove attachment')"}
+										<?php echo i18n::_('Remove attachment'); ?>
 									</a>
 									</a>
 								</li>
 								</li>
 							</ul>
 							</ul>
-						</li>{/if}
+						</li><?php
+endif; ?>
 					</ul>
 					</ul>
-					<ul class="nav navbar-nav pull-right">{if="strlen($LANGUAGESELECTION)"}
+					<ul class="nav navbar-nav pull-right"><?php
+if (strlen($LANGUAGESELECTION)): ?>
 						<li id="language" class="dropdown">
 						<li id="language" class="dropdown">
-							<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="glyphicon glyphicon-flag" aria-hidden="true"></span> {$LANGUAGES[$LANGUAGESELECTION][0]} <span class="caret"></span></a>
-							<ul class="dropdown-menu">
-{loop="LANGUAGES"}
+							<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="glyphicon glyphicon-flag" aria-hidden="true"></span> <?php echo $LANGUAGES[$LANGUAGESELECTION][0]; ?> <span class="caret"></span></a>
+							<ul class="dropdown-menu"><?php
+	foreach ($LANGUAGES as $key => $value): ?>
 								<li>
 								<li>
 									<a href="#" class="reloadlink" onclick="document.cookie='lang={$key}';">
 									<a href="#" class="reloadlink" onclick="document.cookie='lang={$key}';">
-										{$value[0]} ({$value[1]})
+										<?php echo $value[0]; ?> (<?php echo $value[1]; ?>)
 									</a>
 									</a>
-								</li>{/loop}
+								</li><?php
+	endforeach; ?>
 							</ul>
 							</ul>
-						</li>{/if}
+						</li><?php
+endif; ?>
 						<li>
 						<li>
 							<button id="newbutton" type="button" class="reloadlink hidden btn btn-default navbar-btn">
 							<button id="newbutton" type="button" class="reloadlink hidden btn btn-default navbar-btn">
-								<span class="glyphicon glyphicon-file" aria-hidden="true"></span> {function="i18n::_('New')"}
+								<span class="glyphicon glyphicon-file" aria-hidden="true"></span> <?php echo i18n::_('New'); ?>
 							</button>
 							</button>
 						</li>
 						</li>
 					</ul>
 					</ul>
 				</div>
 				</div>
 			</div>
 			</div>
 		</nav>
 		</nav>
-		<header class="container">{if="strlen($NOTICE)"}
+		<header class="container"><?php
+if (strlen($NOTICE)): ?>
 			<div role="alert" class="alert alert-info">
 			<div role="alert" class="alert alert-info">
-				<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span> {$NOTICE|htmlspecialchars}
-			</div>{/if}
+				<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span> <?php echo htmlspecialchars($NOTICE); ?>
+			</div><?php
+endif; ?>
 			<div id="remainingtime" role="alert" class="hidden alert alert-info">
 			<div id="remainingtime" role="alert" class="hidden alert alert-info">
 				<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>
 				<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>
-			</div>{if="$FILEUPLOAD"}
+			</div><?php
+if ($FILEUPLOAD): ?>
 			<div id="attachment" role="alert" class="hidden alert alert-info">
 			<div id="attachment" role="alert" class="hidden alert alert-info">
-				<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span> <a>{function="i18n::_('Download attachment')"}</a> <span id="clonedfile" class="hidden">{function="i18n::_('Cloned file attached.')"}</span>
-			</div>{/if}{if="strlen($STATUS)"}
+				<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span> <a><?php echo i18n::_('Download attachment'); ?></a> <span id="clonedfile" class="hidden"><?php echo i18n::_('Cloned file attached.'); ?></span>
+			</div><?php
+endif;
+if (strlen($STATUS)): ?>
 			<div id="status" role="alert" class="alert alert-success">
 			<div id="status" role="alert" class="alert alert-success">
-				<span class="glyphicon glyphicon-ok" aria-hidden="true"></span> {$STATUS|htmlspecialchars}
-			</div>{/if}
-			<div id="errormessage" role="alert" class="{if="!strlen($ERROR)"}hidden {/if}alert alert-danger"><span class="glyphicon glyphicon-alert" aria-hidden="true"></span> {$ERROR|htmlspecialchars}</div>
-			<noscript><div id="noscript" role="alert" class="nonworking alert alert-warning"><span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span> {function="i18n::_('Javascript is required for PrivateBin to work.<br />Sorry for the inconvenience.')"}</div></noscript>
-			<div id="oldienotice" role="alert" class="hidden nonworking alert alert-danger"><span class="glyphicon glyphicon-alert" aria-hidden="true"></span> {function="i18n::_('PrivateBin requires a modern browser to work.')"}</div>
-			<div id="ienotice" role="alert" class="hidden alert alert-warning"><span class="glyphicon glyphicon-question-sign" aria-hidden="true"></span> {function="i18n::_('Still using Internet Explorer? Do yourself a favor, switch to a modern browser:')"}
+				<span class="glyphicon glyphicon-ok" aria-hidden="true"></span> <?php echo htmlspecialchars($STATUS); ?>
+			</div><?php
+endif; ?>
+			<div id="errormessage" role="alert" class="<?php
+if (!strlen($ERROR)): ?>hidden <?php
+endif; ?>alert alert-danger"><span class="glyphicon glyphicon-alert" aria-hidden="true"></span> <?php echo htmlspecialchars($ERROR); ?></div>
+			<noscript><div id="noscript" role="alert" class="nonworking alert alert-warning"><span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span> <?php echo i18n::_('Javascript is required for PrivateBin to work.<br />Sorry for the inconvenience.'); ?></div></noscript>
+			<div id="oldienotice" role="alert" class="hidden nonworking alert alert-danger"><span class="glyphicon glyphicon-alert" aria-hidden="true"></span> <?php echo i18n::_('PrivateBin requires a modern browser to work.'); ?></div>
+			<div id="ienotice" role="alert" class="hidden alert alert-warning"><span class="glyphicon glyphicon-question-sign" aria-hidden="true"></span> <?php echo i18n::_('Still using Internet Explorer? Do yourself a favor, switch to a modern browser:'); ?>
 				<a href="https://www.mozilla.org/firefox/">Firefox</a>,
 				<a href="https://www.mozilla.org/firefox/">Firefox</a>,
 				<a href="https://www.opera.com/">Opera</a>,
 				<a href="https://www.opera.com/">Opera</a>,
 				<a href="https://www.google.com/chrome">Chrome</a>,
 				<a href="https://www.google.com/chrome">Chrome</a>,
-				<a href="https://www.apple.com/safari">Safari</a>,
-				<a href="https://www.microsoft.com/edge">Edge</a>...
+				<a href="https://www.apple.com/safari">Safari</a>...
 			</div>
 			</div>
 			<div id="pasteresult" role="alert" class="hidden alert alert-success">
 			<div id="pasteresult" role="alert" class="hidden alert alert-success">
 				<span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
 				<span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
 				<div id="deletelink"></div>
 				<div id="deletelink"></div>
-				<div id="pastelink">{if="strlen($URLSHORTENER)"}
-					<button id="shortenbutton" data-shortener="{$URLSHORTENER|htmlspecialchars}" type="button" class="btn btn-primary">
-						<span class="glyphicon glyphicon-send" aria-hidden="true"></span> {function="i18n::_('Shorten URL')"}
-					</button>
-				{/if}</div>
+				<div id="pastelink"><?php
+if (strlen($URLSHORTENER)): ?>
+					<button id="shortenbutton" data-shortener="<?php echo htmlspecialchars($URLSHORTENER); ?>" type="button" class="btn btn-primary">
+						<span class="glyphicon glyphicon-send" aria-hidden="true"></span> <?php echo i18n::_('Shorten URL'); ?>
+					</button><?php
+endif; ?>
+				</div>
 			</div>
 			</div>
 			<ul id="preview" class="nav nav-tabs hidden">
 			<ul id="preview" class="nav nav-tabs hidden">
-				<li role="presentation" class="active"><a id="messageedit" href="#">{function="i18n::_('Editor')"}</a></li>
-				<li role="presentation"><a id="messagepreview" href="#">{function="i18n::_('Preview')"}</a></li>
+				<li role="presentation" class="active"><a id="messageedit" href="#"><?php echo i18n::_('Editor'); ?></a></li>
+				<li role="presentation"><a id="messagepreview" href="#"><?php echo i18n::_('Preview'); ?></a></li>
 			</ul>
 			</ul>
 		</header>
 		</header>
 		<section class="container">
 		<section class="container">
@@ -198,19 +238,19 @@
 		</section>
 		</section>
 		<section class="container">
 		<section class="container">
 			<div id="discussion" class="hidden">
 			<div id="discussion" class="hidden">
-				<h4>{function="i18n::_('Discussion')"}</h4>
+				<h4><?php echo i18n::_('Discussion'); ?></h4>
 				<div id="comments"></div>
 				<div id="comments"></div>
 			</div>
 			</div>
 		</section>
 		</section>
 		<footer class="container">
 		<footer class="container">
 			<div class="row">
 			<div class="row">
-				<h4 class="col-md-5 col-xs-8">{function="i18n::_('PrivateBin')"} <small>- {function="i18n::_('Because ignorance is bliss')"}</small></h4>
-				<p class="col-md-1 col-xs-4 text-center">{$VERSION}</p>
+				<h4 class="col-md-5 col-xs-8"><?php echo i18n::_('PrivateBin'); ?> <small>- <?php echo i18n::_('Because ignorance is bliss'); ?></small></h4>
+				<p class="col-md-1 col-xs-4 text-center"><?php echo $VERSION; ?></p>
 				<p id="aboutbox" class="col-md-6 col-xs-12">
 				<p id="aboutbox" class="col-md-6 col-xs-12">
-					{function="i18n::_('PrivateBin is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted <i>in the browser</i> using 256 bits AES. More information on the <a href="https://github.com/PrivateBin/PrivateBin/wiki">project page</a>.')"}
+					<?php echo i18n::_('PrivateBin is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted <i>in the browser</i> using 256 bits AES. More information on the <a href="https://github.com/PrivateBin/PrivateBin/wiki">project page</a>.'); ?>
 				</p>
 				</p>
 			</div>
 			</div>
 		</footer>
 		</footer>
-		<div id="cipherdata" class="hidden">{$CIPHERDATA}</div>
+		<div id="cipherdata" class="hidden"><?php echo htmlspecialchars($CIPHERDATA, ENT_NOQUOTES); ?></div>
 	</body>
 	</body>
 </html>
 </html>

+ 0 - 212
tpl/bootstrap-dark-page.html

@@ -1,212 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
-		<meta charset="utf-8" />
-		<meta http-equiv="X-UA-Compatible" content="IE=edge">
-		<meta name="viewport" content="width=device-width, initial-scale=1">
-		<meta name="robots" content="noindex" />
-		<title>{function="i18n::_('PrivateBin')"}</title>
-		<link type="text/css" rel="stylesheet" href="css/bootstrap/bootstrap-theme-3.3.5.css" />
-		<link type="text/css" rel="stylesheet" href="css/bootstrap/darkstrap-0.9.3.css" />
-		<link type="text/css" rel="stylesheet" href="css/bootstrap/privatebin.css?{$VERSION|rawurlencode}" />{if="$SYNTAXHIGHLIGHTING"}
-		<link type="text/css" rel="stylesheet" href="css/prettify/prettify.css?{$VERSION|rawurlencode}" />{if="strlen($SYNTAXHIGHLIGHTINGTHEME)"}
-		<link type="text/css" rel="stylesheet" href="css/prettify/{$SYNTAXHIGHLIGHTINGTHEME}.css?{$VERSION|rawurlencode}" />{/if}{/if}
-		<script type="text/javascript" src="js/jquery-1.11.3.js"></script>
-		<script type="text/javascript" src="js/sjcl-1.0.4.js"></script>
-		<script type="text/javascript" src="js/base64-{$BASE64JSVERSION}.js"></script>
-		<script type="text/javascript" src="js/rawdeflate-0.5.js"></script>
-		<script type="text/javascript" src="js/rawinflate-0.3.js"></script>
-		<script type="text/javascript" src="js/bootstrap-3.3.5.js"></script>{if="$SYNTAXHIGHLIGHTING"}
-		<script type="text/javascript" src="js/prettify.js?{$VERSION|rawurlencode}"></script>{/if}{if="$MARKDOWN"}
-		<script type="text/javascript" src="js/showdown-1.4.1.js"></script>{/if}
-		<script type="text/javascript" src="js/privatebin.js?{$VERSION|rawurlencode}"></script>
-		<!--[if lt IE 10]>
-		<style type="text/css">#ienotice {display:block !important;} #oldienotice {display:block !important;}</style>
-		<![endif]-->
-		<link rel="apple-touch-icon" href="apple-touch-icon.png?{$VERSION|rawurlencode}" sizes="180x180" />
-		<link rel="icon" type="image/png" href="favicon-32x32.png?{$VERSION|rawurlencode}" sizes="32x32" />
-		<link rel="icon" type="image/png" href="favicon-16x16.png?{$VERSION|rawurlencode}" sizes="16x16" />
-		<link rel="manifest" href="manifest.json?{$VERSION|rawurlencode}" />
-		<link rel="mask-icon" href="safari-pinned-tab.svg?{$VERSION|rawurlencode}" color="#ffcc00" />
-		<link rel="shortcut icon" href="favicon.ico">
-		<meta name="msapplication-config" content="browserconfig.xml">
-		<meta name="theme-color" content="#ffe57e" />
-	</head>
-	<body role="document">
-		<nav class="navbar navbar-inverse navbar-static-top">
-				<div class="navbar-header">
-					<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
-						<span class="sr-only">{function="i18n::_('Toggle navigation')"}</span>
-						<span class="icon-bar"></span>
-						<span class="icon-bar"></span>
-						<span class="icon-bar"></span>
-					</button>
-					<a class="reloadlink navbar-brand" href="/">
-						<img alt="{function="i18n::_('PrivateBin')"}" src="favicon-32x32.png" width="20" />
-					</a>
-				</div>
-				<div id="navbar" class="navbar-collapse collapse">
-					<ul class="nav navbar-nav">
-						<li>
-							<button id="sendbutton" type="button" class="hidden btn btn-warning navbar-btn">
-								<span class="glyphicon glyphicon-upload" aria-hidden="true"></span> {function="i18n::_('Send')"}
-							</button>{if="$EXPIRECLONE"}
-							<button id="clonebutton" type="button" class="hidden btn btn-warning navbar-btn">
-								<span class="glyphicon glyphicon-duplicate" aria-hidden="true"></span> {function="i18n::_('Clone')"}
-							</button>{/if}
-							<button id="rawtextbutton" type="button" class="hidden btn btn-warning navbar-btn">
-								<span class="glyphicon glyphicon-text-background" aria-hidden="true"></span> {function="i18n::_('Raw text')"}
-							</button>
-						</li>
-						<li class="dropdown">
-							<select id="pasteExpiration" name="pasteExpiration" class="hidden">
-{loop="EXPIRE"}
-								<option value="{$key}"{if="$key == $EXPIREDEFAULT"} selected="selected"{/if}>{$value}</option>{/loop}
-							</select>
-							<a id="expiration" href="#" class="hidden dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{function="i18n::_('Expires')"}: <span id="pasteExpirationDisplay">{$EXPIRE[$EXPIREDEFAULT]}</span> <span class="caret"></span></a>
-							<ul class="dropdown-menu">
-{loop="EXPIRE"}
-								<li>
-									<a href="#" onclick="$('#pasteExpiration').val('{$key}');$('#pasteExpirationDisplay').text('{$value}');return false;">
-										{$value}
-									</a>
-								</li>{/loop}
-							</ul>
-						</li>
-						<li>
-							<div id="burnafterreadingoption" class="navbar-text checkbox hidden">
-								<label>
-									<input type="checkbox" id="burnafterreading" name="burnafterreading" {if="$BURNAFTERREADINGSELECTED"} checked="checked"{/if} />
-									{function="i18n::_('Burn after reading')"}
-								</label>
-							</div>
-						</li>{if="$DISCUSSION"}
-						<li>
-							<div id="opendisc" class="navbar-text checkbox hidden">
-								<label>
-									<input type="checkbox" id="opendiscussion" name="opendiscussion" {if="$OPENDISCUSSION"} checked="checked"{/if} />
-									{function="i18n::_('Open discussion')"}
-							 	</label>
-							</div>
-						</li>{/if}{if="$PASSWORD"}
-						<li>
-							<div id="password" class="navbar-form hidden">
-								<input type="password" id="passwordinput" placeholder="{function="i18n::_('Password (recommended)')"}" class="form-control" size="19"/>
-							</div>
-						</li>{/if}{if="$FILEUPLOAD"}
-						<li id="attach" class="hidden dropdown">
-							<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{function="i18n::_('Attach a file')"} <span class="caret"></span></a>
-							<ul class="dropdown-menu">
-								<li id="filewrap">
-									<div>
-										<input type="file" id="file" name="file" />
-									</div>
-								</li>
-								<li>
-									<a id="fileremovebutton"  href="#">
-										{function="i18n::_('Remove attachment')"}
-									</a>
-								</li>
-							</ul>
-						</li>{/if}
-						<li class="dropdown">
-							<select id="pasteFormatter" name="pasteFormatter" class="hidden">
-{loop="FORMATTER"}
-								<option value="{$key}"{if="$key == $FORMATTERDEFAULT"} selected="selected"{/if}>{$value}</option>{/loop}
-							</select>
-							<a id="formatter" href="#" class="hidden dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{function="i18n::_('Format')"}: <span id="pasteFormatterDisplay">{$FORMATTER[$FORMATTERDEFAULT]}</span> <span class="caret"></span></a>
-							<ul class="dropdown-menu">
-{loop="FORMATTER"}
-								<li>
-									<a href="#" onclick="$('#pasteFormatter').val('{$key}');$('#pasteFormatterDisplay').text('{$value}');return false;">
-										{$value}
-									</a>
-								</li>{/loop}
-							</ul>
-						</li>
-					</ul>
-					<ul class="nav navbar-nav pull-right">{if="strlen($LANGUAGESELECTION)"}
-						<li id="language" class="dropdown">
-							<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="glyphicon glyphicon-flag" aria-hidden="true"></span> {$LANGUAGES[$LANGUAGESELECTION][0]} <span class="caret"></span></a>
-							<ul class="dropdown-menu">
-{loop="LANGUAGES"}
-								<li>
-									<a href="#" class="reloadlink" onclick="document.cookie='lang={$key}';">
-									{$value[0]} ({$value[1]})
-								</a>
-							</li>{/loop}
-						</ul>
-					</li>{/if}
-					<li>
-						<button id="newbutton" type="button" class="reloadlink hidden btn btn-warning navbar-btn">
-							<span class="glyphicon glyphicon-file" aria-hidden="true"></span> {function="i18n::_('New')"}
-						</button>
-					</li>
-				</ul>
-			</div>
-		</nav>
-		<header class="container">{if="strlen($NOTICE)"}
-			<div role="alert" class="alert alert-info">
-				<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span> {$NOTICE|htmlspecialchars}
-			</div>{/if}
-			<div id="remainingtime" role="alert" class="hidden alert alert-info">
-				<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>
-			</div>{if="$FILEUPLOAD"}
-			<div id="attachment" role="alert" class="hidden alert alert-info">
-				<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span> <a>{function="i18n::_('Download attachment')"}</a> <span id="clonedfile" class="hidden">{function="i18n::_('Cloned file attached.')"}</span>
-			</div>{/if}{if="strlen($STATUS)"}
-			<div id="status" role="alert" class="alert alert-success">
-				<span class="glyphicon glyphicon-ok" aria-hidden="true"></span> {$STATUS|htmlspecialchars}
-			</div>{/if}
-			<div id="errormessage" role="alert" class="{if="!strlen($ERROR)"}hidden {/if}alert alert-danger"><span class="glyphicon glyphicon-alert" aria-hidden="true"></span> {$ERROR|htmlspecialchars}</div>
-			<noscript><div id="noscript" role="alert" class="nonworking alert alert-error"><span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span> {function="i18n::_('Javascript is required for PrivateBin to work.<br />Sorry for the inconvenience.')"}</div></noscript>
-			<div id="oldienotice" role="alert" class="hidden nonworking alert alert-danger"><span class="glyphicon glyphicon-alert" aria-hidden="true"></span> {function="i18n::_('PrivateBin requires a modern browser to work.')"}</div>
-			<div id="ienotice" role="alert" class="hidden alert alert-error"><span class="glyphicon glyphicon-question-sign" aria-hidden="true"></span> {function="i18n::_('Still using Internet Explorer? Do yourself a favor, switch to a modern browser:')"}
-				<a href="https://www.mozilla.org/firefox/">Firefox</a>,
-				<a href="https://www.opera.com/">Opera</a>,
-				<a href="https://www.google.com/chrome">Chrome</a>,
-				<a href="https://www.apple.com/safari">Safari</a>,
-				<a href="https://www.microsoft.com/edge">Edge</a>...
-			</div>
-			<div id="pasteresult" role="alert" class="hidden alert alert-success">
-				<span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
-				<div id="deletelink"></div>
-				<div id="pastelink">{if="strlen($URLSHORTENER)"}
-					<button id="shortenbutton" data-shortener="{$URLSHORTENER|htmlspecialchars}" type="button" class="btn btn-warning">
-						<span class="glyphicon glyphicon-send" aria-hidden="true"></span> {function="i18n::_('Shorten URL')"}
-					</button>
-				{/if}</div>
-			</div>
-			<ul id="preview" class="nav nav-tabs hidden">
-				<li role="presentation" class="active"><a id="messageedit" href="#">{function="i18n::_('Editor')"}</a></li>
-				<li role="presentation"><a id="messagepreview" href="#">{function="i18n::_('Preview')"}</a></li>
-			</ul>
-		</header>
-		<section class="container">
-			<article class="row">
-				<div id="image" class="col-md-12 text-center hidden"></div>
-				<div id="prettymessage" class="col-md-12 hidden">
-					<pre id="prettyprint" class="col-md-12 prettyprint linenums:1"></pre>
-				</div>
-				<div id="cleartext" class="col-md-12 hidden"></div>
-				<p class="col-md-12"><textarea id="message" name="message" cols="80" rows="25" class="form-control hidden"></textarea></p>
-			</article>
-		</section>
-		<section class="container">
-			<div id="discussion" class="hidden">
-				<h4>{function="i18n::_('Discussion')"}</h4>
-				<div id="comments"></div>
-			</div>
-		</section>
-		<footer class="container">
-			<div class="row">
-				<h4 class="col-md-5 col-xs-8">{function="i18n::_('PrivateBin')"} <small>- {function="i18n::_('Because ignorance is bliss')"}</small></h4>
-				<p class="col-md-1 col-xs-4 text-center">{$VERSION}</p>
-				<p id="aboutbox" class="col-md-6 col-xs-12">
-					{function="i18n::_('PrivateBin is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted <i>in the browser</i> using 256 bits AES. More information on the <a href="https://github.com/PrivateBin/PrivateBin/wiki">project page</a>.')"}
-				</p>
-			</div>
-		</footer>
-		<div id="cipherdata" class="hidden">{$CIPHERDATA}</div>
-	</body>
-</html>

+ 252 - 0
tpl/bootstrap-dark-page.php

@@ -0,0 +1,252 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<meta http-equiv="X-UA-Compatible" content="IE=edge">
+		<meta name="viewport" content="width=device-width, initial-scale=1">
+		<meta name="robots" content="noindex" />
+		<title><?php echo i18n::_('PrivateBin'); ?></title>
+		<link type="text/css" rel="stylesheet" href="css/bootstrap/bootstrap-theme-3.3.5.css" />
+		<link type="text/css" rel="stylesheet" href="css/bootstrap/darkstrap-0.9.3.css" />
+		<link type="text/css" rel="stylesheet" href="css/bootstrap/privatebin.css?<?php echo rawurlencode($VERSION); ?>" /><?php
+if ($SYNTAXHIGHLIGHTING): ?>
+		<link type="text/css" rel="stylesheet" href="css/prettify/prettify.css?<?php echo rawurlencode($VERSION); ?>" /><?php
+	if (strlen($SYNTAXHIGHLIGHTINGTHEME)): ?>
+		<link type="text/css" rel="stylesheet" href="css/prettify/<?php echo rawurlencode($SYNTAXHIGHLIGHTINGTHEME); ?>.css?<?php echo rawurlencode($VERSION); ?>" /><?php
+	endif;
+endif; ?>
+		<script type="text/javascript" src="js/jquery-1.11.3.js"></script>
+		<script type="text/javascript" src="js/sjcl-1.0.4.js"></script>
+		<script type="text/javascript" src="js/base64-<?php echo rawurlencode($BASE64JSVERSION); ?>.js"></script>
+		<script type="text/javascript" src="js/rawdeflate-0.5.js"></script>
+		<script type="text/javascript" src="js/rawinflate-0.3.js"></script>
+		<script type="text/javascript" src="js/bootstrap-3.3.5.js"></script><?php
+if ($SYNTAXHIGHLIGHTING): ?>
+		<script type="text/javascript" src="js/prettify.js?<?php echo rawurlencode($VERSION); ?>"></script><?php
+endif;
+if ($MARKDOWN): ?>
+		<script type="text/javascript" src="js/showdown-1.4.1.js"></script><?php
+endif; ?>
+		<script type="text/javascript" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>"></script>
+		<!--[if lt IE 10]>
+		<style type="text/css">body {padding-left:60px;padding-right:60px;} #ienotice {display:block;} #oldienotice {display:block;}</style>
+		<![endif]-->
+		<link rel="apple-touch-icon" href="apple-touch-icon.png?<?php echo rawurlencode($VERSION); ?>" sizes="180x180" />
+		<link rel="icon" type="image/png" href="favicon-32x32.png?<?php echo rawurlencode($VERSION); ?>" sizes="32x32" />
+		<link rel="icon" type="image/png" href="favicon-16x16.png?<?php echo rawurlencode($VERSION); ?>" sizes="16x16" />
+		<link rel="manifest" href="manifest.json?<?php echo rawurlencode($VERSION); ?>" />
+		<link rel="mask-icon" href="safari-pinned-tab.svg?<?php echo rawurlencode($VERSION); ?>" color="#ffcc00" />
+		<link rel="shortcut icon" href="favicon.ico">
+		<meta name="msapplication-config" content="browserconfig.xml">
+		<meta name="theme-color" content="#ffe57e" />
+	</head>
+	<body role="document">
+		<nav class="navbar navbar-inverse navbar-static-top">
+			<div class="navbar-header">
+				<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
+					<span class="sr-only"><?php echo i18n::_('Toggle navigation'); ?></span>
+					<span class="icon-bar"></span>
+					<span class="icon-bar"></span>
+					<span class="icon-bar"></span>
+				</button>
+				<a class="reloadlink navbar-brand" href="/">
+					<img alt="<?php echo i18n::_('PrivateBin'); ?>" src="favicon-32x32.png" width="20" />
+				</a>
+			</div>
+			<div id="navbar" class="navbar-collapse collapse">
+				<ul class="nav navbar-nav">
+					<li>
+						<button id="sendbutton" type="button" class="hidden btn btn-warning navbar-btn">
+							<span class="glyphicon glyphicon-upload" aria-hidden="true"></span> <?php echo i18n::_('Send'); ?>
+						</button><?php
+if ($EXPIRECLONE): ?>
+						<button id="clonebutton" type="button" class="hidden btn btn-warning navbar-btn">
+							<span class="glyphicon glyphicon-duplicate" aria-hidden="true"></span> <?php echo i18n::_('Clone'); ?>
+						</button><?php
+endif; ?>
+						<button id="rawtextbutton" type="button" class="hidden btn btn-warning navbar-btn">
+							<span class="glyphicon glyphicon-text-background" aria-hidden="true"></span> <?php echo i18n::_('Raw text'); ?>
+						</button>
+					</li>
+					<li class="dropdown">
+						<select id="pasteExpiration" name="pasteExpiration" class="hidden"><?php
+foreach ($EXPIRE as $key => $value): ?>
+							<option value="<?php echo $key; ?>"<?php
+	if ($key == $EXPIREDEFAULT): ?> selected="selected"<?php
+	endif; ?>><?php echo $value; ?></option><?php
+endforeach; ?>
+						</select>
+						<a id="expiration" href="#" class="hidden dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><?php echo i18n::_('Expires'); ?>: <span id="pasteExpirationDisplay"><?php echo $EXPIRE[$EXPIREDEFAULT]; ?></span> <span class="caret"></span></a>
+						<ul class="dropdown-menu"><?php
+foreach ($EXPIRE as $key => $value): ?>
+							<li>
+								<a href="#" onclick="$('#pasteExpiration').val('<?php echo $key; ?>');$('#pasteExpirationDisplay').text('<?php echo $value; ?>');return false;">
+									<?php echo $value; ?>
+								</a>
+							</li><?php
+endforeach; ?>
+						</ul>
+					</li>
+					<li>
+						<div id="burnafterreadingoption" class="navbar-text checkbox hidden">
+							<label>
+								<input type="checkbox" id="burnafterreading" name="burnafterreading" <?php
+if ($BURNAFTERREADINGSELECTED): ?> checked="checked"<?php
+endif; ?> />
+								<?php echo i18n::_('Burn after reading'); ?>
+							</label>
+						</div>
+					</li><?php
+if ($DISCUSSION): ?>
+					<li>
+						<div id="opendisc" class="navbar-text checkbox hidden">
+							<label>
+								<input type="checkbox" id="opendiscussion" name="opendiscussion" <?php
+	if ($OPENDISCUSSION): ?> checked="checked"<?php
+	endif; ?> />
+								<?php echo i18n::_('Open discussion'); ?>
+						 	</label>
+						</div>
+					</li><?php
+endif;
+if ($PASSWORD): ?>
+					<li>
+						<div id="password" class="navbar-form hidden">
+							<input type="password" id="passwordinput" placeholder="<?php echo i18n::_('Password (recommended)'); ?>" class="form-control" size="19" />
+						</div>
+					</li><?php
+endif;
+if ($FILEUPLOAD): ?>
+					<li id="attach" class="hidden dropdown">
+						<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><?php echo i18n::_('Attach a file'); ?> <span class="caret"></span></a>
+						<ul class="dropdown-menu">
+							<li id="filewrap">
+								<div>
+									<input type="file" id="file" name="file" />
+								</div>
+							</li>
+							<li>
+								<a id="fileremovebutton"  href="#">
+									<?php echo i18n::_('Remove attachment'); ?>
+								</a>
+							</li>
+						</ul>
+					</li><?php
+endif; ?>
+					<li class="dropdown">
+						<select id="pasteFormatter" name="pasteFormatter" class="hidden"><?php
+foreach ($FORMATTER as $key => $value): ?>
+							<option value="<?php echo $key; ?>"<?php
+	if ($key == $FORMATTERDEFAULT): ?> selected="selected"<?php
+	endif; ?>><?php echo $value; ?></option><?php
+endforeach; ?>
+						</select>
+						<a id="formatter" href="#" class="hidden dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><?php echo i18n::_('Format'); ?>: <span id="pasteFormatterDisplay"><?php echo $FORMATTER[$FORMATTERDEFAULT]; ?></span> <span class="caret"></span></a>
+						<ul class="dropdown-menu"><?php
+foreach ($FORMATTER as $key => $value): ?>
+							<li>
+								<a href="#" onclick="$('#pasteFormatter').val('<?php echo $key; ?>');$('#pasteFormatterDisplay').text('<?php echo $value; ?>');return false;">
+									<?php echo $value; ?>
+								</a>
+							</li><?php
+endforeach; ?>
+						</ul>
+					</li>
+				</ul>
+				<ul class="nav navbar-nav pull-right"><?php
+if (strlen($LANGUAGESELECTION)): ?>
+					<li id="language" class="dropdown">
+						<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="glyphicon glyphicon-flag" aria-hidden="true"></span> <?php echo $LANGUAGES[$LANGUAGESELECTION][0]; ?> <span class="caret"></span></a>
+						<ul class="dropdown-menu"><?php
+	foreach ($LANGUAGES as $key => $value): ?>
+							<li>
+								<a href="#" class="reloadlink" onclick="document.cookie='lang=<?php echo $key; ?>';">
+									<?php echo $value[0]; ?> (<?php echo $value[1]; ?>)
+								</a>
+							</li><?php
+	endforeach; ?>
+						</ul>
+					</li><?php
+endif; ?>
+					<li>
+						<button id="newbutton" type="button" class="reloadlink hidden btn btn-warning navbar-btn">
+							<span class="glyphicon glyphicon-file" aria-hidden="true"></span> <?php echo i18n::_('New'); ?>
+						</button>
+					</li>
+				</ul>
+			</div>
+		</nav>
+		<header class="container"><?php
+if (strlen($NOTICE)): ?>
+			<div role="alert" class="alert alert-info">
+				<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span> <?php echo htmlspecialchars($NOTICE); ?>
+			</div><?php
+endif; ?>
+			<div id="remainingtime" role="alert" class="hidden alert alert-info">
+				<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>
+			</div><?php
+if ($FILEUPLOAD): ?>
+			<div id="attachment" role="alert" class="hidden alert alert-info">
+				<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span> <a><?php echo i18n::_('Download attachment'); ?></a> <span id="clonedfile" class="hidden"><?php echo i18n::_('Cloned file attached.'); ?></span>
+			</div><?php
+endif;
+if (strlen($STATUS)): ?>
+			<div id="status" role="alert" class="alert alert-success">
+				<span class="glyphicon glyphicon-ok" aria-hidden="true"></span> <?php echo htmlspecialchars($STATUS); ?>
+			</div><?php
+endif; ?>
+			<div id="errormessage" role="alert" class="<?php
+if (!strlen($ERROR)): ?>hidden <?php
+endif; ?>alert alert-danger"><span class="glyphicon glyphicon-alert" aria-hidden="true"></span> <?php echo htmlspecialchars($ERROR); ?></div>
+			<noscript><div id="noscript" role="alert" class="nonworking alert alert-error"><span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span> <?php echo i18n::_('Javascript is required for PrivateBin to work.<br />Sorry for the inconvenience.'); ?></div></noscript>
+			<div id="oldienotice" role="alert" class="hidden nonworking alert alert-danger"><span class="glyphicon glyphicon-alert" aria-hidden="true"></span> <?php echo i18n::_('PrivateBin requires a modern browser to work.'); ?></div>
+			<div id="ienotice" role="alert" class="hidden alert alert-error"><span class="glyphicon glyphicon-question-sign" aria-hidden="true"></span> <?php echo i18n::_('Still using Internet Explorer? Do yourself a favor, switch to a modern browser:'); ?>
+				<a href="https://www.mozilla.org/firefox/">Firefox</a>,
+				<a href="https://www.opera.com/">Opera</a>,
+				<a href="https://www.google.com/chrome">Chrome</a>,
+				<a href="https://www.apple.com/safari">Safari</a>...
+			</div>
+			<div id="pasteresult" role="alert" class="hidden alert alert-success">
+				<span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
+				<div id="deletelink"></div>
+				<div id="pastelink"><?php
+if (strlen($URLSHORTENER)): ?>
+					<button id="shortenbutton" data-shortener="<?php echo htmlspecialchars($URLSHORTENER); ?>" type="button" class="btn btn-warning">
+						<span class="glyphicon glyphicon-send" aria-hidden="true"></span> <?php echo i18n::_('Shorten URL'); ?>
+					</button><?php
+endif; ?>
+				</div>
+			</div>
+			<ul id="preview" class="nav nav-tabs hidden">
+				<li role="presentation" class="active"><a id="messageedit" href="#"><?php echo i18n::_('Editor'); ?></a></li>
+				<li role="presentation"><a id="messagepreview" href="#"><?php echo i18n::_('Preview'); ?></a></li>
+			</ul>
+		</header>
+		<section class="container">
+			<article class="row">
+				<div id="image" class="col-md-12 text-center hidden"></div>
+				<div id="prettymessage" class="col-md-12 hidden">
+					<pre id="prettyprint" class="col-md-12 prettyprint linenums:1"></pre>
+				</div>
+				<div id="cleartext" class="col-md-12 hidden"></div>
+				<p class="col-md-12"><textarea id="message" name="message" cols="80" rows="25" class="form-control hidden"></textarea></p>
+			</article>
+		</section>
+		<section class="container">
+			<div id="discussion" class="hidden">
+				<h4><?php echo i18n::_('Discussion'); ?></h4>
+				<div id="comments"></div>
+			</div>
+		</section>
+		<footer class="container">
+			<div class="row">
+				<h4 class="col-md-5 col-xs-8"><?php echo i18n::_('PrivateBin'); ?> <small>- <?php echo i18n::_('Because ignorance is bliss'); ?></small></h4>
+				<p class="col-md-1 col-xs-4 text-center"><?php echo $VERSION; ?></p>
+				<p id="aboutbox" class="col-md-6 col-xs-12">
+					<?php echo i18n::_('PrivateBin is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted <i>in the browser</i> using 256 bits AES. More information on the <a href="https://github.com/PrivateBin/PrivateBin/wiki">project page</a>.'); ?>
+				</p>
+			</div>
+		</footer>
+		<div id="cipherdata" class="hidden"><?php echo htmlspecialchars($CIPHERDATA, ENT_NOQUOTES); ?></div>
+	</body>
+</html>

+ 0 - 212
tpl/bootstrap-dark.html

@@ -1,212 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
-		<meta charset="utf-8" />
-		<meta http-equiv="X-UA-Compatible" content="IE=edge">
-		<meta name="viewport" content="width=device-width, initial-scale=1">
-		<meta name="robots" content="noindex" />
-		<title>{function="i18n::_('PrivateBin')"}</title>
-		<link type="text/css" rel="stylesheet" href="css/bootstrap/bootstrap-theme-3.3.5.css" />
-		<link type="text/css" rel="stylesheet" href="css/bootstrap/darkstrap-0.9.3.css" />
-		<link type="text/css" rel="stylesheet" href="css/bootstrap/privatebin.css?{$VERSION|rawurlencode}" />{if="$SYNTAXHIGHLIGHTING"}
-		<link type="text/css" rel="stylesheet" href="css/prettify/prettify.css?{$VERSION|rawurlencode}" />{if="strlen($SYNTAXHIGHLIGHTINGTHEME)"}
-		<link type="text/css" rel="stylesheet" href="css/prettify/{$SYNTAXHIGHLIGHTINGTHEME}.css?{$VERSION|rawurlencode}" />{/if}{/if}
-		<script type="text/javascript" src="js/jquery-1.11.3.js"></script>
-		<script type="text/javascript" src="js/sjcl-1.0.4.js"></script>
-		<script type="text/javascript" src="js/base64-{$BASE64JSVERSION}.js"></script>
-		<script type="text/javascript" src="js/rawdeflate-0.5.js"></script>
-		<script type="text/javascript" src="js/rawinflate-0.3.js"></script>
-		<script type="text/javascript" src="js/bootstrap-3.3.5.js"></script>{if="$SYNTAXHIGHLIGHTING"}
-		<script type="text/javascript" src="js/prettify.js?{$VERSION|rawurlencode}"></script>{/if}{if="$MARKDOWN"}
-		<script type="text/javascript" src="js/showdown-1.4.1.js"></script>{/if}
-		<script type="text/javascript" src="js/privatebin.js?{$VERSION|rawurlencode}"></script>
-		<!--[if lt IE 10]>
-		<style type="text/css">#ienotice {display:block !important;} #oldienotice {display:block !important;}</style>
-		<![endif]-->
-		<link rel="apple-touch-icon" href="apple-touch-icon.png?{$VERSION|rawurlencode}" sizes="180x180" />
-		<link rel="icon" type="image/png" href="favicon-32x32.png?{$VERSION|rawurlencode}" sizes="32x32" />
-		<link rel="icon" type="image/png" href="favicon-16x16.png?{$VERSION|rawurlencode}" sizes="16x16" />
-		<link rel="manifest" href="manifest.json?{$VERSION|rawurlencode}" />
-		<link rel="mask-icon" href="safari-pinned-tab.svg?{$VERSION|rawurlencode}" color="#ffcc00" />
-		<link rel="shortcut icon" href="favicon.ico">
-		<meta name="msapplication-config" content="browserconfig.xml">
-		<meta name="theme-color" content="#ffe57e" />
-	</head>
-	<body role="document">
-		<nav class="navbar navbar-inverse navbar-static-top">
-				<div class="navbar-header">
-					<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
-						<span class="sr-only">{function="i18n::_('Toggle navigation')"}</span>
-						<span class="icon-bar"></span>
-						<span class="icon-bar"></span>
-						<span class="icon-bar"></span>
-					</button>
-					<a class="reloadlink navbar-brand" href="/">
-						<img alt="{function="i18n::_('PrivateBin')"}" src="favicon-32x32.png" width="20" />
-					</a>
-				</div>
-				<div id="navbar" class="navbar-collapse collapse">
-					<ul class="nav navbar-nav">
-						<li>
-							<button id="newbutton" type="button" class="reloadlink hidden btn btn-warning navbar-btn">
-								<span class="glyphicon glyphicon-file" aria-hidden="true"></span> {function="i18n::_('New')"}
-							</button>{if="$EXPIRECLONE"}
-							<button id="clonebutton" type="button" class="hidden btn btn-warning navbar-btn">
-								<span class="glyphicon glyphicon-duplicate" aria-hidden="true"></span> {function="i18n::_('Clone')"}
-							</button>{/if}
-							<button id="rawtextbutton" type="button" class="hidden btn btn-warning navbar-btn">
-								<span class="glyphicon glyphicon-text-background" aria-hidden="true"></span> {function="i18n::_('Raw text')"}
-							</button>
-						</li>
-						<li class="dropdown">
-							<select id="pasteExpiration" name="pasteExpiration" class="hidden">
-{loop="EXPIRE"}
-								<option value="{$key}"{if="$key == $EXPIREDEFAULT"} selected="selected"{/if}>{$value}</option>{/loop}
-							</select>
-							<a id="expiration" href="#" class="hidden dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{function="i18n::_('Expires')"}: <span id="pasteExpirationDisplay">{$EXPIRE[$EXPIREDEFAULT]}</span> <span class="caret"></span></a>
-							<ul class="dropdown-menu">
-{loop="EXPIRE"}
-								<li>
-									<a href="#" onclick="$('#pasteExpiration').val('{$key}');$('#pasteExpirationDisplay').text('{$value}');return false;">
-										{$value}
-									</a>
-								</li>{/loop}
-							</ul>
-						</li>
-						<li>
-							<div id="burnafterreadingoption" class="navbar-text checkbox hidden">
-								<label>
-									<input type="checkbox" id="burnafterreading" name="burnafterreading" {if="$BURNAFTERREADINGSELECTED"} checked="checked"{/if} />
-									{function="i18n::_('Burn after reading')"}
-								</label>
-							</div>
-						</li>{if="$DISCUSSION"}
-						<li>
-							<div id="opendisc" class="navbar-text checkbox hidden">
-								<label>
-									<input type="checkbox" id="opendiscussion" name="opendiscussion" {if="$OPENDISCUSSION"} checked="checked"{/if} />
-									{function="i18n::_('Open discussion')"}
-							 	</label>
-							</div>
-						</li>{/if}{if="$PASSWORD"}
-						<li>
-							<div id="password" class="navbar-form hidden">
-								<input type="password" id="passwordinput" placeholder="{function="i18n::_('Password (recommended)')"}" class="form-control" size="19"/>
-							</div>
-						</li>{/if}{if="$FILEUPLOAD"}
-						<li id="attach" class="hidden dropdown">
-							<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{function="i18n::_('Attach a file')"} <span class="caret"></span></a>
-							<ul class="dropdown-menu">
-								<li id="filewrap">
-									<div>
-										<input type="file" id="file" name="file" />
-									</div>
-								</li>
-								<li>
-									<a id="fileremovebutton"  href="#">
-										{function="i18n::_('Remove attachment')"}
-									</a>
-								</li>
-							</ul>
-						</li>{/if}
-						<li class="dropdown">
-							<select id="pasteFormatter" name="pasteFormatter" class="hidden">
-{loop="FORMATTER"}
-								<option value="{$key}"{if="$key == $FORMATTERDEFAULT"} selected="selected"{/if}>{$value}</option>{/loop}
-							</select>
-							<a id="formatter" href="#" class="hidden dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{function="i18n::_('Format')"}: <span id="pasteFormatterDisplay">{$FORMATTER[$FORMATTERDEFAULT]}</span> <span class="caret"></span></a>
-							<ul class="dropdown-menu">
-{loop="FORMATTER"}
-								<li>
-									<a href="#" onclick="$('#pasteFormatter').val('{$key}');$('#pasteFormatterDisplay').text('{$value}');return false;">
-										{$value}
-									</a>
-								</li>{/loop}
-							</ul>
-						</li>
-					</ul>
-					<ul class="nav navbar-nav pull-right">{if="strlen($LANGUAGESELECTION)"}
-						<li id="language" class="dropdown">
-							<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="glyphicon glyphicon-flag" aria-hidden="true"></span> {$LANGUAGES[$LANGUAGESELECTION][0]} <span class="caret"></span></a>
-							<ul class="dropdown-menu">
-{loop="LANGUAGES"}
-								<li>
-									<a href="#" class="reloadlink" onclick="document.cookie='lang={$key}';">
-									{$value[0]} ({$value[1]})
-								</a>
-							</li>{/loop}
-						</ul>
-					</li>{/if}
-					<li>
-						<button id="sendbutton" type="button" class="hidden btn btn-warning navbar-btn">
-							<span class="glyphicon glyphicon-upload" aria-hidden="true"></span> {function="i18n::_('Send')"}
-						</button>
-					</li>
-				</ul>
-			</div>
-		</nav>
-		<header class="container">{if="strlen($NOTICE)"}
-			<div role="alert" class="alert alert-info">
-				<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span> {$NOTICE|htmlspecialchars}
-			</div>{/if}
-			<div id="remainingtime" role="alert" class="hidden alert alert-info">
-				<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>
-			</div>{if="$FILEUPLOAD"}
-			<div id="attachment" role="alert" class="hidden alert alert-info">
-				<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span> <a>{function="i18n::_('Download attachment')"}</a> <span id="clonedfile" class="hidden">{function="i18n::_('Cloned file attached.')"}</span>
-			</div>{/if}{if="strlen($STATUS)"}
-			<div id="status" role="alert" class="alert alert-success">
-				<span class="glyphicon glyphicon-ok" aria-hidden="true"></span> {$STATUS|htmlspecialchars}
-			</div>{/if}
-			<div id="errormessage" role="alert" class="{if="!strlen($ERROR)"}hidden {/if}alert alert-danger"><span class="glyphicon glyphicon-alert" aria-hidden="true"></span> {$ERROR|htmlspecialchars}</div>
-			<noscript><div id="noscript" role="alert" class="nonworking alert alert-error"><span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span> {function="i18n::_('Javascript is required for PrivateBin to work.<br />Sorry for the inconvenience.')"}</div></noscript>
-			<div id="oldienotice" role="alert" class="hidden nonworking alert alert-danger"><span class="glyphicon glyphicon-alert" aria-hidden="true"></span> {function="i18n::_('PrivateBin requires a modern browser to work.')"}</div>
-			<div id="ienotice" role="alert" class="hidden alert alert-error"><span class="glyphicon glyphicon-question-sign" aria-hidden="true"></span> {function="i18n::_('Still using Internet Explorer? Do yourself a favor, switch to a modern browser:')"}
-				<a href="https://www.mozilla.org/firefox/">Firefox</a>,
-				<a href="https://www.opera.com/">Opera</a>,
-				<a href="https://www.google.com/chrome">Chrome</a>,
-				<a href="https://www.apple.com/safari">Safari</a>,
-				<a href="https://www.microsoft.com/edge">Edge</a>...
-			</div>
-			<div id="pasteresult" role="alert" class="hidden alert alert-success">
-				<span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
-				<div id="deletelink"></div>
-				<div id="pastelink">{if="strlen($URLSHORTENER)"}
-					<button id="shortenbutton" data-shortener="{$URLSHORTENER|htmlspecialchars}" type="button" class="btn btn-warning">
-						<span class="glyphicon glyphicon-send" aria-hidden="true"></span> {function="i18n::_('Shorten URL')"}
-					</button>
-				{/if}</div>
-			</div>
-			<ul id="preview" class="nav nav-tabs hidden">
-				<li role="presentation" class="active"><a id="messageedit" href="#">{function="i18n::_('Editor')"}</a></li>
-				<li role="presentation"><a id="messagepreview" href="#">{function="i18n::_('Preview')"}</a></li>
-			</ul>
-		</header>
-		<section class="container">
-			<article class="row">
-				<div id="image" class="col-md-12 text-center hidden"></div>
-				<div id="prettymessage" class="col-md-12 hidden">
-					<pre id="prettyprint" class="col-md-12 prettyprint linenums:1"></pre>
-				</div>
-				<div id="cleartext" class="col-md-12 hidden"></div>
-				<p class="col-md-12"><textarea id="message" name="message" cols="80" rows="25" class="form-control hidden"></textarea></p>
-			</article>
-		</section>
-		<section class="container">
-			<div id="discussion" class="hidden">
-				<h4>{function="i18n::_('Discussion')"}</h4>
-				<div id="comments"></div>
-			</div>
-		</section>
-		<footer class="container">
-			<div class="row">
-				<h4 class="col-md-5 col-xs-8">{function="i18n::_('PrivateBin')"} <small>- {function="i18n::_('Because ignorance is bliss')"}</small></h4>
-				<p class="col-md-1 col-xs-4 text-center">{$VERSION}</p>
-				<p id="aboutbox" class="col-md-6 col-xs-12">
-					{function="i18n::_('PrivateBin is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted <i>in the browser</i> using 256 bits AES. More information on the <a href="https://github.com/PrivateBin/PrivateBin/wiki">project page</a>.')"}
-				</p>
-			</div>
-		</footer>
-		<div id="cipherdata" class="hidden">{$CIPHERDATA}</div>
-	</body>
-</html>

+ 252 - 0
tpl/bootstrap-dark.php

@@ -0,0 +1,252 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<meta http-equiv="X-UA-Compatible" content="IE=edge">
+		<meta name="viewport" content="width=device-width, initial-scale=1">
+		<meta name="robots" content="noindex" />
+		<title><?php echo i18n::_('PrivateBin'); ?></title>
+		<link type="text/css" rel="stylesheet" href="css/bootstrap/bootstrap-theme-3.3.5.css" />
+		<link type="text/css" rel="stylesheet" href="css/bootstrap/darkstrap-0.9.3.css" />
+		<link type="text/css" rel="stylesheet" href="css/bootstrap/privatebin.css?<?php echo rawurlencode($VERSION); ?>" /><?php
+if ($SYNTAXHIGHLIGHTING): ?>
+		<link type="text/css" rel="stylesheet" href="css/prettify/prettify.css?<?php echo rawurlencode($VERSION); ?>" /><?php
+	if (strlen($SYNTAXHIGHLIGHTINGTHEME)): ?>
+		<link type="text/css" rel="stylesheet" href="css/prettify/<?php echo rawurlencode($SYNTAXHIGHLIGHTINGTHEME); ?>.css?<?php echo rawurlencode($VERSION); ?>" /><?php
+	endif;
+endif; ?>
+		<script type="text/javascript" src="js/jquery-1.11.3.js"></script>
+		<script type="text/javascript" src="js/sjcl-1.0.4.js"></script>
+		<script type="text/javascript" src="js/base64-<?php echo rawurlencode($BASE64JSVERSION); ?>.js"></script>
+		<script type="text/javascript" src="js/rawdeflate-0.5.js"></script>
+		<script type="text/javascript" src="js/rawinflate-0.3.js"></script>
+		<script type="text/javascript" src="js/bootstrap-3.3.5.js"></script><?php
+if ($SYNTAXHIGHLIGHTING): ?>
+		<script type="text/javascript" src="js/prettify.js?<?php echo rawurlencode($VERSION); ?>"></script><?php
+endif;
+if ($MARKDOWN): ?>
+		<script type="text/javascript" src="js/showdown-1.4.1.js"></script><?php
+endif; ?>
+		<script type="text/javascript" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>"></script>
+		<!--[if lt IE 10]>
+		<style type="text/css">body {padding-left:60px;padding-right:60px;} #ienotice {display:block;} #oldienotice {display:block;}</style>
+		<![endif]-->
+		<link rel="apple-touch-icon" href="apple-touch-icon.png?<?php echo rawurlencode($VERSION); ?>" sizes="180x180" />
+		<link rel="icon" type="image/png" href="favicon-32x32.png?<?php echo rawurlencode($VERSION); ?>" sizes="32x32" />
+		<link rel="icon" type="image/png" href="favicon-16x16.png?<?php echo rawurlencode($VERSION); ?>" sizes="16x16" />
+		<link rel="manifest" href="manifest.json?<?php echo rawurlencode($VERSION); ?>" />
+		<link rel="mask-icon" href="safari-pinned-tab.svg?<?php echo rawurlencode($VERSION); ?>" color="#ffcc00" />
+		<link rel="shortcut icon" href="favicon.ico">
+		<meta name="msapplication-config" content="browserconfig.xml">
+		<meta name="theme-color" content="#ffe57e" />
+	</head>
+	<body role="document">
+		<nav class="navbar navbar-inverse navbar-static-top">
+			<div class="navbar-header">
+				<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
+					<span class="sr-only"><?php echo i18n::_('Toggle navigation'); ?></span>
+					<span class="icon-bar"></span>
+					<span class="icon-bar"></span>
+					<span class="icon-bar"></span>
+				</button>
+				<a class="reloadlink navbar-brand" href="/">
+					<img alt="<?php echo i18n::_('PrivateBin'); ?>" src="favicon-32x32.png" width="20" />
+				</a>
+			</div>
+			<div id="navbar" class="navbar-collapse collapse">
+				<ul class="nav navbar-nav">
+					<li>
+						<button id="newbutton" type="button" class="reloadlink hidden btn btn-warning navbar-btn">
+							<span class="glyphicon glyphicon-file" aria-hidden="true"></span> <?php echo i18n::_('New'); ?>
+						</button><?php
+if ($EXPIRECLONE): ?>
+						<button id="clonebutton" type="button" class="hidden btn btn-warning navbar-btn">
+							<span class="glyphicon glyphicon-duplicate" aria-hidden="true"></span> <?php echo i18n::_('Clone'); ?>
+						</button><?php
+endif; ?>
+						<button id="rawtextbutton" type="button" class="hidden btn btn-warning navbar-btn">
+							<span class="glyphicon glyphicon-text-background" aria-hidden="true"></span> <?php echo i18n::_('Raw text'); ?>
+						</button>
+					</li>
+					<li class="dropdown">
+						<select id="pasteExpiration" name="pasteExpiration" class="hidden"><?php
+foreach ($EXPIRE as $key => $value): ?>
+							<option value="<?php echo $key; ?>"<?php
+	if ($key == $EXPIREDEFAULT): ?> selected="selected"<?php
+	endif; ?>><?php echo $value; ?></option><?php
+endforeach; ?>
+						</select>
+						<a id="expiration" href="#" class="hidden dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><?php echo i18n::_('Expires'); ?>: <span id="pasteExpirationDisplay"><?php echo $EXPIRE[$EXPIREDEFAULT]; ?></span> <span class="caret"></span></a>
+						<ul class="dropdown-menu"><?php
+foreach ($EXPIRE as $key => $value): ?>
+							<li>
+								<a href="#" onclick="$('#pasteExpiration').val('<?php echo $key; ?>');$('#pasteExpirationDisplay').text('<?php echo $value; ?>');return false;">
+									<?php echo $value; ?>
+								</a>
+							</li><?php
+endforeach; ?>
+						</ul>
+					</li>
+					<li>
+						<div id="burnafterreadingoption" class="navbar-text checkbox hidden">
+							<label>
+								<input type="checkbox" id="burnafterreading" name="burnafterreading" <?php
+if ($BURNAFTERREADINGSELECTED): ?> checked="checked"<?php
+endif; ?> />
+								<?php echo i18n::_('Burn after reading'); ?>
+							</label>
+						</div>
+					</li><?php
+if ($DISCUSSION): ?>
+					<li>
+						<div id="opendisc" class="navbar-text checkbox hidden">
+							<label>
+								<input type="checkbox" id="opendiscussion" name="opendiscussion" <?php
+	if ($OPENDISCUSSION): ?> checked="checked"<?php
+	endif; ?> />
+								<?php echo i18n::_('Open discussion'); ?>
+						 	</label>
+						</div>
+					</li><?php
+endif;
+if ($PASSWORD): ?>
+					<li>
+						<div id="password" class="navbar-form hidden">
+							<input type="password" id="passwordinput" placeholder="<?php echo i18n::_('Password (recommended)'); ?>" class="form-control" size="19" />
+						</div>
+					</li><?php
+endif;
+if ($FILEUPLOAD): ?>
+					<li id="attach" class="hidden dropdown">
+						<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><?php echo i18n::_('Attach a file'); ?> <span class="caret"></span></a>
+						<ul class="dropdown-menu">
+							<li id="filewrap">
+								<div>
+									<input type="file" id="file" name="file" />
+								</div>
+							</li>
+							<li>
+								<a id="fileremovebutton"  href="#">
+									<?php echo i18n::_('Remove attachment'); ?>
+								</a>
+							</li>
+						</ul>
+					</li><?php
+endif; ?>
+					<li class="dropdown">
+						<select id="pasteFormatter" name="pasteFormatter" class="hidden"><?php
+foreach ($FORMATTER as $key => $value): ?>
+							<option value="<?php echo $key; ?>"<?php
+	if ($key == $FORMATTERDEFAULT): ?> selected="selected"<?php
+	endif; ?>><?php echo $value; ?></option><?php
+endforeach; ?>
+						</select>
+						<a id="formatter" href="#" class="hidden dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><?php echo i18n::_('Format'); ?>: <span id="pasteFormatterDisplay"><?php echo $FORMATTER[$FORMATTERDEFAULT]; ?></span> <span class="caret"></span></a>
+						<ul class="dropdown-menu"><?php
+foreach ($FORMATTER as $key => $value): ?>
+							<li>
+								<a href="#" onclick="$('#pasteFormatter').val('<?php echo $key; ?>');$('#pasteFormatterDisplay').text('<?php echo $value; ?>');return false;">
+									<?php echo $value; ?>
+								</a>
+							</li><?php
+endforeach; ?>
+						</ul>
+					</li>
+				</ul>
+				<ul class="nav navbar-nav pull-right"><?php
+if (strlen($LANGUAGESELECTION)): ?>
+					<li id="language" class="dropdown">
+						<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="glyphicon glyphicon-flag" aria-hidden="true"></span> <?php echo $LANGUAGES[$LANGUAGESELECTION][0]; ?> <span class="caret"></span></a>
+						<ul class="dropdown-menu"><?php
+	foreach ($LANGUAGES as $key => $value): ?>
+							<li>
+								<a href="#" class="reloadlink" onclick="document.cookie='lang=<?php echo $key; ?>';">
+									<?php echo $value[0]; ?> (<?php echo $value[1]; ?>)
+								</a>
+							</li><?php
+	endforeach; ?>
+						</ul>
+					</li><?php
+endif; ?>
+					<li>
+						<button id="sendbutton" type="button" class="hidden btn btn-warning navbar-btn">
+							<span class="glyphicon glyphicon-upload" aria-hidden="true"></span> <?php echo i18n::_('Send'); ?>
+						</button>
+					</li>
+				</ul>
+			</div>
+		</nav>
+		<header class="container"><?php
+if (strlen($NOTICE)): ?>
+			<div role="alert" class="alert alert-info">
+				<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span> <?php echo htmlspecialchars($NOTICE); ?>
+			</div><?php
+endif; ?>
+			<div id="remainingtime" role="alert" class="hidden alert alert-info">
+				<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>
+			</div><?php
+if ($FILEUPLOAD): ?>
+			<div id="attachment" role="alert" class="hidden alert alert-info">
+				<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span> <a><?php echo i18n::_('Download attachment'); ?></a> <span id="clonedfile" class="hidden"><?php echo i18n::_('Cloned file attached.'); ?></span>
+			</div><?php
+endif;
+if (strlen($STATUS)): ?>
+			<div id="status" role="alert" class="alert alert-success">
+				<span class="glyphicon glyphicon-ok" aria-hidden="true"></span> <?php echo htmlspecialchars($STATUS); ?>
+			</div><?php
+endif; ?>
+			<div id="errormessage" role="alert" class="<?php
+if (!strlen($ERROR)): ?>hidden <?php
+endif; ?>alert alert-danger"><span class="glyphicon glyphicon-alert" aria-hidden="true"></span> <?php echo htmlspecialchars($ERROR); ?></div>
+			<noscript><div id="noscript" role="alert" class="nonworking alert alert-error"><span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span> <?php echo i18n::_('Javascript is required for PrivateBin to work.<br />Sorry for the inconvenience.'); ?></div></noscript>
+			<div id="oldienotice" role="alert" class="hidden nonworking alert alert-danger"><span class="glyphicon glyphicon-alert" aria-hidden="true"></span> <?php echo i18n::_('PrivateBin requires a modern browser to work.'); ?></div>
+			<div id="ienotice" role="alert" class="hidden alert alert-error"><span class="glyphicon glyphicon-question-sign" aria-hidden="true"></span> <?php echo i18n::_('Still using Internet Explorer? Do yourself a favor, switch to a modern browser:'); ?>
+				<a href="https://www.mozilla.org/firefox/">Firefox</a>,
+				<a href="https://www.opera.com/">Opera</a>,
+				<a href="https://www.google.com/chrome">Chrome</a>,
+				<a href="https://www.apple.com/safari">Safari</a>...
+			</div>
+			<div id="pasteresult" role="alert" class="hidden alert alert-success">
+				<span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
+				<div id="deletelink"></div>
+				<div id="pastelink"><?php
+if (strlen($URLSHORTENER)): ?>
+					<button id="shortenbutton" data-shortener="<?php echo htmlspecialchars($URLSHORTENER); ?>" type="button" class="btn btn-warning">
+						<span class="glyphicon glyphicon-send" aria-hidden="true"></span> <?php echo i18n::_('Shorten URL'); ?>
+					</button><?php
+endif; ?>
+				</div>
+			</div>
+			<ul id="preview" class="nav nav-tabs hidden">
+				<li role="presentation" class="active"><a id="messageedit" href="#"><?php echo i18n::_('Editor'); ?></a></li>
+				<li role="presentation"><a id="messagepreview" href="#"><?php echo i18n::_('Preview'); ?></a></li>
+			</ul>
+		</header>
+		<section class="container">
+			<article class="row">
+				<div id="image" class="col-md-12 text-center hidden"></div>
+				<div id="prettymessage" class="col-md-12 hidden">
+					<pre id="prettyprint" class="col-md-12 prettyprint linenums:1"></pre>
+				</div>
+				<div id="cleartext" class="col-md-12 hidden"></div>
+				<p class="col-md-12"><textarea id="message" name="message" cols="80" rows="25" class="form-control hidden"></textarea></p>
+			</article>
+		</section>
+		<section class="container">
+			<div id="discussion" class="hidden">
+				<h4><?php echo i18n::_('Discussion'); ?></h4>
+				<div id="comments"></div>
+			</div>
+		</section>
+		<footer class="container">
+			<div class="row">
+				<h4 class="col-md-5 col-xs-8"><?php echo i18n::_('PrivateBin'); ?> <small>- <?php echo i18n::_('Because ignorance is bliss'); ?></small></h4>
+				<p class="col-md-1 col-xs-4 text-center"><?php echo $VERSION; ?></p>
+				<p id="aboutbox" class="col-md-6 col-xs-12">
+					<?php echo i18n::_('PrivateBin is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted <i>in the browser</i> using 256 bits AES. More information on the <a href="https://github.com/PrivateBin/PrivateBin/wiki">project page</a>.'); ?>
+				</p>
+			</div>
+		</footer>
+		<div id="cipherdata" class="hidden"><?php echo htmlspecialchars($CIPHERDATA, ENT_NOQUOTES); ?></div>
+	</body>
+</html>

+ 0 - 212
tpl/bootstrap-page.html

@@ -1,212 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
-		<meta charset="utf-8" />
-		<meta http-equiv="X-UA-Compatible" content="IE=edge">
-		<meta name="viewport" content="width=device-width, initial-scale=1">
-		<meta name="robots" content="noindex" />
-		<title>{function="i18n::_('PrivateBin')"}</title>
-		<link type="text/css" rel="stylesheet" href="css/bootstrap/bootstrap-3.3.5.css" />
-		<link type="text/css" rel="stylesheet" href="css/bootstrap/bootstrap-theme-3.3.5.css" />
-		<link type="text/css" rel="stylesheet" href="css/bootstrap/privatebin.css?{$VERSION|rawurlencode}" />{if="$SYNTAXHIGHLIGHTING"}
-		<link type="text/css" rel="stylesheet" href="css/prettify/prettify.css?{$VERSION|rawurlencode}" />{if="strlen($SYNTAXHIGHLIGHTINGTHEME)"}
-		<link type="text/css" rel="stylesheet" href="css/prettify/{$SYNTAXHIGHLIGHTINGTHEME}.css?{$VERSION|rawurlencode}" />{/if}{/if}
-		<script type="text/javascript" src="js/jquery-1.11.3.js"></script>
-		<script type="text/javascript" src="js/sjcl-1.0.4.js"></script>
-		<script type="text/javascript" src="js/base64-{$BASE64JSVERSION}.js"></script>
-		<script type="text/javascript" src="js/rawdeflate-0.5.js"></script>
-		<script type="text/javascript" src="js/rawinflate-0.3.js"></script>
-		<script type="text/javascript" src="js/bootstrap-3.3.5.js"></script>{if="$SYNTAXHIGHLIGHTING"}
-		<script type="text/javascript" src="js/prettify.js?{$VERSION|rawurlencode}"></script>{/if}{if="$MARKDOWN"}
-		<script type="text/javascript" src="js/showdown-1.4.1.js"></script>{/if}
-		<script type="text/javascript" src="js/privatebin.js?{$VERSION|rawurlencode}"></script>
-		<!--[if lt IE 10]>
-		<style type="text/css">#ienotice {display:block !important;} #oldienotice {display:block !important;}</style>
-		<![endif]-->
-		<link rel="apple-touch-icon" href="apple-touch-icon.png?{$VERSION|rawurlencode}" sizes="180x180" />
-		<link rel="icon" type="image/png" href="favicon-32x32.png?{$VERSION|rawurlencode}" sizes="32x32" />
-		<link rel="icon" type="image/png" href="favicon-16x16.png?{$VERSION|rawurlencode}" sizes="16x16" />
-		<link rel="manifest" href="manifest.json?{$VERSION|rawurlencode}" />
-		<link rel="mask-icon" href="safari-pinned-tab.svg?{$VERSION|rawurlencode}" color="#ffcc00" />
-		<link rel="shortcut icon" href="favicon.ico">
-		<meta name="msapplication-config" content="browserconfig.xml">
-		<meta name="theme-color" content="#ffe57e" />
-	</head>
-	<body role="document">
-		<nav class="navbar navbar-default navbar-static-top">
-				<div class="navbar-header">
-					<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
-						<span class="sr-only">{function="i18n::_('Toggle navigation')"}</span>
-						<span class="icon-bar"></span>
-						<span class="icon-bar"></span>
-						<span class="icon-bar"></span>
-					</button>
-					<a class="reloadlink navbar-brand" href="/">
-						<img alt="{function="i18n::_('PrivateBin')"}" src="favicon-32x32.png" width="20" />
-					</a>
-				</div>
-				<div id="navbar" class="navbar-collapse collapse">
-					<ul class="nav navbar-nav">
-						<li>
-							<button id="sendbutton" type="button" class="hidden btn btn-default navbar-btn">
-								<span class="glyphicon glyphicon-upload" aria-hidden="true"></span> {function="i18n::_('Send')"}
-							</button>{if="$EXPIRECLONE"}
-							<button id="clonebutton" type="button" class="hidden btn btn-default navbar-btn">
-								<span class="glyphicon glyphicon-duplicate" aria-hidden="true"></span> {function="i18n::_('Clone')"}
-							</button>{/if}
-							<button id="rawtextbutton" type="button" class="hidden btn btn-default navbar-btn">
-								<span class="glyphicon glyphicon-text-background" aria-hidden="true"></span> {function="i18n::_('Raw text')"}
-							</button>
-						</li>
-						<li class="dropdown">
-							<select id="pasteExpiration" name="pasteExpiration" class="hidden">
-{loop="EXPIRE"}
-								<option value="{$key}"{if="$key == $EXPIREDEFAULT"} selected="selected"{/if}>{$value}</option>{/loop}
-							</select>
-							<a id="expiration" href="#" class="hidden dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{function="i18n::_('Expires')"}: <span id="pasteExpirationDisplay">{$EXPIRE[$EXPIREDEFAULT]}</span> <span class="caret"></span></a>
-							<ul class="dropdown-menu">
-{loop="EXPIRE"}
-								<li>
-									<a href="#" onclick="$('#pasteExpiration').val('{$key}');$('#pasteExpirationDisplay').text('{$value}');return false;">
-										{$value}
-									</a>
-								</li>{/loop}
-							</ul>
-						</li>
-						<li>
-							<div id="burnafterreadingoption" class="navbar-text checkbox hidden">
-								<label>
-									<input type="checkbox" id="burnafterreading" name="burnafterreading" {if="$BURNAFTERREADINGSELECTED"} checked="checked"{/if} />
-									{function="i18n::_('Burn after reading')"}
-								</label>
-							</div>
-						</li>{if="$DISCUSSION"}
-						<li>
-							<div id="opendisc" class="navbar-text checkbox hidden">
-								<label>
-									<input type="checkbox" id="opendiscussion" name="opendiscussion" {if="$OPENDISCUSSION"} checked="checked"{/if} />
-									{function="i18n::_('Open discussion')"}
-							 	</label>
-							</div>
-						</li>{/if}{if="$PASSWORD"}
-						<li>
-							<div id="password" class="navbar-form hidden">
-								<input type="password" id="passwordinput" placeholder="{function="i18n::_('Password (recommended)')"}" class="form-control" size="19"/>
-							</div>
-						</li>{/if}{if="$FILEUPLOAD"}
-						<li id="attach" class="hidden dropdown">
-							<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{function="i18n::_('Attach a file')"} <span class="caret"></span></a>
-							<ul class="dropdown-menu">
-								<li id="filewrap">
-									<div>
-										<input type="file" id="file" name="file" />
-									</div>
-								</li>
-								<li>
-									<a id="fileremovebutton"  href="#">
-										{function="i18n::_('Remove attachment')"}
-									</a>
-								</li>
-							</ul>
-						</li>{/if}
-						<li class="dropdown">
-							<select id="pasteFormatter" name="pasteFormatter" class="hidden">
-{loop="FORMATTER"}
-								<option value="{$key}"{if="$key == $FORMATTERDEFAULT"} selected="selected"{/if}>{$value}</option>{/loop}
-							</select>
-							<a id="formatter" href="#" class="hidden dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{function="i18n::_('Format')"}: <span id="pasteFormatterDisplay">{$FORMATTER[$FORMATTERDEFAULT]}</span> <span class="caret"></span></a>
-							<ul class="dropdown-menu">
-{loop="FORMATTER"}
-								<li>
-									<a href="#" onclick="$('#pasteFormatter').val('{$key}');$('#pasteFormatterDisplay').text('{$value}');return false;">
-										{$value}
-									</a>
-								</li>{/loop}
-							</ul>
-						</li>
-					</ul>
-					<ul class="nav navbar-nav pull-right">{if="strlen($LANGUAGESELECTION)"}
-						<li id="language" class="dropdown">
-							<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="glyphicon glyphicon-flag" aria-hidden="true"></span> {$LANGUAGES[$LANGUAGESELECTION][0]} <span class="caret"></span></a>
-							<ul class="dropdown-menu">
-{loop="LANGUAGES"}
-								<li>
-									<a href="#" class="reloadlink" onclick="document.cookie='lang={$key}';">
-									{$value[0]} ({$value[1]})
-								</a>
-							</li>{/loop}
-						</ul>
-					</li>{/if}
-					<li>
-						<button id="newbutton" type="button" class="reloadlink hidden btn btn-default navbar-btn">
-							<span class="glyphicon glyphicon-file" aria-hidden="true"></span> {function="i18n::_('New')"}
-						</button>
-					</li>
-				</ul>
-			</div>
-		</nav>
-		<header class="container">{if="strlen($NOTICE)"}
-			<div role="alert" class="alert alert-info">
-				<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span> {$NOTICE|htmlspecialchars}
-			</div>{/if}
-			<div id="remainingtime" role="alert" class="hidden alert alert-info">
-				<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>
-			</div>{if="$FILEUPLOAD"}
-			<div id="attachment" role="alert" class="hidden alert alert-info">
-				<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span> <a>{function="i18n::_('Download attachment')"}</a> <span id="clonedfile" class="hidden">{function="i18n::_('Cloned file attached.')"}</span>
-			</div>{/if}{if="strlen($STATUS)"}
-			<div id="status" role="alert" class="alert alert-success">
-				<span class="glyphicon glyphicon-ok" aria-hidden="true"></span> {$STATUS|htmlspecialchars}
-			</div>{/if}
-			<div id="errormessage" role="alert" class="{if="!strlen($ERROR)"}hidden {/if}alert alert-danger"><span class="glyphicon glyphicon-alert" aria-hidden="true"></span> {$ERROR|htmlspecialchars}</div>
-			<noscript><div id="noscript" role="alert" class="nonworking alert alert-warning"><span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span> {function="i18n::_('Javascript is required for PrivateBin to work.<br />Sorry for the inconvenience.')"}</div></noscript>
-			<div id="oldienotice" role="alert" class="hidden nonworking alert alert-danger"><span class="glyphicon glyphicon-alert" aria-hidden="true"></span> {function="i18n::_('PrivateBin requires a modern browser to work.')"}</div>
-			<div id="ienotice" role="alert" class="hidden alert alert-warning"><span class="glyphicon glyphicon-question-sign" aria-hidden="true"></span> {function="i18n::_('Still using Internet Explorer? Do yourself a favor, switch to a modern browser:')"}
-				<a href="https://www.mozilla.org/firefox/">Firefox</a>,
-				<a href="https://www.opera.com/">Opera</a>,
-				<a href="https://www.google.com/chrome">Chrome</a>,
-				<a href="https://www.apple.com/safari">Safari</a>,
-				<a href="https://www.microsoft.com/edge">Edge</a>...
-			</div>
-			<div id="pasteresult" role="alert" class="hidden alert alert-success">
-				<span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
-				<div id="deletelink"></div>
-				<div id="pastelink">{if="strlen($URLSHORTENER)"}
-					<button id="shortenbutton" data-shortener="{$URLSHORTENER|htmlspecialchars}" type="button" class="btn btn-primary">
-						<span class="glyphicon glyphicon-send" aria-hidden="true"></span> {function="i18n::_('Shorten URL')"}
-					</button>
-				{/if}</div>
-			</div>
-			<ul id="preview" class="nav nav-tabs hidden">
-				<li role="presentation" class="active"><a id="messageedit" href="#">{function="i18n::_('Editor')"}</a></li>
-				<li role="presentation"><a id="messagepreview" href="#">{function="i18n::_('Preview')"}</a></li>
-			</ul>
-		</header>
-		<section class="container">
-			<article class="row">
-				<div id="image" class="col-md-12 text-center hidden"></div>
-				<div id="prettymessage" class="col-md-12 hidden">
-					<pre id="prettyprint" class="col-md-12 prettyprint linenums:1"></pre>
-				</div>
-				<div id="cleartext" class="col-md-12 hidden"></div>
-				<p class="col-md-12"><textarea id="message" name="message" cols="80" rows="25" class="form-control hidden"></textarea></p>
-			</article>
-		</section>
-		<section class="container">
-			<div id="discussion" class="hidden">
-				<h4>{function="i18n::_('Discussion')"}</h4>
-				<div id="comments"></div>
-			</div>
-		</section>
-		<footer class="container">
-			<div class="row">
-				<h4 class="col-md-5 col-xs-8">{function="i18n::_('PrivateBin')"} <small>- {function="i18n::_('Because ignorance is bliss')"}</small></h4>
-				<p class="col-md-1 col-xs-4 text-center">{$VERSION}</p>
-				<p id="aboutbox" class="col-md-6 col-xs-12">
-					{function="i18n::_('PrivateBin is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted <i>in the browser</i> using 256 bits AES. More information on the <a href="https://github.com/PrivateBin/PrivateBin/wiki">project page</a>.')"}
-				</p>
-			</div>
-		</footer>
-		<div id="cipherdata" class="hidden">{$CIPHERDATA}</div>
-	</body>
-</html>

+ 252 - 0
tpl/bootstrap-page.php

@@ -0,0 +1,252 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<meta http-equiv="X-UA-Compatible" content="IE=edge">
+		<meta name="viewport" content="width=device-width, initial-scale=1">
+		<meta name="robots" content="noindex" />
+		<title><?php echo i18n::_('PrivateBin'); ?></title>
+		<link type="text/css" rel="stylesheet" href="css/bootstrap/bootstrap-3.3.5.css" />
+		<link type="text/css" rel="stylesheet" href="css/bootstrap/bootstrap-theme-3.3.5.css" />
+		<link type="text/css" rel="stylesheet" href="css/bootstrap/privatebin.css?<?php echo rawurlencode($VERSION); ?>" /><?php
+if ($SYNTAXHIGHLIGHTING): ?>
+		<link type="text/css" rel="stylesheet" href="css/prettify/prettify.css?<?php echo rawurlencode($VERSION); ?>" /><?php
+	if (strlen($SYNTAXHIGHLIGHTINGTHEME)): ?>
+		<link type="text/css" rel="stylesheet" href="css/prettify/<?php echo rawurlencode($SYNTAXHIGHLIGHTINGTHEME); ?>.css?<?php echo rawurlencode($VERSION); ?>" /><?php
+	endif;
+endif; ?>
+		<script type="text/javascript" src="js/jquery-1.11.3.js"></script>
+		<script type="text/javascript" src="js/sjcl-1.0.4.js"></script>
+		<script type="text/javascript" src="js/base64-<?php echo rawurlencode($BASE64JSVERSION); ?>.js"></script>
+		<script type="text/javascript" src="js/rawdeflate-0.5.js"></script>
+		<script type="text/javascript" src="js/rawinflate-0.3.js"></script>
+		<script type="text/javascript" src="js/bootstrap-3.3.5.js"></script><?php
+if ($SYNTAXHIGHLIGHTING): ?>
+		<script type="text/javascript" src="js/prettify.js?<?php echo rawurlencode($VERSION); ?>"></script><?php
+endif;
+if ($MARKDOWN): ?>
+		<script type="text/javascript" src="js/showdown-1.4.1.js"></script><?php
+endif; ?>
+		<script type="text/javascript" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>"></script>
+		<!--[if lt IE 10]>
+		<style type="text/css">body {padding-left:60px;padding-right:60px;} #ienotice {display:block;} #oldienotice {display:block;}</style>
+		<![endif]-->
+		<link rel="apple-touch-icon" href="apple-touch-icon.png?<?php echo rawurlencode($VERSION); ?>" sizes="180x180" />
+		<link rel="icon" type="image/png" href="favicon-32x32.png?<?php echo rawurlencode($VERSION); ?>" sizes="32x32" />
+		<link rel="icon" type="image/png" href="favicon-16x16.png?<?php echo rawurlencode($VERSION); ?>" sizes="16x16" />
+		<link rel="manifest" href="manifest.json?<?php echo rawurlencode($VERSION); ?>" />
+		<link rel="mask-icon" href="safari-pinned-tab.svg?<?php echo rawurlencode($VERSION); ?>" color="#ffcc00" />
+		<link rel="shortcut icon" href="favicon.ico">
+		<meta name="msapplication-config" content="browserconfig.xml">
+		<meta name="theme-color" content="#ffe57e" />
+	</head>
+	<body role="document">
+		<nav class="navbar navbar-default navbar-static-top">
+			<div class="navbar-header">
+				<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
+					<span class="sr-only"><?php echo i18n::_('Toggle navigation'); ?></span>
+					<span class="icon-bar"></span>
+					<span class="icon-bar"></span>
+					<span class="icon-bar"></span>
+				</button>
+				<a class="reloadlink navbar-brand" href="/">
+					<img alt="<?php echo i18n::_('PrivateBin'); ?>" src="favicon-32x32.png" width="20" />
+				</a>
+			</div>
+			<div id="navbar" class="navbar-collapse collapse">
+				<ul class="nav navbar-nav">
+					<li>
+						<button id="sendbutton" type="button" class="hidden btn btn-primary navbar-btn">
+							<span class="glyphicon glyphicon-upload" aria-hidden="true"></span> <?php echo i18n::_('Send'); ?>
+						</button><?php
+if ($EXPIRECLONE): ?>
+						<button id="clonebutton" type="button" class="hidden btn btn-default navbar-btn">
+							<span class="glyphicon glyphicon-duplicate" aria-hidden="true"></span> <?php echo i18n::_('Clone'); ?>
+						</button><?php
+endif; ?>
+						<button id="rawtextbutton" type="button" class="hidden btn btn-default navbar-btn">
+							<span class="glyphicon glyphicon-text-background" aria-hidden="true"></span> <?php echo i18n::_('Raw text'); ?>
+						</button>
+					</li>
+					<li class="dropdown">
+						<select id="pasteExpiration" name="pasteExpiration" class="hidden"><?php
+foreach ($EXPIRE as $key => $value): ?>
+							<option value="<?php echo $key; ?>"<?php
+	if ($key == $EXPIREDEFAULT): ?> selected="selected"<?php
+	endif; ?>><?php echo $value; ?></option><?php
+endforeach; ?>
+						</select>
+						<a id="expiration" href="#" class="hidden dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><?php echo i18n::_('Expires'); ?>: <span id="pasteExpirationDisplay"><?php echo $EXPIRE[$EXPIREDEFAULT]; ?></span> <span class="caret"></span></a>
+						<ul class="dropdown-menu"><?php
+foreach ($EXPIRE as $key => $value): ?>
+							<li>
+								<a href="#" onclick="$('#pasteExpiration').val('<?php echo $key; ?>');$('#pasteExpirationDisplay').text('<?php echo $value; ?>');return false;">
+									<?php echo $value; ?>
+								</a>
+							</li><?php
+endforeach; ?>
+						</ul>
+					</li>
+					<li>
+						<div id="burnafterreadingoption" class="navbar-text checkbox hidden">
+							<label>
+								<input type="checkbox" id="burnafterreading" name="burnafterreading" <?php
+if ($BURNAFTERREADINGSELECTED): ?> checked="checked"<?php
+endif; ?> />
+								<?php echo i18n::_('Burn after reading'); ?>
+							</label>
+						</div>
+					</li><?php
+if ($DISCUSSION): ?>
+					<li>
+						<div id="opendisc" class="navbar-text checkbox hidden">
+							<label>
+								<input type="checkbox" id="opendiscussion" name="opendiscussion" <?php
+	if ($OPENDISCUSSION): ?> checked="checked"<?php
+	endif; ?> />
+								<?php echo i18n::_('Open discussion'); ?>
+						 	</label>
+						</div>
+					</li><?php
+endif;
+if ($PASSWORD): ?>
+					<li>
+						<div id="password" class="navbar-form hidden">
+							<input type="password" id="passwordinput" placeholder="<?php echo i18n::_('Password (recommended)'); ?>" class="form-control" size="19" />
+						</div>
+					</li><?php
+endif;
+if ($FILEUPLOAD): ?>
+					<li id="attach" class="hidden dropdown">
+						<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><?php echo i18n::_('Attach a file'); ?> <span class="caret"></span></a>
+						<ul class="dropdown-menu">
+							<li id="filewrap">
+								<div>
+									<input type="file" id="file" name="file" />
+								</div>
+							</li>
+							<li>
+								<a id="fileremovebutton"  href="#">
+									<?php echo i18n::_('Remove attachment'); ?>
+								</a>
+							</li>
+						</ul>
+					</li><?php
+endif; ?>
+					<li class="dropdown">
+						<select id="pasteFormatter" name="pasteFormatter" class="hidden"><?php
+foreach ($FORMATTER as $key => $value): ?>
+							<option value="<?php echo $key; ?>"<?php
+	if ($key == $FORMATTERDEFAULT): ?> selected="selected"<?php
+	endif; ?>><?php echo $value; ?></option><?php
+endforeach; ?>
+						</select>
+						<a id="formatter" href="#" class="hidden dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><?php echo i18n::_('Format'); ?>: <span id="pasteFormatterDisplay"><?php echo $FORMATTER[$FORMATTERDEFAULT]; ?></span> <span class="caret"></span></a>
+						<ul class="dropdown-menu"><?php
+foreach ($FORMATTER as $key => $value): ?>
+							<li>
+								<a href="#" onclick="$('#pasteFormatter').val('<?php echo $key; ?>');$('#pasteFormatterDisplay').text('<?php echo $value; ?>');return false;">
+									<?php echo $value; ?>
+								</a>
+							</li><?php
+endforeach; ?>
+						</ul>
+					</li>
+				</ul>
+				<ul class="nav navbar-nav pull-right"><?php
+if (strlen($LANGUAGESELECTION)): ?>
+					<li id="language" class="dropdown">
+						<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="glyphicon glyphicon-flag" aria-hidden="true"></span> <?php echo $LANGUAGES[$LANGUAGESELECTION][0]; ?> <span class="caret"></span></a>
+						<ul class="dropdown-menu"><?php
+	foreach ($LANGUAGES as $key => $value): ?>
+							<li>
+								<a href="#" class="reloadlink" onclick="document.cookie='lang=<?php echo $key; ?>';">
+									<?php echo $value[0]; ?> (<?php echo $value[1]; ?>)
+								</a>
+							</li><?php
+	endforeach; ?>
+						</ul>
+					</li><?php
+endif; ?>
+					<li>
+						<button id="newbutton" type="button" class="reloadlink hidden btn btn-default navbar-btn">
+							<span class="glyphicon glyphicon-file" aria-hidden="true"></span> <?php echo i18n::_('New'); ?>
+						</button>
+					</li>
+				</ul>
+			</div>
+		</nav>
+		<header class="container"><?php
+if (strlen($NOTICE)): ?>
+			<div role="alert" class="alert alert-info">
+				<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span> <?php echo htmlspecialchars($NOTICE); ?>
+			</div><?php
+endif; ?>
+			<div id="remainingtime" role="alert" class="hidden alert alert-info">
+				<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>
+			</div><?php
+if ($FILEUPLOAD): ?>
+			<div id="attachment" role="alert" class="hidden alert alert-info">
+				<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span> <a><?php echo i18n::_('Download attachment'); ?></a> <span id="clonedfile" class="hidden"><?php echo i18n::_('Cloned file attached.'); ?></span>
+			</div><?php
+endif;
+if (strlen($STATUS)): ?>
+			<div id="status" role="alert" class="alert alert-success">
+				<span class="glyphicon glyphicon-ok" aria-hidden="true"></span> <?php echo htmlspecialchars($STATUS); ?>
+			</div><?php
+endif; ?>
+			<div id="errormessage" role="alert" class="<?php
+if (!strlen($ERROR)): ?>hidden <?php
+endif; ?>alert alert-danger"><span class="glyphicon glyphicon-alert" aria-hidden="true"></span> <?php echo htmlspecialchars($ERROR); ?></div>
+			<noscript><div id="noscript" role="alert" class="nonworking alert alert-warning"><span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span> <?php echo i18n::_('Javascript is required for PrivateBin to work.<br />Sorry for the inconvenience.'); ?></div></noscript>
+			<div id="oldienotice" role="alert" class="hidden nonworking alert alert-danger"><span class="glyphicon glyphicon-alert" aria-hidden="true"></span> <?php echo i18n::_('PrivateBin requires a modern browser to work.'); ?></div>
+			<div id="ienotice" role="alert" class="hidden alert alert-warning"><span class="glyphicon glyphicon-question-sign" aria-hidden="true"></span> <?php echo i18n::_('Still using Internet Explorer? Do yourself a favor, switch to a modern browser:'); ?>
+				<a href="https://www.mozilla.org/firefox/">Firefox</a>,
+				<a href="https://www.opera.com/">Opera</a>,
+				<a href="https://www.google.com/chrome">Chrome</a>,
+				<a href="https://www.apple.com/safari">Safari</a>...
+			</div>
+			<div id="pasteresult" role="alert" class="hidden alert alert-success">
+				<span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
+				<div id="deletelink"></div>
+				<div id="pastelink"><?php
+if (strlen($URLSHORTENER)): ?>
+					<button id="shortenbutton" data-shortener="<?php echo htmlspecialchars($URLSHORTENER); ?>" type="button" class="btn btn-primary">
+						<span class="glyphicon glyphicon-send" aria-hidden="true"></span> <?php echo i18n::_('Shorten URL'); ?>
+					</button><?php
+endif; ?>
+				</div>
+			</div>
+			<ul id="preview" class="nav nav-tabs hidden">
+				<li role="presentation" class="active"><a id="messageedit" href="#"><?php echo i18n::_('Editor'); ?></a></li>
+				<li role="presentation"><a id="messagepreview" href="#"><?php echo i18n::_('Preview'); ?></a></li>
+			</ul>
+		</header>
+		<section class="container">
+			<article class="row">
+				<div id="image" class="col-md-12 text-center hidden"></div>
+				<div id="prettymessage" class="col-md-12 hidden">
+					<pre id="prettyprint" class="col-md-12 prettyprint linenums:1"></pre>
+				</div>
+				<div id="cleartext" class="col-md-12 hidden"></div>
+				<p class="col-md-12"><textarea id="message" name="message" cols="80" rows="25" class="form-control hidden"></textarea></p>
+			</article>
+		</section>
+		<section class="container">
+			<div id="discussion" class="hidden">
+				<h4><?php echo i18n::_('Discussion'); ?></h4>
+				<div id="comments"></div>
+			</div>
+		</section>
+		<footer class="container">
+			<div class="row">
+				<h4 class="col-md-5 col-xs-8"><?php echo i18n::_('PrivateBin'); ?> <small>- <?php echo i18n::_('Because ignorance is bliss'); ?></small></h4>
+				<p class="col-md-1 col-xs-4 text-center"><?php echo $VERSION; ?></p>
+				<p id="aboutbox" class="col-md-6 col-xs-12">
+					<?php echo i18n::_('PrivateBin is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted <i>in the browser</i> using 256 bits AES. More information on the <a href="https://github.com/PrivateBin/PrivateBin/wiki">project page</a>.'); ?>
+				</p>
+			</div>
+		</footer>
+		<div id="cipherdata" class="hidden"><?php echo htmlspecialchars($CIPHERDATA, ENT_NOQUOTES); ?></div>
+	</body>
+</html>

+ 0 - 212
tpl/bootstrap.html

@@ -1,212 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
-		<meta charset="utf-8" />
-		<meta http-equiv="X-UA-Compatible" content="IE=edge">
-		<meta name="viewport" content="width=device-width, initial-scale=1">
-		<meta name="robots" content="noindex" />
-		<title>{function="i18n::_('PrivateBin')"}</title>
-		<link type="text/css" rel="stylesheet" href="css/bootstrap/bootstrap-3.3.5.css" />
-		<link type="text/css" rel="stylesheet" href="css/bootstrap/bootstrap-theme-3.3.5.css" />
-		<link type="text/css" rel="stylesheet" href="css/bootstrap/privatebin.css?{$VERSION|rawurlencode}" />{if="$SYNTAXHIGHLIGHTING"}
-		<link type="text/css" rel="stylesheet" href="css/prettify/prettify.css?{$VERSION|rawurlencode}" />{if="strlen($SYNTAXHIGHLIGHTINGTHEME)"}
-		<link type="text/css" rel="stylesheet" href="css/prettify/{$SYNTAXHIGHLIGHTINGTHEME}.css?{$VERSION|rawurlencode}" />{/if}{/if}
-		<script type="text/javascript" src="js/jquery-1.11.3.js"></script>
-		<script type="text/javascript" src="js/sjcl-1.0.4.js"></script>
-		<script type="text/javascript" src="js/base64-{$BASE64JSVERSION}.js"></script>
-		<script type="text/javascript" src="js/rawdeflate-0.5.js"></script>
-		<script type="text/javascript" src="js/rawinflate-0.3.js"></script>
-		<script type="text/javascript" src="js/bootstrap-3.3.5.js"></script>{if="$SYNTAXHIGHLIGHTING"}
-		<script type="text/javascript" src="js/prettify.js?{$VERSION|rawurlencode}"></script>{/if}{if="$MARKDOWN"}
-		<script type="text/javascript" src="js/showdown-1.4.1.js"></script>{/if}
-		<script type="text/javascript" src="js/privatebin.js?{$VERSION|rawurlencode}"></script>
-		<!--[if lt IE 10]>
-		<style type="text/css">#ienotice {display:block !important;} #oldienotice {display:block !important;}</style>
-		<![endif]-->
-		<link rel="apple-touch-icon" href="apple-touch-icon.png?{$VERSION|rawurlencode}" sizes="180x180" />
-		<link rel="icon" type="image/png" href="favicon-32x32.png?{$VERSION|rawurlencode}" sizes="32x32" />
-		<link rel="icon" type="image/png" href="favicon-16x16.png?{$VERSION|rawurlencode}" sizes="16x16" />
-		<link rel="manifest" href="manifest.json?{$VERSION|rawurlencode}" />
-		<link rel="mask-icon" href="safari-pinned-tab.svg?{$VERSION|rawurlencode}" color="#ffcc00" />
-		<link rel="shortcut icon" href="favicon.ico">
-		<meta name="msapplication-config" content="browserconfig.xml">
-		<meta name="theme-color" content="#ffe57e" />
-	</head>
-	<body role="document">
-		<nav class="navbar navbar-default navbar-static-top">
-				<div class="navbar-header">
-					<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
-						<span class="sr-only">{function="i18n::_('Toggle navigation')"}</span>
-						<span class="icon-bar"></span>
-						<span class="icon-bar"></span>
-						<span class="icon-bar"></span>
-					</button>
-					<a class="reloadlink navbar-brand" href="/">
-						<img alt="{function="i18n::_('PrivateBin')"}" src="favicon-32x32.png" width="20" />
-					</a>
-				</div>
-				<div id="navbar" class="navbar-collapse collapse">
-					<ul class="nav navbar-nav">
-						<li>
-							<button id="newbutton" type="button" class="reloadlink hidden btn btn-default navbar-btn">
-								<span class="glyphicon glyphicon-file" aria-hidden="true"></span> {function="i18n::_('New')"}
-							</button>{if="$EXPIRECLONE"}
-							<button id="clonebutton" type="button" class="hidden btn btn-default navbar-btn">
-								<span class="glyphicon glyphicon-duplicate" aria-hidden="true"></span> {function="i18n::_('Clone')"}
-							</button>{/if}
-							<button id="rawtextbutton" type="button" class="hidden btn btn-default navbar-btn">
-								<span class="glyphicon glyphicon-text-background" aria-hidden="true"></span> {function="i18n::_('Raw text')"}
-							</button>
-						</li>
-						<li class="dropdown">
-							<select id="pasteExpiration" name="pasteExpiration" class="hidden">
-{loop="EXPIRE"}
-								<option value="{$key}"{if="$key == $EXPIREDEFAULT"} selected="selected"{/if}>{$value}</option>{/loop}
-							</select>
-							<a id="expiration" href="#" class="hidden dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{function="i18n::_('Expires')"}: <span id="pasteExpirationDisplay">{$EXPIRE[$EXPIREDEFAULT]}</span> <span class="caret"></span></a>
-							<ul class="dropdown-menu">
-{loop="EXPIRE"}
-								<li>
-									<a href="#" onclick="$('#pasteExpiration').val('{$key}');$('#pasteExpirationDisplay').text('{$value}');return false;">
-										{$value}
-									</a>
-								</li>{/loop}
-							</ul>
-						</li>
-						<li>
-							<div id="burnafterreadingoption" class="navbar-text checkbox hidden">
-								<label>
-									<input type="checkbox" id="burnafterreading" name="burnafterreading" {if="$BURNAFTERREADINGSELECTED"} checked="checked"{/if} />
-									{function="i18n::_('Burn after reading')"}
-								</label>
-							</div>
-						</li>{if="$DISCUSSION"}
-						<li>
-							<div id="opendisc" class="navbar-text checkbox hidden">
-								<label>
-									<input type="checkbox" id="opendiscussion" name="opendiscussion" {if="$OPENDISCUSSION"} checked="checked"{/if} />
-									{function="i18n::_('Open discussion')"}
-							 	</label>
-							</div>
-						</li>{/if}{if="$PASSWORD"}
-						<li>
-							<div id="password" class="navbar-form hidden">
-								<input type="password" id="passwordinput" placeholder="{function="i18n::_('Password (recommended)')"}" class="form-control" size="19"/>
-							</div>
-						</li>{/if}{if="$FILEUPLOAD"}
-						<li id="attach" class="hidden dropdown">
-							<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{function="i18n::_('Attach a file')"} <span class="caret"></span></a>
-							<ul class="dropdown-menu">
-								<li id="filewrap">
-									<div>
-										<input type="file" id="file" name="file" />
-									</div>
-								</li>
-								<li>
-									<a id="fileremovebutton"  href="#">
-										{function="i18n::_('Remove attachment')"}
-									</a>
-								</li>
-							</ul>
-						</li>{/if}
-						<li class="dropdown">
-							<select id="pasteFormatter" name="pasteFormatter" class="hidden">
-{loop="FORMATTER"}
-								<option value="{$key}"{if="$key == $FORMATTERDEFAULT"} selected="selected"{/if}>{$value}</option>{/loop}
-							</select>
-							<a id="formatter" href="#" class="hidden dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{function="i18n::_('Format')"}: <span id="pasteFormatterDisplay">{$FORMATTER[$FORMATTERDEFAULT]}</span> <span class="caret"></span></a>
-							<ul class="dropdown-menu">
-{loop="FORMATTER"}
-								<li>
-									<a href="#" onclick="$('#pasteFormatter').val('{$key}');$('#pasteFormatterDisplay').text('{$value}');return false;">
-										{$value}
-									</a>
-								</li>{/loop}
-							</ul>
-						</li>
-					</ul>
-					<ul class="nav navbar-nav pull-right">{if="strlen($LANGUAGESELECTION)"}
-						<li id="language" class="dropdown">
-							<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="glyphicon glyphicon-flag" aria-hidden="true"></span> {$LANGUAGES[$LANGUAGESELECTION][0]} <span class="caret"></span></a>
-							<ul class="dropdown-menu">
-{loop="LANGUAGES"}
-								<li>
-									<a href="#" class="reloadlink" onclick="document.cookie='lang={$key}';">
-									{$value[0]} ({$value[1]})
-								</a>
-							</li>{/loop}
-						</ul>
-					</li>{/if}
-					<li>
-						<button id="sendbutton" type="button" class="hidden btn btn-primary navbar-btn">
-							<span class="glyphicon glyphicon-upload" aria-hidden="true"></span> {function="i18n::_('Send')"}
-						</button>
-					</li>
-				</ul>
-			</div>
-		</nav>
-		<header class="container">{if="strlen($NOTICE)"}
-			<div role="alert" class="alert alert-info">
-				<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span> {$NOTICE|htmlspecialchars}
-			</div>{/if}
-			<div id="remainingtime" role="alert" class="hidden alert alert-info">
-				<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>
-			</div>{if="$FILEUPLOAD"}
-			<div id="attachment" role="alert" class="hidden alert alert-info">
-				<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span> <a>{function="i18n::_('Download attachment')"}</a> <span id="clonedfile" class="hidden">{function="i18n::_('Cloned file attached.')"}</span>
-			</div>{/if}{if="strlen($STATUS)"}
-			<div id="status" role="alert" class="alert alert-success">
-				<span class="glyphicon glyphicon-ok" aria-hidden="true"></span> {$STATUS|htmlspecialchars}
-			</div>{/if}
-			<div id="errormessage" role="alert" class="{if="!strlen($ERROR)"}hidden {/if}alert alert-danger"><span class="glyphicon glyphicon-alert" aria-hidden="true"></span> {$ERROR|htmlspecialchars}</div>
-			<noscript><div id="noscript" role="alert" class="nonworking alert alert-warning"><span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span> {function="i18n::_('Javascript is required for PrivateBin to work.<br />Sorry for the inconvenience.')"}</div></noscript>
-			<div id="oldienotice" role="alert" class="hidden nonworking alert alert-danger"><span class="glyphicon glyphicon-alert" aria-hidden="true"></span> {function="i18n::_('PrivateBin requires a modern browser to work.')"}</div>
-			<div id="ienotice" role="alert" class="hidden alert alert-warning"><span class="glyphicon glyphicon-question-sign" aria-hidden="true"></span> {function="i18n::_('Still using Internet Explorer? Do yourself a favor, switch to a modern browser:')"}
-				<a href="https://www.mozilla.org/firefox/">Firefox</a>,
-				<a href="https://www.opera.com/">Opera</a>,
-				<a href="https://www.google.com/chrome">Chrome</a>,
-				<a href="https://www.apple.com/safari">Safari</a>,
-				<a href="https://www.microsoft.com/edge">Edge</a>...
-			</div>
-			<div id="pasteresult" role="alert" class="hidden alert alert-success">
-				<span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
-				<div id="deletelink"></div>
-				<div id="pastelink">{if="strlen($URLSHORTENER)"}
-					<button id="shortenbutton" data-shortener="{$URLSHORTENER|htmlspecialchars}" type="button" class="btn btn-primary">
-						<span class="glyphicon glyphicon-send" aria-hidden="true"></span> {function="i18n::_('Shorten URL')"}
-					</button>
-				{/if}</div>
-			</div>
-			<ul id="preview" class="nav nav-tabs hidden">
-				<li role="presentation" class="active"><a id="messageedit" href="#">{function="i18n::_('Editor')"}</a></li>
-				<li role="presentation"><a id="messagepreview" href="#">{function="i18n::_('Preview')"}</a></li>
-			</ul>
-		</header>
-		<section class="container">
-			<article class="row">
-				<div id="image" class="col-md-12 text-center hidden"></div>
-				<div id="prettymessage" class="col-md-12 hidden">
-					<pre id="prettyprint" class="col-md-12 prettyprint linenums:1"></pre>
-				</div>
-				<div id="cleartext" class="col-md-12 hidden"></div>
-				<p class="col-md-12"><textarea id="message" name="message" cols="80" rows="25" class="form-control hidden"></textarea></p>
-			</article>
-		</section>
-		<section class="container">
-			<div id="discussion" class="hidden">
-				<h4>{function="i18n::_('Discussion')"}</h4>
-				<div id="comments"></div>
-			</div>
-		</section>
-		<footer class="container">
-			<div class="row">
-				<h4 class="col-md-5 col-xs-8">{function="i18n::_('PrivateBin')"} <small>- {function="i18n::_('Because ignorance is bliss')"}</small></h4>
-				<p class="col-md-1 col-xs-4 text-center">{$VERSION}</p>
-				<p id="aboutbox" class="col-md-6 col-xs-12">
-					{function="i18n::_('PrivateBin is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted <i>in the browser</i> using 256 bits AES. More information on the <a href="https://github.com/PrivateBin/PrivateBin/wiki">project page</a>.')"}
-				</p>
-			</div>
-		</footer>
-		<div id="cipherdata" class="hidden">{$CIPHERDATA}</div>
-	</body>
-</html>

+ 252 - 0
tpl/bootstrap.php

@@ -0,0 +1,252 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<meta http-equiv="X-UA-Compatible" content="IE=edge">
+		<meta name="viewport" content="width=device-width, initial-scale=1">
+		<meta name="robots" content="noindex" />
+		<title><?php echo i18n::_('PrivateBin'); ?></title>
+		<link type="text/css" rel="stylesheet" href="css/bootstrap/bootstrap-3.3.5.css" />
+		<link type="text/css" rel="stylesheet" href="css/bootstrap/bootstrap-theme-3.3.5.css" />
+		<link type="text/css" rel="stylesheet" href="css/bootstrap/privatebin.css?<?php echo rawurlencode($VERSION); ?>" /><?php
+if ($SYNTAXHIGHLIGHTING): ?>
+		<link type="text/css" rel="stylesheet" href="css/prettify/prettify.css?<?php echo rawurlencode($VERSION); ?>" /><?php
+	if (strlen($SYNTAXHIGHLIGHTINGTHEME)): ?>
+		<link type="text/css" rel="stylesheet" href="css/prettify/<?php echo rawurlencode($SYNTAXHIGHLIGHTINGTHEME); ?>.css?<?php echo rawurlencode($VERSION); ?>" /><?php
+	endif;
+endif; ?>
+		<script type="text/javascript" src="js/jquery-1.11.3.js"></script>
+		<script type="text/javascript" src="js/sjcl-1.0.4.js"></script>
+		<script type="text/javascript" src="js/base64-<?php echo rawurlencode($BASE64JSVERSION); ?>.js"></script>
+		<script type="text/javascript" src="js/rawdeflate-0.5.js"></script>
+		<script type="text/javascript" src="js/rawinflate-0.3.js"></script>
+		<script type="text/javascript" src="js/bootstrap-3.3.5.js"></script><?php
+if ($SYNTAXHIGHLIGHTING): ?>
+		<script type="text/javascript" src="js/prettify.js?<?php echo rawurlencode($VERSION); ?>"></script><?php
+endif;
+if ($MARKDOWN): ?>
+		<script type="text/javascript" src="js/showdown-1.4.1.js"></script><?php
+endif; ?>
+		<script type="text/javascript" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>"></script>
+		<!--[if lt IE 10]>
+		<style type="text/css">body {padding-left:60px;padding-right:60px;} #ienotice {display:block;} #oldienotice {display:block;}</style>
+		<![endif]-->
+		<link rel="apple-touch-icon" href="apple-touch-icon.png?<?php echo rawurlencode($VERSION); ?>" sizes="180x180" />
+		<link rel="icon" type="image/png" href="favicon-32x32.png?<?php echo rawurlencode($VERSION); ?>" sizes="32x32" />
+		<link rel="icon" type="image/png" href="favicon-16x16.png?<?php echo rawurlencode($VERSION); ?>" sizes="16x16" />
+		<link rel="manifest" href="manifest.json?<?php echo rawurlencode($VERSION); ?>" />
+		<link rel="mask-icon" href="safari-pinned-tab.svg?<?php echo rawurlencode($VERSION); ?>" color="#ffcc00" />
+		<link rel="shortcut icon" href="favicon.ico">
+		<meta name="msapplication-config" content="browserconfig.xml">
+		<meta name="theme-color" content="#ffe57e" />
+	</head>
+	<body role="document">
+		<nav class="navbar navbar-default navbar-static-top">
+			<div class="navbar-header">
+				<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
+					<span class="sr-only"><?php echo i18n::_('Toggle navigation'); ?></span>
+					<span class="icon-bar"></span>
+					<span class="icon-bar"></span>
+					<span class="icon-bar"></span>
+				</button>
+				<a class="reloadlink navbar-brand" href="/">
+					<img alt="<?php echo i18n::_('PrivateBin'); ?>" src="favicon-32x32.png" width="20" />
+				</a>
+			</div>
+			<div id="navbar" class="navbar-collapse collapse">
+				<ul class="nav navbar-nav">
+					<li>
+						<button id="newbutton" type="button" class="reloadlink hidden btn btn-default navbar-btn">
+							<span class="glyphicon glyphicon-file" aria-hidden="true"></span> <?php echo i18n::_('New'); ?>
+						</button><?php
+if ($EXPIRECLONE): ?>
+						<button id="clonebutton" type="button" class="hidden btn btn-default navbar-btn">
+							<span class="glyphicon glyphicon-duplicate" aria-hidden="true"></span> <?php echo i18n::_('Clone'); ?>
+						</button><?php
+endif; ?>
+						<button id="rawtextbutton" type="button" class="hidden btn btn-default navbar-btn">
+							<span class="glyphicon glyphicon-text-background" aria-hidden="true"></span> <?php echo i18n::_('Raw text'); ?>
+						</button>
+					</li>
+					<li class="dropdown">
+						<select id="pasteExpiration" name="pasteExpiration" class="hidden"><?php
+foreach ($EXPIRE as $key => $value): ?>
+							<option value="<?php echo $key; ?>"<?php
+	if ($key == $EXPIREDEFAULT): ?> selected="selected"<?php
+	endif; ?>><?php echo $value; ?></option><?php
+endforeach; ?>
+						</select>
+						<a id="expiration" href="#" class="hidden dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><?php echo i18n::_('Expires'); ?>: <span id="pasteExpirationDisplay"><?php echo $EXPIRE[$EXPIREDEFAULT]; ?></span> <span class="caret"></span></a>
+						<ul class="dropdown-menu"><?php
+foreach ($EXPIRE as $key => $value): ?>
+							<li>
+								<a href="#" onclick="$('#pasteExpiration').val('<?php echo $key; ?>');$('#pasteExpirationDisplay').text('<?php echo $value; ?>');return false;">
+									<?php echo $value; ?>
+								</a>
+							</li><?php
+endforeach; ?>
+						</ul>
+					</li>
+					<li>
+						<div id="burnafterreadingoption" class="navbar-text checkbox hidden">
+							<label>
+								<input type="checkbox" id="burnafterreading" name="burnafterreading" <?php
+if ($BURNAFTERREADINGSELECTED): ?> checked="checked"<?php
+endif; ?> />
+								<?php echo i18n::_('Burn after reading'); ?>
+							</label>
+						</div>
+					</li><?php
+if ($DISCUSSION): ?>
+					<li>
+						<div id="opendisc" class="navbar-text checkbox hidden">
+							<label>
+								<input type="checkbox" id="opendiscussion" name="opendiscussion" <?php
+	if ($OPENDISCUSSION): ?> checked="checked"<?php
+	endif; ?> />
+								<?php echo i18n::_('Open discussion'); ?>
+						 	</label>
+						</div>
+					</li><?php
+endif;
+if ($PASSWORD): ?>
+					<li>
+						<div id="password" class="navbar-form hidden">
+							<input type="password" id="passwordinput" placeholder="<?php echo i18n::_('Password (recommended)'); ?>" class="form-control" size="19" />
+						</div>
+					</li><?php
+endif;
+if ($FILEUPLOAD): ?>
+					<li id="attach" class="hidden dropdown">
+						<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><?php echo i18n::_('Attach a file'); ?> <span class="caret"></span></a>
+						<ul class="dropdown-menu">
+							<li id="filewrap">
+								<div>
+									<input type="file" id="file" name="file" />
+								</div>
+							</li>
+							<li>
+								<a id="fileremovebutton"  href="#">
+									<?php echo i18n::_('Remove attachment'); ?>
+								</a>
+							</li>
+						</ul>
+					</li><?php
+endif; ?>
+					<li class="dropdown">
+						<select id="pasteFormatter" name="pasteFormatter" class="hidden"><?php
+foreach ($FORMATTER as $key => $value): ?>
+							<option value="<?php echo $key; ?>"<?php
+	if ($key == $FORMATTERDEFAULT): ?> selected="selected"<?php
+	endif; ?>><?php echo $value; ?></option><?php
+endforeach; ?>
+						</select>
+						<a id="formatter" href="#" class="hidden dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><?php echo i18n::_('Format'); ?>: <span id="pasteFormatterDisplay"><?php echo $FORMATTER[$FORMATTERDEFAULT]; ?></span> <span class="caret"></span></a>
+						<ul class="dropdown-menu"><?php
+foreach ($FORMATTER as $key => $value): ?>
+							<li>
+								<a href="#" onclick="$('#pasteFormatter').val('<?php echo $key; ?>');$('#pasteFormatterDisplay').text('<?php echo $value; ?>');return false;">
+									<?php echo $value; ?>
+								</a>
+							</li><?php
+endforeach; ?>
+						</ul>
+					</li>
+				</ul>
+				<ul class="nav navbar-nav pull-right"><?php
+if (strlen($LANGUAGESELECTION)): ?>
+					<li id="language" class="dropdown">
+						<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="glyphicon glyphicon-flag" aria-hidden="true"></span> <?php echo $LANGUAGES[$LANGUAGESELECTION][0]; ?> <span class="caret"></span></a>
+						<ul class="dropdown-menu"><?php
+	foreach ($LANGUAGES as $key => $value): ?>
+							<li>
+								<a href="#" class="reloadlink" onclick="document.cookie='lang=<?php echo $key; ?>';">
+									<?php echo $value[0]; ?> (<?php echo $value[1]; ?>)
+								</a>
+							</li><?php
+	endforeach; ?>
+						</ul>
+					</li><?php
+endif; ?>
+					<li>
+						<button id="sendbutton" type="button" class="hidden btn btn-primary navbar-btn">
+							<span class="glyphicon glyphicon-upload" aria-hidden="true"></span> <?php echo i18n::_('Send'); ?>
+						</button>
+					</li>
+				</ul>
+			</div>
+		</nav>
+		<header class="container"><?php
+if (strlen($NOTICE)): ?>
+			<div role="alert" class="alert alert-info">
+				<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span> <?php echo htmlspecialchars($NOTICE); ?>
+			</div><?php
+endif; ?>
+			<div id="remainingtime" role="alert" class="hidden alert alert-info">
+				<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>
+			</div><?php
+if ($FILEUPLOAD): ?>
+			<div id="attachment" role="alert" class="hidden alert alert-info">
+				<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span> <a><?php echo i18n::_('Download attachment'); ?></a> <span id="clonedfile" class="hidden"><?php echo i18n::_('Cloned file attached.'); ?></span>
+			</div><?php
+endif;
+if (strlen($STATUS)): ?>
+			<div id="status" role="alert" class="alert alert-success">
+				<span class="glyphicon glyphicon-ok" aria-hidden="true"></span> <?php echo htmlspecialchars($STATUS); ?>
+			</div><?php
+endif; ?>
+			<div id="errormessage" role="alert" class="<?php
+if (!strlen($ERROR)): ?>hidden <?php
+endif; ?>alert alert-danger"><span class="glyphicon glyphicon-alert" aria-hidden="true"></span> <?php echo htmlspecialchars($ERROR); ?></div>
+			<noscript><div id="noscript" role="alert" class="nonworking alert alert-warning"><span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span> <?php echo i18n::_('Javascript is required for PrivateBin to work.<br />Sorry for the inconvenience.'); ?></div></noscript>
+			<div id="oldienotice" role="alert" class="hidden nonworking alert alert-danger"><span class="glyphicon glyphicon-alert" aria-hidden="true"></span> <?php echo i18n::_('PrivateBin requires a modern browser to work.'); ?></div>
+			<div id="ienotice" role="alert" class="hidden alert alert-warning"><span class="glyphicon glyphicon-question-sign" aria-hidden="true"></span> <?php echo i18n::_('Still using Internet Explorer? Do yourself a favor, switch to a modern browser:'); ?>
+				<a href="https://www.mozilla.org/firefox/">Firefox</a>,
+				<a href="https://www.opera.com/">Opera</a>,
+				<a href="https://www.google.com/chrome">Chrome</a>,
+				<a href="https://www.apple.com/safari">Safari</a>...
+			</div>
+			<div id="pasteresult" role="alert" class="hidden alert alert-success">
+				<span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
+				<div id="deletelink"></div>
+				<div id="pastelink"><?php
+if (strlen($URLSHORTENER)): ?>
+					<button id="shortenbutton" data-shortener="<?php echo htmlspecialchars($URLSHORTENER); ?>" type="button" class="btn btn-primary">
+						<span class="glyphicon glyphicon-send" aria-hidden="true"></span> <?php echo i18n::_('Shorten URL'); ?>
+					</button><?php
+endif; ?>
+				</div>
+			</div>
+			<ul id="preview" class="nav nav-tabs hidden">
+				<li role="presentation" class="active"><a id="messageedit" href="#"><?php echo i18n::_('Editor'); ?></a></li>
+				<li role="presentation"><a id="messagepreview" href="#"><?php echo i18n::_('Preview'); ?></a></li>
+			</ul>
+		</header>
+		<section class="container">
+			<article class="row">
+				<div id="image" class="col-md-12 text-center hidden"></div>
+				<div id="prettymessage" class="col-md-12 hidden">
+					<pre id="prettyprint" class="col-md-12 prettyprint linenums:1"></pre>
+				</div>
+				<div id="cleartext" class="col-md-12 hidden"></div>
+				<p class="col-md-12"><textarea id="message" name="message" cols="80" rows="25" class="form-control hidden"></textarea></p>
+			</article>
+		</section>
+		<section class="container">
+			<div id="discussion" class="hidden">
+				<h4><?php echo i18n::_('Discussion'); ?></h4>
+				<div id="comments"></div>
+			</div>
+		</section>
+		<footer class="container">
+			<div class="row">
+				<h4 class="col-md-5 col-xs-8"><?php echo i18n::_('PrivateBin'); ?> <small>- <?php echo i18n::_('Because ignorance is bliss'); ?></small></h4>
+				<p class="col-md-1 col-xs-4 text-center"><?php echo $VERSION; ?></p>
+				<p id="aboutbox" class="col-md-6 col-xs-12">
+					<?php echo i18n::_('PrivateBin is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted <i>in the browser</i> using 256 bits AES. More information on the <a href="https://github.com/PrivateBin/PrivateBin/wiki">project page</a>.'); ?>
+				</p>
+			</div>
+		</footer>
+		<div id="cipherdata" class="hidden"><?php echo htmlspecialchars($CIPHERDATA, ENT_NOQUOTES); ?></div>
+	</body>
+</html>

+ 0 - 121
tpl/page.html

@@ -1,121 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
-		<meta charset="utf-8" />
-		<meta name="robots" content="noindex" />
-		<title>{function="i18n::_('PrivateBin')"}</title>
-		<link type="text/css" rel="stylesheet" href="css/privatebin.css?{$VERSION|rawurlencode}" />{if="$SYNTAXHIGHLIGHTING"}
-		<link type="text/css" rel="stylesheet" href="css/prettify/prettify.css?{$VERSION|rawurlencode}" />{if="strlen($SYNTAXHIGHLIGHTINGTHEME)"}
-		<link type="text/css" rel="stylesheet" href="css/prettify/{$SYNTAXHIGHLIGHTINGTHEME}.css?{$VERSION|rawurlencode}" />{/if}{/if}
-		<script type="text/javascript" src="js/jquery-1.11.3.js"></script>
-		<script type="text/javascript" src="js/sjcl-1.0.4.js"></script>
-		<script type="text/javascript" src="js/base64-{$BASE64JSVERSION}.js"></script>
-		<script type="text/javascript" src="js/rawdeflate-0.5.js"></script>
-		<script type="text/javascript" src="js/rawinflate-0.3.js"></script>{if="$SYNTAXHIGHLIGHTING"}
-		<script type="text/javascript" src="js/prettify.js?{$VERSION|rawurlencode}"></script>{/if}{if="$MARKDOWN"}
-		<script type="text/javascript" src="js/showdown-1.4.1.js"></script>{/if}
-		<script type="text/javascript" src="js/privatebin.js?{$VERSION|rawurlencode}"></script>
-		<!--[if lt IE 10]>
-		<style type="text/css">body {padding-left:60px;padding-right:60px;} #ienotice {display:block;} #oldienotice {display:block;}</style>
-		<![endif]-->
-		<link rel="apple-touch-icon" href="apple-touch-icon.png?{$VERSION|rawurlencode}" sizes="180x180" />
-		<link rel="icon" type="image/png" href="favicon-32x32.png?{$VERSION|rawurlencode}" sizes="32x32" />
-		<link rel="icon" type="image/png" href="favicon-16x16.png?{$VERSION|rawurlencode}" sizes="16x16" />
-		<link rel="manifest" href="manifest.json?{$VERSION|rawurlencode}" />
-		<link rel="mask-icon" href="safari-pinned-tab.svg?{$VERSION|rawurlencode}" color="#ffcc00" />
-		<link rel="shortcut icon" href="favicon.ico">
-		<meta name="msapplication-config" content="browserconfig.xml">
-		<meta name="theme-color" content="#ffe57e" />
-	</head>
-	<body>
-		<header>
-			<div id="aboutbox">
-				{function="i18n::_('PrivateBin is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted <i>in the browser</i> using 256 bits AES. More information on the <a href="https://github.com/PrivateBin/PrivateBin/wiki">project page</a>.')"}<br />{if="strlen($NOTICE)"}
-				<span class="blink">▶</span> {$NOTICE}{/if}
-			</div>
-			<h1 class="title reloadlink">{function="i18n::_('PrivateBin')"}</h1><br />
-			<h2 class="title">{function="i18n::_('Because ignorance is bliss')"}</h2><br />
-			<h3 class="title">{$VERSION}</h3>
-			<noscript><div id="noscript" class="nonworking">{function="i18n::_('Javascript is required for PrivateBin to work.<br />Sorry for the inconvenience.')"}</div></noscript>
-			<div id="oldienotice" class="nonworking">{function="i18n::_('PrivateBin requires a modern browser to work.')"}</div>
-			<div id="ienotice">{function="i18n::_('Still using Internet Explorer? Do yourself a favor, switch to a modern browser:')"}
-				<a href="https://www.mozilla.org/firefox/">Firefox</a>,
-				<a href="https://www.opera.com/">Opera</a>,
-				<a href="https://www.google.com/chrome">Chrome</a>,
-				<a href="https://www.apple.com/safari">Safari</a>,
-				<a href="https://www.microsoft.com/edge">Edge</a>...
-			</div>
-		</header>
-		<section>
-			<article>
-				<div id="status">{$STATUS|htmlspecialchars}</div>
-				<div id="errormessage" class="hidden">{$ERROR|htmlspecialchars}</div>
-				<div id="toolbar">
-					<button id="newbutton" class="reloadlink hidden"><img src="img/icon_new.png" width="11" height="15" alt="" />{function="i18n::_('New')"}</button>
-					<button id="sendbutton" class="hidden"><img src="img/icon_send.png" width="18" height="15" alt="" />{function="i18n::_('Send')"}</button>{if="$EXPIRECLONE"}
-					<button id="clonebutton" class="hidden"><img src="img/icon_clone.png" width="15" height="17" alt="" />{function="i18n::_('Clone')"}</button>{/if}
-					<button id="rawtextbutton" class="hidden"><img src="img/icon_raw.png" width="15" height="15" alt="" />{function="i18n::_('Raw text')"}</button>
-					<div id="expiration" class="hidden button">{function="i18n::_('Expires')"}:
-						<select id="pasteExpiration" name="pasteExpiration">
-{loop="EXPIRE"}
-							<option value="{$key}"{if="$key == $EXPIREDEFAULT"} selected="selected"{/if}>{$value}</option>{/loop}
-						</select>
-					</div>
-					<div id="remainingtime" class="hidden"></div>
-					<div id="burnafterreadingoption" class="button hidden">
-						<input type="checkbox" id="burnafterreading" name="burnafterreading" {if="$BURNAFTERREADINGSELECTED"} checked="checked"{/if} />
-						<label for="burnafterreading">{function="i18n::_('Burn after reading')"}</label>
-					</div>{if="$DISCUSSION"}
-					<div id="opendisc" class="button hidden">
-						<input type="checkbox" id="opendiscussion" name="opendiscussion" {if="$OPENDISCUSSION"} checked="checked"{/if} />
-						<label for="opendiscussion" {if="!$OPENDISCUSSION"} style="color: #BBBBBB;"{/if}>{function="i18n::_('Open discussion')"}</label>
-					</div>{/if}{if="$PASSWORD"}
-					<div id="password" class="hidden">
-						<input type="password" id="passwordinput" placeholder="{function="i18n::_('Password (recommended)')"}" size="32" />
-					</div>{/if}
-					<div id="formatter" class="button hidden">{function="i18n::_('Format')"}:
-						<select id="pasteFormatter" name="pasteFormatter">
-{loop="FORMATTER"}
-							<option value="{$key}"{if="$key == $FORMATTERDEFAULT"} selected="selected"{/if}>{$value}</option>{/loop}
-						</select>
-					</div>{if="strlen($LANGUAGESELECTION)"}
-					<div id="language" class="button">
-						<select name="lang">
-{loop="LANGUAGES"}
-							<option class="reloadlink" onclick="document.cookie='lang={$key}';" value="{$key}"{if="$key == $LANGUAGESELECTION"} selected="selected"{/if}>{$value[0]} ({$value[1]})</option>{/loop}
-						</select>
-					</div>{/if}
-				</div>
-				<div id="pasteresult" class="hidden">
-					<div id="deletelink"></div>
-					<div id="pastelink">{if="strlen($URLSHORTENER)"}
-						<button id="shortenbutton" data-shortener="{$URLSHORTENER|htmlspecialchars}"><img src="img/icon_shorten.png" width="13" height="15" />{function="i18n::_('Shorten URL')"}</button>
-					{/if}</div>
-				</div>{if="$FILEUPLOAD"}
-				<div id="attachment" class="hidden"><a>{function="i18n::_('Download attachment')"}</a></div>
-				<div id="attach" class="hidden">
-					<span id="clonedfile" class="hidden">{function="i18n::_('Cloned file attached.')"}</span>
-					<span id="filewrap">{function="i18n::_('Attach a file')"}: <input type="file" id="file" name="file" /></span>
-					<button id="fileremovebutton">{function="i18n::_('Remove attachment')"}</button>
-				</div>{/if}
-				<div id="preview" class="hidden">
-					<button id="messageedit">{function="i18n::_('Editor')"}</button>
-					<button id="messagepreview">{function="i18n::_('Preview')"}</button>
-				</div>
-				<div id="image" class="hidden"></div>
-				<div id="prettymessage" class="hidden">
-					<pre id="prettyprint" class="prettyprint linenums:1"></pre>
-				</div>
-				<div id="cleartext" class="hidden"></div>
-				<textarea id="message" name="message" cols="80" rows="25" class="hidden"></textarea>
-			</article>
-		</section>
-		<section>
-			<div id="discussion" class="hidden">
-				<h4 class="title">{function="i18n::_('Discussion')"}</h4>
-				<div id="comments"></div>
-			</div>
-		</section>
-		<div id="cipherdata" class="hidden">{$CIPHERDATA}</div>
-	</body>
-</html>

+ 157 - 0
tpl/page.php

@@ -0,0 +1,157 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<meta name="robots" content="noindex" />
+		<title><?php echo i18n::_('PrivateBin'); ?></title>
+		<link type="text/css" rel="stylesheet" href="css/privatebin.css?<?php echo rawurlencode($VERSION); ?>" /><?php
+if ($SYNTAXHIGHLIGHTING): ?>
+		<link type="text/css" rel="stylesheet" href="css/prettify/prettify.css?<?php echo rawurlencode($VERSION); ?>" /><?php
+	if (strlen($SYNTAXHIGHLIGHTINGTHEME)): ?>
+		<link type="text/css" rel="stylesheet" href="css/prettify/<?php echo rawurlencode($SYNTAXHIGHLIGHTINGTHEME); ?>.css?<?php echo rawurlencode($VERSION); ?>" /><?php
+	endif;
+endif; ?>
+		<script type="text/javascript" src="js/jquery-1.11.3.js"></script>
+		<script type="text/javascript" src="js/sjcl-1.0.4.js"></script>
+		<script type="text/javascript" src="js/base64-<?php echo rawurlencode($BASE64JSVERSION); ?>.js"></script>
+		<script type="text/javascript" src="js/rawdeflate-0.5.js"></script>
+		<script type="text/javascript" src="js/rawinflate-0.3.js"></script><?php
+if ($SYNTAXHIGHLIGHTING): ?>
+		<script type="text/javascript" src="js/prettify.js?<?php echo rawurlencode($VERSION); ?>"></script><?php
+endif;
+if ($MARKDOWN): ?>
+		<script type="text/javascript" src="js/showdown-1.4.1.js"></script><?php
+endif; ?>
+		<script type="text/javascript" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>"></script>
+		<!--[if lt IE 10]>
+		<style type="text/css">body {padding-left:60px;padding-right:60px;} #ienotice {display:block;} #oldienotice {display:block;}</style>
+		<![endif]-->
+		<link rel="apple-touch-icon" href="apple-touch-icon.png?<?php echo rawurlencode($VERSION); ?>" sizes="180x180" />
+		<link rel="icon" type="image/png" href="favicon-32x32.png?<?php echo rawurlencode($VERSION); ?>" sizes="32x32" />
+		<link rel="icon" type="image/png" href="favicon-16x16.png?<?php echo rawurlencode($VERSION); ?>" sizes="16x16" />
+		<link rel="manifest" href="manifest.json?<?php echo rawurlencode($VERSION); ?>" />
+		<link rel="mask-icon" href="safari-pinned-tab.svg?<?php echo rawurlencode($VERSION); ?>" color="#ffcc00" />
+		<link rel="shortcut icon" href="favicon.ico">
+		<meta name="msapplication-config" content="browserconfig.xml">
+		<meta name="theme-color" content="#ffe57e" />
+	</head>
+	<body>
+		<header>
+			<div id="aboutbox">
+				<?php echo i18n::_('PrivateBin is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted <i>in the browser</i> using 256 bits AES. More information on the <a href="https://github.com/PrivateBin/PrivateBin/wiki">project page</a>.'); ?><br /><?php
+if (strlen($NOTICE)): ?>
+				<span class="blink">▶</span> <?php echo htmlspecialchars($NOTICE);
+endif; ?>
+			</div>
+			<h1 class="title reloadlink"><?php echo i18n::_('PrivateBin'); ?></h1><br />
+			<h2 class="title"><?php echo i18n::_('Because ignorance is bliss'); ?></h2><br />
+			<h3 class="title"><?php echo $VERSION; ?></h3>
+			<noscript><div id="noscript" class="nonworking"><?php echo i18n::_('Javascript is required for PrivateBin to work.<br />Sorry for the inconvenience.'); ?></div></noscript>
+			<div id="oldienotice" class="nonworking"><?php echo i18n::_('PrivateBin requires a modern browser to work.'); ?></div>
+			<div id="ienotice"><?php echo i18n::_('Still using Internet Explorer? Do yourself a favor, switch to a modern browser:'); ?>
+				<a href="https://www.mozilla.org/firefox/">Firefox</a>,
+				<a href="https://www.opera.com/">Opera</a>,
+				<a href="https://www.google.com/chrome">Chrome</a>,
+				<a href="https://www.apple.com/safari">Safari</a>...
+			</div>
+		</header>
+		<section>
+			<article>
+				<div id="status"><?php echo htmlspecialchars($STATUS); ?></div>
+				<div id="errormessage" class="hidden"><?php echo htmlspecialchars($ERROR); ?></div>
+				<div id="toolbar">
+					<button id="newbutton" class="reloadlink hidden"><img src="img/icon_new.png" width="11" height="15" alt="" /><?php echo i18n::_('New'); ?></button>
+					<button id="sendbutton" class="hidden"><img src="img/icon_send.png" width="18" height="15" alt="" /><?php echo i18n::_('Send'); ?></button><?php
+if ($EXPIRECLONE): ?>
+					<button id="clonebutton" class="hidden"><img src="img/icon_clone.png" width="15" height="17" alt="" /><?php echo i18n::_('Clone'); ?></button><?php
+endif; ?>
+					<button id="rawtextbutton" class="hidden"><img src="img/icon_raw.png" width="15" height="15" alt="" /><?php echo i18n::_('Raw text'); ?></button>
+					<div id="expiration" class="hidden button"><?php echo i18n::_('Expires'); ?>:
+						<select id="pasteExpiration" name="pasteExpiration"><?php
+foreach ($EXPIRE as $key => $value): ?>
+							<option value="<?php echo $key; ?>"<?php
+	if ($key == $EXPIREDEFAULT): ?> selected="selected"<?php
+	endif; ?>><?php echo $value; ?></option><?php
+endforeach; ?>
+						</select>
+					</div>
+					<div id="remainingtime" class="hidden"></div>
+					<div id="burnafterreadingoption" class="button hidden">
+						<input type="checkbox" id="burnafterreading" name="burnafterreading" <?php
+if ($BURNAFTERREADINGSELECTED): ?> checked="checked"<?php
+endif; ?> />
+						<label for="burnafterreading"><?php echo i18n::_('Burn after reading'); ?></label>
+					</div><?php
+if ($DISCUSSION): ?>
+					<div id="opendisc" class="button hidden">
+						<input type="checkbox" id="opendiscussion" name="opendiscussion" <?php
+	if ($OPENDISCUSSION): ?> checked="checked"<?php
+	endif; ?> />
+						<label for="opendiscussion" <?php
+	if (!$OPENDISCUSSION): ?> style="color: #BBBBBB;"<?php
+	endif; ?>><?php echo i18n::_('Open discussion'); ?></label>
+					</div><?php
+endif;
+if ($PASSWORD): ?>
+					<div id="password" class="hidden">
+						<input type="password" id="passwordinput" placeholder="<?php echo i18n::_('Password (recommended)'); ?>" size="32" />
+					</div><?php
+endif; ?>
+					<div id="formatter" class="button hidden"><?php echo i18n::_('Format'); ?>:
+						<select id="pasteFormatter" name="pasteFormatter"><?php
+foreach ($FORMATTER as $key => $value): ?>
+							<option value="<?php echo $key; ?>"<?php
+	if ($key == $FORMATTERDEFAULT): ?> selected="selected"<?php
+	endif; ?>><?php echo $value; ?></option><?php
+endforeach; ?>
+						</select>
+					</div><?php
+if (strlen($LANGUAGESELECTION)): ?>
+					<div id="language" class="button">
+						<select name="lang"><?php
+	foreach ($LANGUAGES as $key => $value): ?>
+							<option class="reloadlink" onclick="document.cookie='lang=<?php echo $key; ?>';" value="<?php echo $key; ?>"<?php
+		if ($key == $LANGUAGESELECTION): ?> selected="selected"<?php
+		endif; ?>><?php echo $value[0]; ?> (<?php echo $value[1]; ?>)</option><?php
+	endforeach; ?>
+						</select>
+					</div><?php
+endif; ?>
+				</div>
+				<div id="pasteresult" class="hidden">
+					<div id="deletelink"></div>
+					<div id="pastelink"><?php
+if (strlen($URLSHORTENER)): ?>
+						<button id="shortenbutton" data-shortener="<?php echo htmlspecialchars($URLSHORTENER); ?>"><img src="img/icon_shorten.png" width="13" height="15" /><?php echo i18n::_('Shorten URL'); ?></button><?php
+endif; ?>
+					</div>
+				</div><?php
+if ($FILEUPLOAD): ?>
+				<div id="attachment" class="hidden"><a><?php echo i18n::_('Download attachment'); ?></a></div>
+				<div id="attach" class="hidden">
+					<span id="clonedfile" class="hidden"><?php echo i18n::_('Cloned file attached.'); ?></span>
+					<span id="filewrap"><?php echo i18n::_('Attach a file'); ?>: <input type="file" id="file" name="file" /></span>
+					<button id="fileremovebutton"><?php echo i18n::_('Remove attachment'); ?></button>
+				</div><?php
+endif; ?>
+				<div id="preview" class="hidden">
+					<button id="messageedit"><?php echo i18n::_('Editor'); ?></button>
+					<button id="messagepreview"><?php echo i18n::_('Preview'); ?></button>
+				</div>
+				<div id="image" class="hidden"></div>
+				<div id="prettymessage" class="hidden">
+					<pre id="prettyprint" class="prettyprint linenums:1"></pre>
+				</div>
+				<div id="cleartext" class="hidden"></div>
+				<textarea id="message" name="message" cols="80" rows="25" class="hidden"></textarea>
+			</article>
+		</section>
+		<section>
+			<div id="discussion" class="hidden">
+				<h4 class="title"><?php echo i18n::_('Discussion'); ?></h4>
+				<div id="comments"></div>
+			</div>
+		</section>
+		<div id="cipherdata" class="hidden"><?php echo htmlspecialchars($CIPHERDATA, ENT_NOQUOTES); ?></div>
+	</body>
+</html>

+ 16 - 13
tst/RainTPL.php → tst/view.php

@@ -1,10 +1,18 @@
 <?php
 <?php
-class RainTPLTest extends PHPUnit_Framework_TestCase
+class viewTest extends PHPUnit_Framework_TestCase
 {
 {
     private static $error = 'foo bar';
     private static $error = 'foo bar';
 
 
     private static $status = '!*#@?$+';
     private static $status = '!*#@?$+';
 
 
+    private static $formatters = array(
+        'plaintext' => 'Plain Text',
+        'syntaxhighlighting' => 'Source Code',
+        'markdown' => 'Markdown',
+    );
+
+    private static $formatter_default = 'plaintext';
+
     private static $expire = array(
     private static $expire = array(
         '5min' => '5 minutes',
         '5min' => '5 minutes',
         '1hour' => '1 hour',
         '1hour' => '1 hour',
@@ -20,12 +28,8 @@ class RainTPLTest extends PHPUnit_Framework_TestCase
     public function setUp()
     public function setUp()
     {
     {
         /* Setup Routine */
         /* Setup Routine */
-        $page = new RainTPL;
-        $page::configure(array('cache_dir' => 'tmp/'));
-        $page::$path_replace = false;
-
-        // We escape it here because ENT_NOQUOTES can't be used in RainTPL templates.
-        $page->assign('CIPHERDATA', htmlspecialchars(helper::getPaste()['data'], ENT_NOQUOTES));
+        $page = new view;
+        $page->assign('CIPHERDATA', helper::getPaste()['data']);
         $page->assign('ERROR', self::$error);
         $page->assign('ERROR', self::$error);
         $page->assign('STATUS', self::$status);
         $page->assign('STATUS', self::$status);
         $page->assign('VERSION', self::$version);
         $page->assign('VERSION', self::$version);
@@ -34,6 +38,8 @@ class RainTPLTest extends PHPUnit_Framework_TestCase
         $page->assign('MARKDOWN', true);
         $page->assign('MARKDOWN', true);
         $page->assign('SYNTAXHIGHLIGHTING', true);
         $page->assign('SYNTAXHIGHLIGHTING', true);
         $page->assign('SYNTAXHIGHLIGHTINGTHEME', 'sons-of-obsidian');
         $page->assign('SYNTAXHIGHLIGHTINGTHEME', 'sons-of-obsidian');
+        $page->assign('FORMATTER', self::$formatters);
+        $page->assign('FORMATTERDEFAULT', self::$formatter_default);
         $page->assign('BURNAFTERREADINGSELECTED', false);
         $page->assign('BURNAFTERREADINGSELECTED', false);
         $page->assign('PASSWORD', true);
         $page->assign('PASSWORD', true);
         $page->assign('FILEUPLOAD', false);
         $page->assign('FILEUPLOAD', false);
@@ -48,16 +54,12 @@ class RainTPLTest extends PHPUnit_Framework_TestCase
         ob_start();
         ob_start();
         $page->draw('page');
         $page->draw('page');
         $this->_content = ob_get_contents();
         $this->_content = ob_get_contents();
-        // run a second time from cache
-        $page->cache('page');
-        $page->draw('page');
         ob_end_clean();
         ob_end_clean();
     }
     }
 
 
     public function tearDown()
     public function tearDown()
     {
     {
         /* Tear Down Routine */
         /* Tear Down Routine */
-        helper::rmdir(PATH . 'tmp');
     }
     }
 
 
     public function testTemplateRendersCorrectly()
     public function testTemplateRendersCorrectly()
@@ -98,11 +100,12 @@ class RainTPLTest extends PHPUnit_Framework_TestCase
     }
     }
 
 
     /**
     /**
-     * @expectedException RainTpl_Exception
+     * @expectedException Exception
+     * @expectedExceptionCode 80
      */
      */
     public function testMissingTemplate()
     public function testMissingTemplate()
     {
     {
-        $test = new RainTPL;
+        $test = new view;
         $test->draw('123456789 does not exist!');
         $test->draw('123456789 does not exist!');
     }
     }
 }
 }