All spaces are stripped from sections of my scripts

  • (2 Pages)
  • +
  • 1
  • 2

24 Replies - 879 Views - Last Post: 27 July 2020 - 11:05 AM Rate Topic: -----

#1 chris98   User is offline

  • D.I.C Lover

Reputation: 44
  • View blog
  • Posts: 1,161
  • Joined: 06-July 13

All spaces are stripped from sections of my scripts

Posted 06 July 2020 - 11:04 AM

I have no idea why this is happening, other than I recently changed my forum to use IPS 4 and integrated my site with that. For some bizarre reason, a lot of whitespace is now stripped out of my HTML, to the point where it's causing functioning issues. For example, the following Twig code:

{% if graph is not none %}
<script src="https://www.gstatic.com/charts/loader.js"></script>
{% endif %}
    {% if scripts is not none %}
        {% for script in scripts %}
        <script src="{{ constant('\\SHN\\config::CDN_BASE_URL') }}js/admin/{{ script }}.js"></script>
        {% endfor %}
    {% endif %}
{% if vars is not none %}
<script type="text/javascript">
{% for var, value in vars %}
var {{ var }} = '{{ value }}';
{% endfor %}
</script>
{% endif %}

</head>



The rendered HTML:

<script src="https://www.gstatic.com/charts/loader.js"></script>		<script src="https://cdn.*************/js/admin/index.js"></script><script type="text/javascript">varcsrf_token = '7a27860bcc9e04f9160b426b33eaf888';</script>
</head>



And closer inspection: varcsrf_token = '7a27860bcc9e04f9160b426b33eaf888';

Literally the only thing which has changed is the fact I'm no longer using this code to strip out bad UTF-8 characters:

//
// Removes any "bad" characters (characters which mess with the display of a page, are invisible, etc) from the given string
// See: http://kb.mozillazine.org/Network.IDN.blacklist_chars
//
function remove_bad_characters($array)
{
	static $bad_utf8_chars;

	if (!isset($bad_utf8_chars))
	{
		$bad_utf8_chars = array(
			"\xcc\xb7"		=> '',		// COMBINING SHORT SOLIDUS OVERLAY		0337	*
			"\xcc\xb8"		=> '',		// COMBINING LONG SOLIDUS OVERLAY		0338	*
			"\xe1\x85\x9F"	=> '',		// HANGUL CHOSEONG FILLER				115F	*
			"\xe1\x85\xA0"	=> '',		// HANGUL JUNGSEONG FILLER				1160	*
			"\xe2\x80\x8b"	=> '',		// ZERO WIDTH SPACE						200B	*
			"\xe2\x80\x8c"	=> '',		// ZERO WIDTH NON-JOINER				200C
			"\xe2\x80\x8d"	=> '',		// ZERO WIDTH JOINER					200D
			"\xe2\x80\x8e"	=> '',		// LEFT-TO-RIGHT MARK					200E
			"\xe2\x80\x8f"	=> '',		// RIGHT-TO-LEFT MARK					200F
			"\xe2\x80\xaa"	=> '',		// LEFT-TO-RIGHT EMBEDDING				202A
			"\xe2\x80\xab"	=> '',		// RIGHT-TO-LEFT EMBEDDING				202B
			"\xe2\x80\xac"	=> '', 		// POP DIRECTIONAL FORMATTING			202C
			"\xe2\x80\xad"	=> '',		// LEFT-TO-RIGHT OVERRIDE				202D
			"\xe2\x80\xae"	=> '',		// RIGHT-TO-LEFT OVERRIDE				202E
			"\xe2\x80\xaf"	=> '',		// NARROW NO-BREAK SPACE				202F	*
			"\xe2\x81\x9f"	=> '',		// MEDIUM MATHEMATICAL SPACE			205F	*
			"\xe2\x81\xa0"	=> '',		// WORD JOINER							2060
			"\xe3\x85\xa4"	=> '',		// HANGUL FILLER						3164	*
			"\xef\xbb\xbf"	=> '',		// ZERO WIDTH NO-BREAK SPACE			FEFF
			"\xef\xbe\xa0"	=> '',		// HALFWIDTH HANGUL FILLER				FFA0	*
			"\xef\xbf\xb9"	=> '',		// INTERLINEAR ANNOTATION ANCHOR		FFF9	*
			"\xef\xbf\xba"	=> '',		// INTERLINEAR ANNOTATION SEPARATOR		FFFA	*
			"\xef\xbf\xbb"	=> '',		// INTERLINEAR ANNOTATION TERMINATOR	FFFB	*
			"\xef\xbf\xbc"	=> '',		// OBJECT REPLACEMENT CHARACTER			FFFC	*
			"\xef\xbf\xbd"	=> '',		// REPLACEMENT CHARACTER				FFFD	*
			"\xe2\x80\x80"	=> ' ',		// EN QUAD								2000	*
			"\xe2\x80\x81"	=> ' ',		// EM QUAD								2001	*
			"\xe2\x80\x82"	=> ' ',		// EN SPACE								2002	*
			"\xe2\x80\x83"	=> ' ',		// EM SPACE								2003	*
			"\xe2\x80\x84"	=> ' ',		// THREE-PER-EM SPACE					2004	*
			"\xe2\x80\x85"	=> ' ',		// FOUR-PER-EM SPACE					2005	*
			"\xe2\x80\x86"	=> ' ',		// SIX-PER-EM SPACE						2006	*
			"\xe2\x80\x87"	=> ' ',		// FIGURE SPACE							2007	*
			"\xe2\x80\x88"	=> ' ',		// AURACTUATION SPACE					2008	*
			"\xe2\x80\x89"	=> ' ',		// THIN SPACE							2009	*
			"\xe2\x80\x8a"	=> ' ',		// HAIR SPACE							200A	*
			"\xE3\x80\x80"	=> ' ',		// IDEOGRAPHIC SPACE					3000	*
		);
	}

	if (is_array($array))
		return array_map('remove_bad_characters', $array);

	// Strip out any invalid characters
	$array = utf8_bad_strip($array);

	// Remove control characters
	$array = preg_replace('%[\x00-\x08\x0b-\x0c\x0e-\x1f]%', '', $array);

	// Replace some "bad" characters
	$array = str_replace(array_keys($bad_utf8_chars), array_values($bad_utf8_chars), $array);

	return $array;
}

$_GET = remove_bad_characters($_GET);
$_POST = remove_bad_characters($_POST);
$_COOKIE = remove_bad_characters($_COOKIE);



I'd still be using it but I found that it breaks IPS sessions so that it doesn't recognise you're logged in anymore. Does anyone have any clue what could possibly be wrong here? Is there some kind of header or something I could send to force a utf-8 compliant output?

This post has been edited by chris98: 06 July 2020 - 11:06 AM


Is This A Good Question/Topic? 0
  • +

Replies To: All spaces are stripped from sections of my scripts

#2 Dormilich   User is offline

  • 痛覚残留
  • member icon

Reputation: 4290
  • View blog
  • Posts: 13,601
  • Joined: 08-June 10

Re: All spaces are stripped from sections of my scripts

Posted 06 July 2020 - 11:33 AM

you could omit the var declaration, it's a global anyways.

I wouldn't say it's a Twig issue, as I never had Twig strip spaces inside a line.
Was This Post Helpful? 0
  • +
  • -

#3 chris98   User is offline

  • D.I.C Lover

Reputation: 44
  • View blog
  • Posts: 1,161
  • Joined: 06-July 13

Re: All spaces are stripped from sections of my scripts

Posted 07 July 2020 - 10:21 AM

Thanks for your reply. I've done that & it works perfectly for that page.

My real issue here though is that this is a more global issue on the site, on some pages it's messing up HTML or text strings, on other pages it's stripping spaces from the browser title..... it's very strange.
Was This Post Helpful? 0
  • +
  • -

#4 CTphpnwb   User is offline

  • D.I.C Lover
  • member icon

Reputation: 3847
  • View blog
  • Posts: 14,027
  • Joined: 08-August 08

Re: All spaces are stripped from sections of my scripts

Posted 11 July 2020 - 04:28 AM

Do these pages import from other twig files? If so, I'd start by looking at the imports that are common to the affected pages. See if you can find a but in those imports.
Was This Post Helpful? 0
  • +
  • -

#5 chris98   User is offline

  • D.I.C Lover

Reputation: 44
  • View blog
  • Posts: 1,161
  • Joined: 06-July 13

Re: All spaces are stripped from sections of my scripts

Posted 23 July 2020 - 07:25 AM

Hey I'm sorry I didn't reply to you. I didn't get notified for some reason.

Sadly, there aren't any imports. I use a common header and footer across all pages, but these are rendered separately through my template class, so the header is rendered and output, then the content, then the footer.

It's such a weird glitch. I can only estimate that it's a single whitespace character somewhere in one of the files that is causing the whole page to glitch, but why this is suddenly happening, I genuinely have no idea. I also can't work out why it only appears to be happening in some pages and not others, which kinda rules out the header and footer in my opinion. But even when I try this and go to save the file after I've removed then re-added the spaces properly, my editor says that nothing in the file has changed.

I mean check out this blatant glitch on this image here: Posted Image

The code for this section in the template file is as follows:

<div itemscope itemtype="http://schema.org/Product">
	<div itemprop="name">
		<h1>{{ article['title'] }}</h1>
	</div>
	<div id="mainCenter_ratingsSmall">
		<div itemprop="aggregateRating" itemscope itemtype="http://schema.org/AggregateRating">
			<div class="line-separator"></div>
{% if article['allow_ratings'] == '1' %}
{{ lang.t('Article rating', '<strong><span itemprop="ratingValue" class="current_rating">' ~ article['rating'] ~ '</span></strong><span class="ratingsSep">')|raw }} </span> {{ lang.t('Total article rating', '<strong><span itemprop="ratingCount" class="total_ratings">' ~ article['rid'] ~ '</span></strong>')|raw }} {{ lang.t('Article separator') }} {{ lang.t('Article views', article['views']|number_format) }} {{ lang.t('Article separator') }}
{% endif %}
<a target="_blank" title="{{ lang.t('Share on Facebook') }}" href="//www.facebook.com/sharer/sharer.php?u={{ encoded_url }}"><img src="{{ constant('SHN\\config::CDN_BASE_URL') }}images/share_facebook.png" style="border:0px" alt="" /></a> {{ lang.t('Article separator') }} <a target="_blank" title="{{ lang.t('Share on Twitter') }}" href="//twitter.com/share?url={{ encoded_url }}"><img src="{{ constant('SHN\\config::CDN_BASE_URL') }}images/share_twitter.png" style="border:0px" alt="" /></a> {{ lang.t('Article separator') }} <a target="_blank" title="{{ lang.t('Share on Tumblr') }}" href="http://www.tumblr.com/share/link?url={{ encoded_url }}"><img src="{{ constant('SHN\\config::CDN_BASE_URL') }}images/share_tumblr.png" style="border:0px" alt="" /></a> {{ lang.t('Article separator') }} <a target="_blank" title="{{ lang.t('Share on Reddit') }}" href="//www.reddit.com/submit?url={{ encoded_url }}"><img src="{{ constant('SHN\\config::CDN_BASE_URL') }}images/share_reddit.png" style="border:0px" alt="" /></a> {{ lang.t('Article separator') }} {% if (_call(ips_user, 'modPermission', ['can_view_reports']) and _call(ips_user, 'canAccessModule', [_call('\\IPS\\Application\\Module', 'get', ['core', 'modcp'])])) or ips_user.isAdmin() %}<a target="_blank" title="{{ lang.t('Edit Page') }}" href="{{ constant('SHN\\config::ADMIN_BASE_URL') }}index.php?module=essentials&act=edit_article&id={{ article['id'] }}"><img src="{{ constant('SHN\\config::CDN_BASE_URL') }}images/page_edit.png" style="border:0px" alt="" /></a>{% else %}<a class="fake_link" onclick="javascript:window.print();" title="{{ lang.t('Print page') }}"><img src="{{ constant('SHN\\config::CDN_BASE_URL') }}images/print_page.png" style="border:0px" alt="" /></a>{% endif %} {% if article['allow_ratings'] == '1' %}{{ lang.t('Article separator') }} <span class="article_stars_wrapper"><span class="article_rating_wrapper"><span class="article_rating">{%- for i in 1..5 -%}
	<div class="{%- if i <= article['rating'] -%}star{%- else -%}nostar{%- endif -%}">
		<input type="radio" />
	</div>
{%- endfor -%}</span></span></span>{% endif %}
			<div class="line-separator"></div>
		</div>
	</div>
</div>


The | symbol in the browser is represented by the lang.t('Article separator'). The spaces are here..... it's just... not outputting them.
Was This Post Helpful? 0
  • +
  • -

#6 ArtificialSoldier   User is online

  • D.I.C Lover
  • member icon

Reputation: 2875
  • View blog
  • Posts: 8,276
  • Joined: 15-January 14

Re: All spaces are stripped from sections of my scripts

Posted 23 July 2020 - 11:17 AM

It kind of sounds like it's just how the library you're using works. Replace that one space with 10 spaces in a row. Hell, put them on multiple lines, stop bunching everything up and doing the minimum. Put 100 spaces there. If it removes them all, then it kind of sounds like that's how the library works.
Was This Post Helpful? 0
  • +
  • -

#7 CTphpnwb   User is offline

  • D.I.C Lover
  • member icon

Reputation: 3847
  • View blog
  • Posts: 14,027
  • Joined: 08-August 08

Re: All spaces are stripped from sections of my scripts

Posted 24 July 2020 - 07:22 AM

Looking at this again, it seems there must be bad characters in {{ var }}. How is it generated?
Was This Post Helpful? 0
  • +
  • -

#8 chris98   User is offline

  • D.I.C Lover

Reputation: 44
  • View blog
  • Posts: 1,161
  • Joined: 06-July 13

Re: All spaces are stripped from sections of my scripts

Posted 25 July 2020 - 05:09 AM

@ArtificialSoldier: I've done as you said, and it's doing exactly the same thing. But surely if it's how the library works, there wouldn't be ANY spaces at all? If it was just whitespace or in the header or page body or something, I'd have maybe just let this one go, but when I'm printing out the article for example in the screenshot above, the spaces are showing perfectly. It's only in certain places where it's doing this, not everywhere.

Quote

Looking at this again, it seems there must be bad characters in {{ var }}. How is it generated?


If you mean the JS 'var', in the admin template I originally posted, it's literally just the word var that I typed in the template. If you actually mean the variables themselves in the template, then they're just taken straight from a database query pretty much.

<?php
class article_controller extends SHNController
{
    public function execute()
    {
		$article = $this->fetch_article();
		$this->template->header = array(
			'title' => array($article['title'], ucwords($article['section']).' '.ucwords($article['type'])),
			'keywords' => $article['tags'],
			'description' => $article['description'],
			'canonical' => 'article/'.$article['id'].'-'.$article['seo_title'],
			'jquery' => true,
			'ajax' => true,
		);

        $tpl = $this->template->load('article.tpl');
		$this->template->output($tpl,
		    array(
			    'article' => $article,
			    'csrf_token' => \IPS\Session::i()->csrfKey,
		    )
		);
    }

	protected function fetch_article()
	{
		$name = isset($_GET['name']) ? utf8_trim($_GET['name']) : '';
		$id = isset($_GET['id']) ? intval($_GET['id']) : 1;
		$data = array(
			':id' => $id,
		);

		$ps = $this->db->run('SELECT COUNT(r.id) AS rid, AVG(r.rating) AS average, p.title, p.tags, p.id, p.section, p.type, p.message, p.views, p.poster_id, p.allow_ratings, p.parent, p.previous, p.next, p.show_staff FROM pages AS p LEFT JOIN ratings AS r ON p.id=r.pid WHERE p.id=:id', $data);
		$article = $ps->fetch();

		$article['seo_title'] = \SHN\url::make_seo($article['title']);
		if ($article['id'] != $id)
			$this->registry->get('\SHN\handlers\errormsg')->show(404);
		else if ($name == '')
		{
			header('Location: '.\SHN\config::SITE_BASE_URL.'article/'.$id.'-'.$article['seo_title']);
			exit;
		}

		$this->db->run('UPDATE pages SET views=views+1 WHERE id=:id', $data);

		$author = \IPS\Member::load($article['poster_id']);

		$article['rating'] = round($article['average']);
		$article['description'] = utf8_substr(strip_tags($article['message']), 0, 150).' ';
		$article['poster'] = $author->link(null, true);

		return $article;
	}
}


Then there's the language class, which is responsible for outputting the {{ lang.t('String') }}:

<?php
namespace SHN;
use Exception;

class lang
{
	protected $translations = array();
	protected static $lang_dir = 'include/i18n';
	protected static $default_lang = 'en_GB';
	protected $lang = 'en_GB';
	protected $loaded_resources = array();

	public function __construct($registry)
	{
		self::set_default_language(self::$default_lang);

		$this->registry = $registry;
		$this->cache = $registry->cache;
	}

	public static function mail_template_location($language, $type)
	{
		return SITE_ROOT.'/'.self::$lang_dir.'/'.$language.'/mail_templates/'.$type.'/';
	}

	public static function get_language_list()
	{
		static $list = null;

		if (!isset($list))
		{
			$list = array();
			foreach (glob(SITE_ROOT.self::$lang_dir.'/*', GLOB_ONLYDIR) as $dir)
			{
				$dirs = explode('/', $dir);
				$list[] = end($dirs);
			}
		}

		return $list;
	}

	public static function language_exists($lang)
	{
		return in_array($lang, self::get_language_list());
	}

	public static function set_default_language($lang)
	{
		if (self::language_exists($lang))
			self::$default_lang = $lang;
		else
			throw new Exception('Language '.$lang.' cannot be found');
	}

	public static function get_default_language()
	{
		return self::$default_lang;
	}

	public function set_language($lang)
	{
		if (self::language_exists($lang))
			$this->lang = $lang;
		else
			throw new Exception('Language '.$lang.' cannot be found');
	}

	public function load($resource, $path = '')
	{
		// Make sure we don't load it twice
		if (in_array($resource, $this->loaded_resources))
			return;

		$this->loaded_resources[] = $resource;

		if ($path == '')
			$path = SITE_ROOT.'/'.self::$lang_dir;
		else if ($path != '' && !file_exists($path))
			throw new Exception('File path '.$path.' does not exist or cannot be found');

		$trans_cache = $this->cache->get('language', array($this->lang, $resource, $path), true, true); 
		if (self::$default_lang != $this->lang) // If this isn't the default language then load that too, and we'll use it for fallback
		{
			$def_trans_cache = $this->cache->get('language', array(self::$default_lang, $resource, $path), true, true);
			$trans_cache = array_merge($def_trans_cache, $trans_cache);
		}

		// Store the loaded values for usage
		$this->translations = array_merge($this->translations, $trans_cache);
	}

	public function add_translations($resource)
	{
		$this->translations = array_merge($this->translations, $resource);
	}

	public function t($str)
	{
		if (isset($this->translations[$str]))
		{
			$args = func_get_args();
			$args[0] = $this->translations[$args[0]];
			return call_user_func_array('sprintf', $args);
		}

		return $str;
	}
}


This post has been edited by chris98: 25 July 2020 - 05:12 AM

Was This Post Helpful? 0
  • +
  • -

#9 chris98   User is offline

  • D.I.C Lover

Reputation: 44
  • View blog
  • Posts: 1,161
  • Joined: 06-July 13

Re: All spaces are stripped from sections of my scripts

Posted 25 July 2020 - 05:23 AM

Also here is my template class. Again nothing in here has actually changed, but I just wanted to give you guys the clearest picture possible on how things are setup:

<?php
class template
{
	public $header = array();
	public $footer = array();
	protected $manager;

	public function __construct($registry)
	{
        $this->registry = $registry;
		$this->cache = $registry->cache;
		$this->lang = $registry->lang;

		// Load the Twig Templating Engine
		require SITE_ROOT.'include/lib/Twig/Autoloader.php';

		// Register Twig autoloader
		Twig_Autoloader::register();

		$loader = new Twig_Loader_Filesystem(SITE_ROOT.'include/templates');
		$loader->addPath(SITE_ROOT.'include/templates/', 'site');

		$this->manager = new Twig_Environment($loader, 
			array(
				'cache' => $this->cache->cache_dir.'templates/',
				'debug' => \SHN\config::DEBUG_TEMPLATES,
			)
		);

		$this->manager->addFunction('_call', new Twig_Function_Function(
			function($class, $function, $arguments = array())
			{
				return call_user_func_array(array($class, $function), $arguments);
			})
		);

		$this->manager->addFunction('_property', new Twig_Function_Function(
			function($class, $property)
			{
				return $class->$property;
			})
		);
	}

	/**
	 * Load a template object through the template manager
	 */
    public function load($tpl_file)
    {
        return $this->manager->loadTemplate('@site/'.\SHN::_App().'/'.$tpl_file);
    }

	/**
	 * Output a template to the browser
	 */
	public function output($tpl, $data = array(), $header = true, $footer = true)
	{
		if ($header)
			$this->execute_header();

		echo $tpl->render(array_merge(
				array(
					'lang' => $this->lang,
					'ips_config' => \IPS\Settings::i(),
					'ips_user' => \IPS\Member::loggedIn(),
					'cache' => $this->cache,
					'current_url' => \SHN\url::url(),
					'encoded_url' => urlencode(\SHN\url::url()),
				), $data
			)
		);

		if ($footer)
			$this->execute_footer();
	}

	/**
	 * Render a single template object and return it to the system
	 */
	public function render($tpl, $data = array())
	{
		return $tpl->render(array_merge(
				array(
					'lang' => $this->lang,
					'ips_config' => \IPS\Settings::i(),
					'ips_user' => \IPS\Member::loggedIn(),
					'cache' => $this->cache,
					'current_url' => \SHN\url::url(),
					'encoded_url' => urlencode(\SHN\url::url()),
				), $data
			)
		);
	}

	/**
	 * Execute our header and output it to the browser
	 */
	public function execute_header()
	{
	    $class = '\SHN\templates\\'.\SHN::_App().'\template_header';
		$header = new $class($this->registry);
		$header->set_data($this->header);
		$args = $header->fetch_data();

		$tpl = $this->load($args['tpl_file']);
		$this->output($tpl, $args, false, false);
	}

	/**
	 * Execute our footer and output it to the browser
	 */
	public function execute_footer()
	{
	    $class = '\SHN\templates\\'.\SHN::_App().'\template_footer';
		$footer = new $class($this->registry);
		$footer->set_data($this->footer);
		$args = $footer->fetch_data();

		$tpl = $this->load($args['tpl_file']);
		$this->output($tpl, $args, false, false);
	}
}

abstract class template_element
{
	protected $data = array();
	final public function __construct($registry)
	{
		$this->registry = $registry;
		$this->lang = $registry->lang;
        $this->cache = $registry->cache;
		$this->db = $registry->db;
	}

	final public function set_data($data)
	{
		$this->data = $data;
	}

	abstract function fetch_data();
}


In terms of the language class, this basically just loads a file with an array of language strings, so i.e.

<?php

if (!defined('\SHN\config::DEFAULT_APP'))
	exit;

return array (
  'Title separator' => '::',
  'Browser title' => 'Site Name',
  'SHN default title' => 'Welcome to Site Name',
  'Site navigation' => 'Site Navigation',
  'Administration' => 'Administration',
........



I did at one point wonder whether there was some kind of malformed space in one of these language strings which may be messing with things (these are parsed from .po files), so in my language class file, I added utf8_trim() to the output of the t() function to try and strip any bad characters. But this didn't really make any difference to what was happening.

This post has been edited by chris98: 25 July 2020 - 05:24 AM

Was This Post Helpful? 0
  • +
  • -

#10 CTphpnwb   User is offline

  • D.I.C Lover
  • member icon

Reputation: 3847
  • View blog
  • Posts: 14,027
  • Joined: 08-August 08

Re: All spaces are stripped from sections of my scripts

Posted 25 July 2020 - 05:25 AM

I was referring to this:
{% for var, value in vars %}
var {{ var }} = '{{ value }}';
{% endfor %}


{{ var }} is a variable based on vars. I don't see how you're generating it.

This post has been edited by CTphpnwb: 25 July 2020 - 05:26 AM

Was This Post Helpful? 0
  • +
  • -

#11 chris98   User is offline

  • D.I.C Lover

Reputation: 44
  • View blog
  • Posts: 1,161
  • Joined: 06-July 13

Re: All spaces are stripped from sections of my scripts

Posted 25 July 2020 - 05:30 AM

Ah, I see. So this is done in a few stages.

<?php
class index_controller extends SHNController
{
    public function execute()
    {
		$vars = array(
			'csrf_token' => \IPS\Session::i()->csrfKey,
		);

		$crumbs = array(
			array(
				'url' => 'index.php',
				'title' => 'Dashboard',
				'description' => 'Go to Dashboard',
				'icon' => 'home',
			)
		);

		$this->template->header = array(
			'title' => 'Dashboard',
			'vars' => $vars,
			'scripts' => array('index'),
			'crumbs' => $crumbs,
			'active' => 'dashboard',
			'graph' => true,
		);

        $tpl = $this->template->load('index.tpl');
        $this->template->output($tpl);
    }
}



First of all I set it to the template as a variable using the $this->template->header, then using my template class above I send it to the template_header class, where I send it back to be rendered as part of the template:

<?php
namespace SHN\templates\admin;
use template_element;
use registry;
use SHN;

class template_header extends template_element implements \SHN\interfaces\template_element_interface
{
    public function fetch_data()
    {
        registry::send_headers('html');

        return array_merge(
            array(
                'tpl_file' => 'header.tpl',
                'session_token' => \IPS\Session::i()->csrfKey,
				'logout_link' => \IPS\Http\Url::internal('app=core&module=system&controller=login&do=logout', 'front', 'logout')->csrf()->setQueryString('ref', base64_encode(\SHN\config::SITE_BASE_URL)),
		    ), $this->data
        );
    }
}

Was This Post Helpful? 0
  • +
  • -

#12 CTphpnwb   User is offline

  • D.I.C Lover
  • member icon

Reputation: 3847
  • View blog
  • Posts: 14,027
  • Joined: 08-August 08

Re: All spaces are stripped from sections of my scripts

Posted 25 July 2020 - 05:39 AM

Where do you render the view? You seem to be taking a large number of steps to accomplish a simple goal. Somewhere in those steps, your data is being corrupted.

(I'm assuming you're using Symfony. Am I wrong?)
Was This Post Helpful? 0
  • +
  • -

#13 chris98   User is offline

  • D.I.C Lover

Reputation: 44
  • View blog
  • Posts: 1,161
  • Joined: 06-July 13

Re: All spaces are stripped from sections of my scripts

Posted 25 July 2020 - 06:06 AM

This is done via the template class through the output method. To be honest, looking again at this I know this template code isn't perfect, but for what I need it for, it is good enough (assuming it all works, that is). Obviously in an ideal world, it would be a lot better. I actually wrote this class a few years ago now, I suppose I could try to rewrite it all and make it better, maybe I could learn how Composer works too and update my Twig version, but it just seems like an awful lot of work when there really isn't much gain from it.

I'm not using Symfony, it's a custom system loosely based off code from IPS 3, that is with the general structure of the registry, and file system. So in essence:

  • I initiate the SHN class and create the registry from there
  • I load the IPS 4 sessions, forum integration etc
  • Connect to my site's database and load up all of my data, connections etc
  • Route the request to where it needs to go
  • Run the relevant controller file
  • Load any model classes needed to fetch data, or do whatever it needs to do within the controller class
  • Send any data to the template class to render the page
  • Prior to outputting the template, if needed send the header, then the page, then the footer

Was This Post Helpful? 0
  • +
  • -

#14 CTphpnwb   User is offline

  • D.I.C Lover
  • member icon

Reputation: 3847
  • View blog
  • Posts: 14,027
  • Joined: 08-August 08

Re: All spaces are stripped from sections of my scripts

Posted 25 July 2020 - 06:13 AM

Well, you need to be able to show the exact lines of code responsible for sending data to the template class. Exactly where does vars get set? What is its value when it is sent to the template? Knowing this will tell you where the corruption occurs, either in the template or prior to sending to the template.
Was This Post Helpful? 0
  • +
  • -

#15 chris98   User is offline

  • D.I.C Lover

Reputation: 44
  • View blog
  • Posts: 1,161
  • Joined: 06-July 13

Re: All spaces are stripped from sections of my scripts

Posted 25 July 2020 - 06:40 AM

Vars gets set on line #19 of my controller above. That sets it as a variable in the template class, and then when I render the template through the controller on line #29, it renders the header first. I've just done a print_r on the data before and after it's rendered by the header and it's coming back with exactly the right data each time.

This is what I'm getting that is passed to Twig as the template data:

Array ( [tpl_file] => header.tpl [session_token] => *** [logout_link] => IPS\Http\Url\Friendly Object ( [base] => front [seoTemplate] => logout [seoTitles] => Array ( ) [friendlyUrlComponent] => logout [isInternal] => 1 [isFriendly] => 1 [seoPagination] => [url:protected] => **** [data] => Array ( [scheme] => https [host] => **** [port] => [user] => [pass] => [path] => **** [query] => **** [fragment] => ) [queryString] => Array ( [csrfKey] => 012465e001e6732989c485b5a96d3082 [ref] => **** ) [hiddenQueryString] => Array ( [app] => core [module] => system [controller] => login [do] => logout ) ) [title] => Dashboard [vars] => Array ( [csrf_token] => 012465e001e6732989c485b5a96d3082 ) [scripts] => Array ( [0] => index ) [crumbs] => Array ( [0] => Array ( [url] => index.php [title] => Dashboard [description] => Go to Dashboard [icon] => home ) ) [active] => dashboard [graph] => 1 ) 


That surely means the error has to be somewhere in the Twig template, right? This is the full header.tpl file:

<!DOCTYPE html>
<html lang="en">
<head>
<title>{% if title is not none %}{{ title|join(' | ') }} |{% endif %} Administration Control Panel</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.0/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.0/css/bootstrap-responsive.min.css" />
<link rel="stylesheet" href="{{ constant('\\SHN\\config::CDN_BASE_URL') }}css/admin.css" />

<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,700,800" rel="stylesheet" type="text/css">

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.0/bootstrap.min.js"></script>

<link rel="shortcut icon" href="{{ constant('\\SHN\\config::CDN_BASE_URL') }}favicons/favicon.ico" />
<link rel="apple-touch-icon" sizes="57x57" href="{{ constant('\\SHN\\config::CDN_BASE_URL') }}favicons/apple-touch-icon-57x57.png" />
<link rel="apple-touch-icon" sizes="60x60" href="{{ constant('\\SHN\\config::CDN_BASE_URL') }}favicons/apple-touch-icon-60x60.png" />
<link rel="apple-touch-icon" sizes="72x72" href="{{ constant('\\SHN\\config::CDN_BASE_URL') }}favicons/apple-touch-icon-72x72.png" />
<link rel="apple-touch-icon" sizes="76x76" href="{{ constant('\\SHN\\config::CDN_BASE_URL') }}favicons/apple-touch-icon-76x76.png" />
<link rel="apple-touch-icon" sizes="114x114" href="{{ constant('\\SHN\\config::CDN_BASE_URL') }}favicons/apple-touch-icon-114x114.png" />
<link rel="apple-touch-icon" sizes="120x120" href="{{ constant('\\SHN\\config::CDN_BASE_URL') }}favicons/apple-touch-icon-120x120.png" />
<link rel="icon" type="image/png" href="{{ constant('\\SHN\\config::CDN_BASE_URL') }}favicons/favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="{{ constant('\\SHN\\config::CDN_BASE_URL') }}favicons/favicon-96x96.png" sizes="96x96" />
<link rel="icon" type="image/png" href="{{ constant('\\SHN\\config::CDN_BASE_URL') }}favicons/favicon-16x16.png" sizes="16x16" />
<link rel="manifest" href="{{ constant('\\SHN\\config::CDN_BASE_URL') }}favicons/android-chrome-manifest.json" />
<meta name="msapplication-TileColor" content="#2d89ef" />
<meta name="msapplication-config" content="{{ constant('\\SHN\\config::CDN_BASE_URL') }}favicons/browserconfig.xml" />
<meta name="theme-color" content="#99a6cf" />
<meta name="ROBOTS" content="NOINDEX, NOFOLLOW" />

<script src="{{ constant('\\SHN\\config::CDN_BASE_URL') }}js/admin/core.js"></script>

{% if fileupload is not none %}
<script src="{{ constant('\\SHN\\config::CDN_BASE_URL') }}js/jquery.ui.widget.js"></script>
<script src="{{ constant('\\SHN\\config::CDN_BASE_URL') }}js/jquery.iframe-transport.js"></script>
<script src="{{ constant('\\SHN\\config::CDN_BASE_URL') }}js/jquery.fileupload.js"></script>
{% endif %}

{% if tinymce is not none %}
<script src="//cdn.tinymce.com/4/tinymce.min.js"></script>
{% endif %}

{% if graph is not none %}
<script src="https://www.gstatic.com/charts/loader.js"></script>
{% endif %}
    {% if scripts is not none %}
        {% for script in scripts %}
        <script src="{{ constant('\\SHN\\config::CDN_BASE_URL') }}js/admin/{{ script }}.js"></script>
        {% endfor %}
    {% endif %}
{% if vars is not none %}
<script type="text/javascript">
{% for var, value in vars %}
var {{ var }} = '{{ value }}';
{% endfor %}
</script>
{% endif %}

</head>
<body>

<div id="header">
  <h1><a href="index.php">Dashboard</a></h1>
</div>

<div id="user-nav" class="navbar navbar-inverse">
  <ul class="nav">
    <li class="dropdown" id="profile-messages" ><a href="#" data-toggle="dropdown" data-target="#profile-messages" class="dropdown-toggle"><i class="fa fa-user"></i>  <span class="text">Welcome {{ ips_user.name }}</span><b class="caret"></b></a>
      <ul class="dropdown-menu">
        <li><a target="_blank" href="{{ constant('\\SHN\\config::SITE_BASE_URL') }}"><i class="fa fa-share-alt"></i> Back to site</a></li>
        <li class="divider"></li>
        <li><a href="index.php?module=main&act=logout&csrfKey={{ session_token }}"><i class="fa fa-check-square-o"></i> End Session</a></li>
        <li><a href="{{ logout_link }}"><i class="fa fa-key"></i> Logout</a></li>
      </ul>
    </li>
    <li><a href="index.php?module=main&act=logout&csrfKey={{ session_token }}"><i class="fa fa-mail-forward"></i> <span class="text">Logout</span></a></li>
  </ul>
</div>

<div id="sidebar"><a href="index.php" class="visible-phone"><i class="fa fa-home"></i> Dashboard</a>
  <ul>
    <li{% if active == 'dashboard' %} class="active"{% endif %}><a href="index.php"><i class="fa fa-home"></i> <span>Dashboard</span></a></li>
    <li class="submenu{% if active == 'essentials' %} active{% endif %}"><a href="#"><i class="fa fa-th-list"></i><span>Essentials</span></a>
      <ul>
    <li><a href="index.php?module=essentials&act=carousel">Site Carousel</a></li>
    <li><a href="index.php?module=essentials&act=polls">Poll Management</a></li>
    <li><a href="index.php?module=essentials&act=quotes">Game Quotes</a></li>
      </ul>
    </li>
    <li class="submenu{% if active == 'history' %} active{% endif %}"><a href="#"><i class="fa fa-fort-awesome"></i><span>History</span></a>
      <ul>
    <li><a href="index.php?module=essentials&act=quiz">History Quiz</a></li>
    <li><a href="index.php?module=essentials&act=onthisday">On This Day In History</a></li>
    <li><a href="index.php?module=essentials&act=add_castle">Add Historical Castle</a></li>
    <li><a href="index.php?module=essentials&act=castles">View Historical Castles</a></li>
    <li><a href="index.php?module=essentials&act=add_glossary">Add Glossary Article</a></li>
    <li><a href="index.php?module=essentials&act=glossary">View Glossary Articles</a></li>
    <li><a href="index.php?module=essentials&act=sections">Glossary Sections</a></li>
      </ul>
    </li>
    <li class="submenu{% if active == 'articles' %} active{% endif %}"><a href="#"><i class="fa fa-newspaper-o"></i><span>Articles</span></a>
      <ul>
    <li><a href="index.php?module=essentials&act=upload">Upload Images</a></li>
    <li><a href="index.php?module=essentials&act=wizard">Article Wizard</a></li>
    <li><a href="index.php?module=essentials&act=articles">View Articles</a></li>
      </ul>
    </li>
    <li class="submenu{% if active == 'downloads' %} active{% endif %}"> <a href="#"><i class="fa fa-file"></i> <span>Downloads</span></a>
      <ul>
    <li><a href="index.php?module=essentials&act=downloads">Unapproved Downloads</a></li>
    <li><a href="index.php?module=essentials&act=reports">Downloads Reports</a></li>
      </ul>
    </li>
{% if ips_user.isAdmin() %}
    <li class="submenu{% if active == 'navigation' %} active{% endif %}"> <a href="#"><i class="fa fa-bars"></i> <span>Navigation</span></a>
      <ul>
        <li><a href="index.php?module=settings&act=sidebar">Sidebar</a></li>
        <li><a href="index.php?module=settings&act=navigation">Navigation</a></li>
      </ul>
    </li>
    <li class="submenu{% if active == 'gallery' %} active{% endif %}"> <a href="#"><i class="fa fa-image"></i> <span>Gallery</span></a>
      <ul>
        <li><a href="index.php?module=settings&act=add_gallery">Add Gallery</a></li>
        <li><a href="index.php?module=settings&act=galleries">Gallery</a></li>
      </ul>
    </li>
    <li class="submenu{% if active == 'pages' %} active{% endif %}"> <a href="#"><i class="fa fa-file-text-o"></i> <span>Pages</span></a>
      <ul>
        <li><a href="index.php?module=settings&act=wizard">Page Wizard</a></li>
        <li><a href="index.php?module=settings&act=pages">View Pages</a></li>
        <li><a href="index.php?module=settings&act=errors">Error Pages</a></li>
      </ul>
    </li>
    <li class="submenu{% if active == 'downloads_config' %} active{% endif %}"> <a href="#"><i class="fa fa-cubes"></i> <span>Downloads Configuration</span></a>
      <ul>
        <li><a href="index.php?module=settings&act=sections">Download Sections</a></li>
        <li><a href="index.php?module=settings&act=categories">Download Categories</a></li>
        <li><a href="index.php?module=settings&act=versions">Download Versions</a></li>
      </ul>
    </li>
    <li class="submenu{% if active == 'optimisation' %} active{% endif %}"> <a href="#"><i class="fa fa-cloud"></i> <span>Optimisation</span></a>
      <ul>
        <li><a href="index.php?module=settings&act=toolbox">SQL Toolbox</a></li>
        <li><a href="index.php?module=settings&act=caches">Cache Management</a></li>
        <li><a href="index.php?module=settings&act=emails">Scheduled Emails</a></li>
        <li><a href="index.php?module=settings&act=mass_email">Mass Email</a></li>
      </ul>
    </li>
  </ul>
{% endif %}
</div>

<div id="content">

{% if no_crumbs is none %}
<div id="content-header">
{% if crumbs is not none %}
	<div id="breadcrumb">
	{% for crumb in crumbs %}
		<a href="{{ crumb['url'] }}" title="{{ crumb['description'] }}" class="tip-bottom"><i class="fa fa-{{ crumb['icon'] }}"></i> {{ crumb['title']|title }}</a>
	{% endfor %}
	</div>
{% endif %}
</div>
{% endif %}


On another note, looking back at the rendered page, I've also noticed there's another error as well. This section is doing the same thing- the username is showing next to the "welcome" with the space stripped:

<span class="text">Welcome {{ ips_user.name }}</span><b class="caret"></b></a>

Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2