Textpattern Forum

You are not logged in. Register | Login | Help

#21 2010-12-04 20:25:20

jsoo
Developer
From: NC, USA
Registered: 2004-11-15
Posts: 1,730
Website

Re: Article thumbnail image from YouTube/Flickr code found in Body

Good job. I was just previewing this post when you posted your latest, so here’s another way the code could be arranged:

// Check article body for embedded flickr and/or youtube content
	$img_pattern = '#^(.*)<img src=(\'|")(.+flickr\.com.+)\2#sU';
	$youtube_pattern = '#^(.*)<object.+youtube\.com/v/([\w-]+).+</object>#sU';

// Check for embedded content; if found calculate position from start of article
	$first_bodyimg = preg_match($img_pattern, $thisarticle['body'], $img_match) ? 
		strlen($img_match[1]) : null;
	$first_youtube = preg_match($youtube_pattern, $thisarticle['body'], $youtube_match) ?
		strlen($youtube_match[1]) : null;

// Find first instance and resize it
	$img_src = null;
	if ( $first_youtube and ( is_null($first_bodyimg) or $first_youtube < $first_bodyimg ) )
		$img_src = resize('http://i.ytimg.com/vi/'.$youtube_match[2].'/0.jpg',array('w'=>200));
	elseif ( $first_bodyimg and ( is_null($first_youtube) or $first_bodyimg < $first_youtube ) )
		$img_src = resize($img_match[3], array("w"=>200));

// If we have an image src, output the image as the contents of a link to the current article
	if ( $img_src )
		echo permlink(array('class'=>'article-thumb'), '<img src="'.$img_src.'" alt="" />');

Among other things this avoids repeating the permlink() code, including the concatenated strings for building the img tag. Not a big deal, but if you wanted to add, say, a title attribute to the img tag, there’s only one place you need to edit.

Note that I’ve added a class attribute to permlink(). When calling a Txp tag directly as a PHP function, the first argument is always the tag attribute array.

I also made a few tweaks to the regex patterns. I added the U option to both patterns. This makes the * and + quantifiers non-greedy by default, so I can do away with the ? modifiers. I added flickr\.com to the flickr pattern to only match flickr images. I removed the http./ from the youtube pattern because it doesn’t really add anything useful. I changed the [A-Za-z0-9\-_] character class to [\w-], which is identical. I escaped the literal dot characters (youtube\.com), because an unescaped dot in regex matches any character.


Txp tags not doing what you expect? Learn to use a tag trace. And the Tag Reference.

Offline

#22 2011-04-07 20:22:00

photonomad
Member
Registered: 2005-09-10
Posts: 260
Website

Re: Article thumbnail image from YouTube/Flickr code found in Body

Hello! I have another php/regex question. It appears that YouTube recently changed the format of the code for embedding videos. Instead of an <object>, they are now using an <iframe> and the video id comes after embed/ in the src.

Example:

<iframe title="YouTube video player" width="480" height="390" src="http://www.youtube.com/embed/9JA0QVP3JwQ" frameborder="0" allowfullscreen></iframe>

I need help understanding how to modify the script so that it will look for the first object or iframe with youtube code.

Also, jsoo, I decided that I do not want to limit the script for just Flickr images. I tried to modify your changes (so that it would find any img tags) in the revised code (in your post above) and I wasn’t able to get it to work correctly.

I have been using the following:

<txp:php> 
// Regex patterns to search for embedded image and youtube content
	$img_pattern = '#^(.*?)<img src=(\'|")(.+?)\2#s';
	$youtube_pattern = '#^(.*?)<object[^>]+>.+?http://www.youtube.com/v/([A-Za-z0-9\-_]+).+?</object>#s';

// Check for embedded content; if found calculate position from start of article $first_bodyimg = preg_match($img_pattern, $thisarticle[‘body’], $img_match) ? strlen($img_match1) : null; $first_youtube = preg_match($youtube_pattern, $thisarticle[‘body’], $youtube_match) ? strlen($youtube_match1) : null;

// Resize and output thumbnail for first embedded content if ( $first_youtube and ( is_null($first_bodyimg) or $first_youtube < $first_bodyimg ) ) echo permlink(array(), “<img src=\”.”.resize(‘http://i.ytimg.com/vi/’.$youtube_match2.’/0.jpg’,array(‘w’=>150)).”\” />”); elseif ( $first_bodyimg and ( is_null($first_youtube) or $first_bodyimg < $first_youtube ) ) echo permlink(array(), “<img src=\”.”.resize($img_match3, array(“w”=>150)).”\” />”);
</txp:php>

Offline

#23 2011-04-08 13:46:49

jsoo
Developer
From: NC, USA
Registered: 2004-11-15
Posts: 1,730
Website

Re: Article thumbnail image from YouTube/Flickr code found in Body

photonomad wrote:

$img_pattern = '#^(.*?)<img src=(\'|")(.+?)\2#s';

Should still be OK for matching the first img tag. This might improve it, in case of tags in which src is not the first attribute:

$img_pattern = '#^(.*?)<img\s[^>]*src=(\'|")(.+?)\2#s';

photonomad wrote:

$youtube_pattern = '#^(.*?)<object[^>]+>.+?http://www.youtube.com/v/([A-Za-z0-9\-_]+).+?</object>#s';

Untested, but this might work if you need to test for either object or iframe:

$youtube_pattern = '#^(.*?)<(object|iframe)[^>]+>.+?http://www.youtube.com/(?:v|embed)/([A-Za-z0-9\-_]+).+?</\2>#s';

With this latter pattern there is an extra matching subpattern (the (object|iframe) subpattern), so you would need to change this in the $youtube_match index for the ID (i.e., use $youtube_match[3]).


Txp tags not doing what you expect? Learn to use a tag trace. And the Tag Reference.

Offline

#24 2011-04-09 19:32:11

photonomad
Member
Registered: 2005-09-10
Posts: 260
Website

Re: Article thumbnail image from YouTube/Flickr code found in Body

Hi jsoo, Thanks for your help!

I’ve tested it and the new image pattern works great and finds the src no matter what order it appears in the <img> tag!

The youtube regex pattern works fine too, but I’m getting stuck with the $youtube_match index. You are correct, $youtube_match[2] does not work. The resize script runs, but doesn’t return an actual image url.

When I switch $youtube_match[2] to $youtube_match[3], it works, but does not return the first occurrence. If there is only one youtube (object and/or iframe) in the article body, then no image is returned. When I put two youtube (objects and/or iframes) in the same article, the second video’s image is returned. If I put an image in between two youtubes, the second youtube is returned and the still image is ignored. However, if there is a youtube first and then an image and no other youtubes, then the still image is returned. I am stumped as to how to fix it. Any ideas?

Thanks so much!

Offline

#25 2011-04-09 20:30:45

jsoo
Developer
From: NC, USA
Registered: 2004-11-15
Posts: 1,730
Website

Re: Article thumbnail image from YouTube/Flickr code found in Body

Right. I was trying to avoid needing a third pattern, but I overlooked the fact that iframe is all one element. Probably best to add in a third pattern.

$img_pattern = '#^(.*?)<img\s[^>]*src=(\'|")(.+?)\2#s';
$iframe_pattern = '#^(.*?)<iframe[^>]+http://www.youtube.com/embed/([A-Za-z0-9\-_]+)#s';
$object_pattern = '#^(.*?)<object.+?>.+?http://www.youtube.com/v/([A-Za-z0-9\-_]+).+?</object>#s';

Determining which comes first is trickier. There’s probably a cleaner way to do this, but this should work:

if ( $first_img )
{
	if ( $first_iframe )
	{
		if ( $first_iframe < $first_img )
			$first_img = null;
		else
			$first_iframe = null;
	}
	if ( $first_object )
	{
		if ( $first_object < $first_img )
			$first_img = null;
		else
			$first_object = null;
	}
}
if ( $first_iframe && $first_object )
{
	if ( $first_iframe < $first_object )
		$first_object = null;
	else
		$first_iframe = null;
}

Then something like:

if ( $first_img ) echo ...
if ($first_iframe) echo ...
if ($first_object) echo ...

Txp tags not doing what you expect? Learn to use a tag trace. And the Tag Reference.

Offline

#26 2012-07-30 02:35:31

photonomad
Member
Registered: 2005-09-10
Posts: 260
Website

Re: Article thumbnail image from YouTube/Flickr code found in Body

Hello! I am revisiting this code and was wondering how I can make the results into a variable? Something like: <txp:variable name=“bodyimg” /> I want to be to test if there are any embedded images in the article body, then output different code in my article form if there aren’t.

Scratch the above. I have bigger issues now because I’m using hak_tinymce to insert images into the body of articles. If the appearance of an image is edited when inserting an image into an article, the style tag shows up between <img and src=”, like this: <img style=“float:left;” src=”. The regex code for finding images doesn’t work (see posts in this thread above for sample code of regex pattern). I’m starting to wonder if I need to use something other than regex to find the first image or video? Or, is there some regex that will find the src regardless of the attribute order? I’ve searched the web for regex patterns, but can’t find any that work here. I know it isn’t the ideal situation for regex, but I’m not sure how else to proceed. Anyone have advice? Thanks.

Last edited by photonomad (2012-07-30 04:49:24)

Offline

#27 2012-07-30 14:32:42

photonomad
Member
Registered: 2005-09-10
Posts: 260
Website

Re: Article thumbnail image from YouTube/Flickr code found in Body

I found a solution. :) Inspired by this post on Stackoverflow, I gave phpQuery a try. The code below works great for finding the first image src in an article body and storing it as a variable. (I am postponing the youtube test for now).

Call at top of page: <txp:php>require 'phpQuery-onefile.php';</txp:php>

<txp:php>
global $variable;
$texthtml = $thisarticle['body']; 
$pq = phpQuery::newDocumentHTML($texthtml);
$img = $pq->find('img:first');
$src = $img->attr('src');
$variable['bodyimg'] = $src;
</txp:php>

<txp:if_variable name="bodyimg" value="">nope<txp:else /><txp:variable name="bodyimg" /></txp:if_variable>

My next challenge is to introduce the logic of finding the first youtube video id or first img src, whichever comes first in the article body.

Offline

#28 2012-07-31 21:01:59

etc
Plugin Author
Registered: 2010-11-11
Posts: 1,268
Website

Re: Article thumbnail image from YouTube/Flickr code found in Body

You could give a try to etc_query:

<txp:variable name= "bodyimg" value='<txp:etc_query data="{?body}" query="//img[1]@src?" />' />

etc_[ query | search | pagination | date | tree | url ]

Offline

#29 2012-08-01 17:16:41

photonomad
Member
Registered: 2005-09-10
Posts: 260
Website

Re: Article thumbnail image from YouTube/Flickr code found in Body

Thanks, etc! I’m trying out your plugin now and there is a problem somewhere (using the txp:variable code you included in the post above). I’m not sure how to fix it:

Tag error: <txp:etc_query data=”{?body}” query=”//img1@src?” /> -> Warning: DOMXPath::evaluate() [domxpath.evaluate]: Invalid expression on line 194
textpattern/lib/txplib_misc.php(653) : eval()’d code:194 DOMXPath->evaluate()
textpattern/publish.php:1188 etc_query()
textpattern/publish.php:1100 processTags()
textpattern/lib/txplib_misc.php:1053 parse()
textpattern/publish.php:1188 splat()
textpattern/publish.php:1100 processTags()
textpattern/publish.php:847 parse()
textpattern/publish.php:964 doArticles()
textpattern/publish.php:954 parseArticles()
textpattern/publish.php:1188 article_custom()

Offline

#30 2012-08-01 19:03:19

etc
Plugin Author
Registered: 2010-11-11
Posts: 1,268
Website

Re: Article thumbnail image from YouTube/Flickr code found in Body

Yes, sorry, should be <txp:etc_query data="{?body}" query="//img[1]/@src">{?}</txp:etc_query>.

Edit: or <txp:etc_query data="{?body}" query="string(//img[1]/@src)" />

Last edited by etc (2012-08-01 19:09:03)


etc_[ query | search | pagination | date | tree | url ]

Offline

Board footer

Powered by FluxBB