Jump to content

Recommended Posts

Posted

Hi guys,

I'm trying to modify the configuration of TinyMCE. Note: I am NOT modifying any code in the module at this stage, I am only using the Admin interface.

According to the TinyMCE website, the standard "valid elements" string is as follows:

@[id|class|style|title|dir<ltr?rtl|lang|xml::lang|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup],a[rel|rev|charset|hreflang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur],strong/b,em/i,strike,u,#p,-ol[type|compact],-ul[type|compact],-li,br,img[longdesc|usemap|src|border|alt=|title|hspace|vspace|width|height|align],-sub,-sup,-blockquote,-table[border=0|cellspacing|cellpadding|width|frame|rules|height|align|summary|bgcolor|background|bordercolor],-tr[rowspan|width|height|align|valign|bgcolor|background|bordercolor],tbody,thead,tfoot,#td[colspan|rowspan|width|height|align|valign|bgcolor|background|bordercolor|scope],#th[colspan|rowspan|width|height|align|valign|scope],caption,-div,-span,-code,-pre,address,-h1,-h2,-h3,-h4,-h5,-h6,hr[size|noshade],-font[face|size|color],dd,dl,dt,cite,abbr,acronym,del[datetime|cite],ins[datetime|cite],object[classid|width|height|codebase|*],param[name|value|_value],embed[type|width|height|src|*],script[src|type],map[name],area[shape|coords|href|alt|target],bdo,button,col[align|char|charoff|span|valign|width],colgroup[align|char|charoff|span|valign|width],dfn,fieldset,form[action|accept|accept-charset|enctype|method],input[accept|alt|checked|disabled|maxlength|name|readonly|size|src|type|value],kbd,label[for],legend,noscript,optgroup[label|disabled],option[disabled|label|selected|value],q[cite],samp,select[disabled|multiple|name|size],small,textarea[cols|rows|disabled|name|readonly],tt,var,big

I trust the content person 100% and want them to have full flexibility in what they are doing.

Specifically, I want to be able to embed Youtube videos using the old embedded style.

Now, it doesn't seem to matter what I do; TinyMCE is mangling my code.

I want this to be embedded (using the HTML editor in TinyMCE):

<object width="420" height="315"><param name="movie" value="https://www.youtube.com/v/by8oyJztzwo?version=3&hl=en_US"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="https://www.youtube.com/v/by8oyJztzwo?version=3&hl=en_US" type="application/x-shockwave-flash" width="420" height="315" allowscriptaccess="always" allowfullscreen="true"></embed></object>

When I look at the code I get this:

<object width="420" height="315" data="https://www.youtube.com/v/by8oyJztzwo?version=3&hl=en_US" type="application/x-shockwave-flash"><param name="data" value="https://www.youtube.com/v/by8oyJztzwo?version=3&hl=en_US" /><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="https://www.youtube.com/v/by8oyJztzwo?version=3&hl=en_US" /><param name="allowfullscreen" value="true" /></object></p>

I notice the TinyMCE version is a bit out of date: 3.3.9.2. On the TinyMCE website the latest patches on the 3.3 branch is 3.3.9.4, and v3.4 7 is out too.

I also tried only adding the object, param and embed codes as given here: http://processwire.com/talk/index.php?topic=486.0 - but that didn't help either.

Any ideas?

Posted

Does your embed code work on front end? It seems that tinyMCE adds something, but was there something required missing?

Posted

It does actually work, however the code has been mangled/rewritten.

The <embed> tag is completely missing although it's explicitly allowed, and the URL is inserted into the <object> tag although it shouldn't be there.

Posted

That's odd how TinyMCE is modifying the code and adding a data attribute to the object tag, among other things. I've looked around a bit, but don't have an answer as to why it's doing that. Clearly it seems to think it's a 'feature' based on the intentional modifications it's making, but not a very desirable feature.

I would suggest making making your own tag for your videos, something like this in it's own paragraph in your TinyMCE editor:

youtube:url

i.e.

youtube:https://www.youtube.com/v/by8oyJztzwo?version=3&hl=en_US 

Then in your output code, perform a replace to insert the object/embed codes:

<?php

if(strpos($page->body, '<p>youtube:') !== false) {
    $replacement = '<object width="420" height="315"><param name="movie" value="$1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="$1" type="application/x-shockwave-flash" width="420" height="315" allowscriptaccess="always" allowfullscreen="true"></embed></object>';
    $page->body = preg_replace('{^<p>youtube:\s*(http://[^\s<]+)\s*</p>\s*$}m', $replacement, $page->body); 
}

// now your $page->body ready to output somewhere
Posted

I've tried this tag approach with absolutely no luck. Here's the tag I'm using:

youtube:https://www.youtube.com/watch?v=rEKDj1OOkhI

...and my code. Is it my URL that's the issue?

Regards

Martin

<?
if(strpos($page->body, '<p>youtube:') !== false) {
    $replacement = '<object width="420" height="315"><param name="movie" value="$1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="$1" type="application/x-shockwave-flash" width="420" height="315" allowscriptaccess="always" allowfullscreen="true"></embed></object>';
    $page->body = preg_replace('{^<p>youtube:\s*(http://[^\s<]+)\s*</p>\s*$}m', $replacement, $page->body); 
}
echo $page->body;
Posted

Just realized that TinyMCE doesn't exactly maintain paragraph-to-line relationships very well, so there was a good chance that previous regexp wasn't going to work. Also realized there really isn't any reason for us to have a "youtube:" tag, when instead the "https://www.youtube.com" could be the tag we look for. Let me know if this version works?

if(strpos($page->body, '<p>https://www.youtube.com') !== false) {
    $replacement = '<object width="420" height="315"><param name="movie" value="$1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="$1" type="application/x-shockwave-flash" width="420" height="315" allowscriptaccess="always" allowfullscreen="true"></embed></object>';
    $page->body = preg_replace('{<p>(http://[^\s<]+)\s*</p>}', $replacement, $page->body); 
}
echo $page->body;

Bow you can just past the youtube URL in it's own paragraph (skip the "youtube:") and that's all you need to do, i.e.

https://www.youtube.com/watch?v=rEKDj1OOkhI
Posted

Thank Ryan. I reckon it's nearly there.

I think Google needs a different url:

value="https://www.youtube.com/v/OVb6auDGo7E"

If I use your code it gives me:

value="https://www.youtube.com/watch?v=OVb6auDGo7E"

I understand regex but not how it works. Any help re-wrangling this would be great.

Regards

Marty

Posted

The iframe code (preferable) that Youtube likes contains this style url: https://www.youtube.com/embed/rEKDj1OOkhI

<iframe width="480" height="360" src="https://www.youtube.com/embed/rEKDj1OOkhI?rel=0" frameborder="0" allowfullscreen></iframe>

But the easiest URL for a client to copy in is from the browser url area which would be:

So I need a way to go from:

https://www.youtube.com/watch?v=rEKDj1OOkhI

to

<iframe width="480" height="360" src="https://www.youtube.com/embed/rEKDj1OOkhI?rel=0" frameborder="0" allowfullscreen></iframe>

Regards

Marty

Posted
$replacement = '<iframe width="480" height="360" src="https://www.youtube.com/embed/$1" frameborder="0" allowfullscreen></iframe>';
$page->body = preg_replace('#<p>.*https://www.youtube.com/watch\?v=(\w{11}).*</p>#is', $replacement, $page->body); 

echo $page->body;
Posted

You're welcome. Sorry, I got something wrong. I updated the code. The $body variable was wrong it should be $page->body =

But just tried, it should work, what do you mean by entire body field?

Posted

Everything in the body field where I'm putting the YouTube link is getting completely replaced by the iframe code. eg:

text text text text

youtube link

text text text text

<?php
if(strpos($page->body, '<p>https://www.youtube.com') !== false) {
$replacement = '<iframe width="480" height="360" src="https://www.youtube.com/embed/$1" frameborder="0" allowfullscreen></iframe>';
$page->body = preg_replace('#<p>.*https://www.youtube.com/watch\?v=(\w{11}).*</p>#is', $replacement, $page->body); 
Posted

But for me, everything else stays the same...

The regex assumes the link is in a <p></p> ...

You could remove the first line... too "if(strpos($page->body, '<p>https://www.youtube.com') !== false) {"

Ahh, now... I could reproduce, if there other <p><p> after or before is the problem. I'm not a master at regex, but I'll try to fix

post-1337-132614280988_thumb.png

Posted

I think this should be ok, can you also test?

$page->body = preg_replace('#<p>.?https://www.youtube.com/watch\?v=(\w{11}).*?</p>#is', $replacement, $page->body); 
Posted

Well I still got a problem with <p></p> before the <p>http://www.you... they also get included, but don't know why.

I'm trying to get it work with optinal whitespace before and after the url... as soon as you have a whitespace in front of http:// the previous <p>'s also get replaced.

Posted

This should work.

$page->body = preg_replace("#<p>https://www.youtube.com/watch\?v=([a-zA-z0-9\-\_]{11}).*?</p>#is", $replacement, $page->body); 

But if I put a whitespace before the http like  "<p>  http:// ... </p>" I can't get it to work with what's comming from $page->body:

$page->body = preg_replace("#<p>\s*?https://www.youtube.com/watch\?v=([a-zA-z0-9\-\_]{11}).*?</p>#is", $replacement, $page->body); 

If I test it with a string it works with the whitespace...

$str = "<p>Paragraph before video</p><p>  https://www.youtube.com/watch?v=9e-57gmA67o&feature=feedrec_grec_index</p>";

$replacement = '<iframe width="480" height="360" src="https://www.youtube.com/embed/$1" frameborder="0" allowfullscreen></iframe>';
$page->body = preg_replace("#<p>\s*?https://www.youtube.com/watch\?v=([a-zA-z0-9\-\_]{11}).*?</p>#is", $replacement, $str); 
echo $page->body;

So aslong as you don't have a whitepsace before url it works. Maybe someone else know what's going on.

Posted
But if I put a whitespace before the http like  "<p>  http:// ... </p>" I can't get it to work with what's comming from $page->body:

$page->body = preg_replace("#<p>\s*?https://www.youtube.com/watch\?v=([a-zA-z0-9\-\_]{11}).*?</p>#is", $replacement, $page->body);

I think the problem might be the first question mark in there (in bold). That doesn't add anything since the '*' is already making the whitespace optional. Adding a '?' technically converts it to a 'lazy' (regex term) match of optional whitespace, and it's unnecessary at best, or breaking the regex at worst (I'm not sure which).

I'd modify that regex to this (below), grabbing the whole 'v' variable, whatever is in it, and then matching anything after it until it hits a closing paragraph tag.  Also I took out the 's' option at the end so that it doesn't attempt to match one item across multiple lines. I don't think it matters much to the replacement, but I figure it's better to leave stuff out that doesn't need to be there in case it's faster.

$page->body = preg_replace("#<p>\s*https://www.youtube.com/watch\?v=([^\s&<]+).*?</p>#i", $replacement, $str); 
Posted

The regex isn't wrong I just played around with it trying to get it to work (but you're right it isn't neccessary), it works well like this for optional whitespace between <p> and http, but somehow the whitespace is different in the <p>   http://</p> that gets returned from the $page->body from TinyMCE for some reason I can't figure out.

I tested this for hours, and It drove me nuts literaly. If I test it with a simple /\s+/  and replace every whitespace, for example with a string "SPACE" , all whitespaces get's replaced except the one in the <p> http://... </p>. So I can't really figure out what's up with this.

---

jsut tested your regex and it doesn' work for the same reason as mine doesn't with whitespace in front of http...

Posted

This is very interesting topic. I would love to see textformatter, which would take many of the most popular services (youtube, vimeo, slideshare etc) and do something similar than here.

Posted

There must be some unusual UTF-8 whitespace in there or ascii 160s or something like that. Adding the 'u' (UTF-8) modifier to the end should fix it:

$page->body = preg_replace("#<p>\s*https://www.youtube.com/watch\?v=([^\s&<]+).*?</p>#iu", $replacement, $page->body);
Posted

I tested them al already, \s \040 " " ... if I do an encode it doesn't help.

I know am testing and searching since hours and can't find anything. But there's definately TinyMCE where the problem comes from (again). It seems a whitespace at the beginning of a line, TMCE enters some weird unknown invisible char, second whitespace then is a normal one. If I go into DB to look at what's in table, it just shows a normal space " ", and if I'm retyping it in DB with a space, suddenly it works...  ???

Posted

Try it with the 'u' modifier at the end. Just tested here and it does work. That enables "\s*" to match whatever those odd whitespace chars are.  I was also able to duplicate that \s won't match without the 'u' modifier.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...