Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

General Questions /

General questions about getting started with SilverStripe that don't fit in any of the categories above.

Moderators: martimiz, Sean, Ed, biapar, Willr, Ingo, swaiba

Editor strips out Javascript tags


Go to End


23 Posts   10104 Views

Avatar
fnds

Community Member, 2 Posts

25 February 2010 at 11:16am

I'm facing the same issue. I'm considering migrating a web site to SilveStripe but this could be a show stopper.

Sometimes the HTML just disappears. I had to retry pasting it multiple times in the HTML box until it decided to take it. Even then it stripped some code.

Stripping javascript is not a security issue. It's a bug. A CMS should allow authorized users to add whatever they want to any page, even bad code.

A security issue would be allowing a unauthorized or anonymous user to do the same.

Are there any plans to fix this *bug*?

I installed and started using SilverStripe Today and things seemed to be going well until now. I hope this is not a sign of how buggy SilverStripe is. It seems a really good concept.

Thanks.

--fnds

Avatar
MateuszU

Community Member, 89 Posts

25 February 2010 at 12:00pm

Edited: 25/02/2010 12:01pm

Welcome! :)
Like Hamish wrote above, JS is part of the site logic and should go into JS files, or should be added via Requirements::customScript calls. We want to keep clean separation between the logic and the data layers. What JS code do you have that would justify injecting it into the database?

mat.

Avatar
Greg1

Community Member, 28 Posts

25 February 2010 at 12:26pm

It is certainly not a bug that you can't enter JS (or various other code) into the editor. It is very dangerous (even for internal editors) and poor programming practice. This should be the default behaviour.

But... there should be a way that you can allow it so that people can accept the risks to run their site like this.

Avatar
Hamish

Community Member, 712 Posts

25 February 2010 at 1:07pm

Just a side note: an HTML Editor should edit HTML, not JavaScript. Why people insist on adding JS via it, I don't understand. If your content editors really must add bespoke JS (an idea that gives me nightmares) there are better ways:

1. Add an "upload a script" to include on the page function
2. Add a plain text field where optional JS can be entered
3. Create a set of 'safe' scripts as separate dataobjects that can optionally be associated with a page

The common rebuttal is that people think they need inline JavaScript. Well if you think you need inline JavaScript, you need to learn more about JavaScript.

Avatar
fnds

Community Member, 2 Posts

27 February 2010 at 11:17am

Thank you for all the feedback. You are right that I need to learn more about JS.

I was trying to migrate pages to SilverStripe and thought the HTML editor would be the best way to do it.

Is there any documentation on the best way to migrate complex pages, including JavaScript to SilverStripe.

Would you please elaborate more on the three options that you proposed? Can you point me to a place where I can learn more about how to implement it?

1. Add an "upload a script" to include on the page function
2. Add a plain text field where optional JS can be entered
3. Create a set of 'safe' scripts as separate dataobjects that can optionally be associated with a page

Thanks.

--fnds

Avatar
Hamish

Community Member, 712 Posts

27 February 2010 at 12:12pm

Sure thing. None of the following code is tested, but it should help.

1. Add an "upload a script" to include on the page function

First you need to modify your page class. You could either create a new page type ("PageWithJavaScript" maybe) or add this to your normal page class if you want it available for all of them.

First, modify your page model so it has:

static $has_one = array(
	'JavaScriptFile' => 'File'
);

then add an upload field to the getCMSfields:

function getCMSFields() {
	$fields = parent::getCMSFields();
	$fields->addFieldToTab('Root.Main.Content', new FileIFrameField('JavaScriptFile', 'JavaScript Behaviours'));
	return $fields;
}

Finally, in your page controller init function:

function init() {
	parent::init();
	if($this->JavaScriptFile()->exists())
		Requirements::javascript($this->JavaScriptFile()->getRelativePath());
}

2. Add a plain text field where optional JS can be entered

Just add a text column to your database and a text area field in the CMS and use Requirement::customScript instead, in the init function.

3. Create a set of 'safe' scripts as separate dataobjects...

Requires a bit more work, but you should be able to do this if you've done the tutorials and you understand what is happening above.

You'll need to understand how to attach events to objects without using inline tags. For example, instead of:

<a id='someLink' onclick='return someComplexFunction()' href='/'>Link</a>

you should be doing stuff like:

<a id='someLink' href='/'>Link</a>
...
<script type='text/javascript'>
document.getElementById('someLink').onclick = function() {
    // etc
}
</script>

Hope this helps.

Avatar
bummzack

Community Member, 904 Posts

27 February 2010 at 1:18pm

Excellent writeup Hamish. This should be a sticky.
Regarding point 3. You could also use jQuery, which adds a lot of possibilities to add additional features via JavaScript. It also allows you to bind custom actions to css selectors, so you can apply a style in the CMS content editor, and the jQuery script will add the required functionality to all the elements matching a given selector.
A simple example: Make a link load its content via AJAX. I the content editor you would put something like:

<a href="linkto/mypage" class="ajaxlink">Click here</a>

Then your jQuery script (which would ideally be in a separate file that you include like a regular js file):

;(function($) {
	$(function(){
		$('a.ajaxlink').click(function(evt){
			evt.preventDefault();
			$('#Content').load($(this).attr('href') + ' #Content');
		});
	});
})(jQuery);

This will add AJAX loading functionality to all links that have the class ajaxlink which is much cleaner and more powerful than adding the code inline. It will also degrade nicely if people don't have JavaScript enabled.
That's a good rule of thumb anyway: Build your site so that it works nicely without JavaScript. Then add the JavaScript functionality as a layer on top of that (and believe me, you can create two totally different user experiences without ruining it for anybody).

Avatar
Hamish

Community Member, 712 Posts

28 February 2010 at 6:22pm

Thanks, might post it to ssbits.

Yeah didn't want to go into too much detail with the JS, but jQuery is a good option. In fact I recently posted something similar to your ajax code - a plugin to cache AJAX calls in 150 characters.

The downside is quite often the people using it have no idea what is going on under the hood, so I would still never allow non-developer users to include arbitrary code.