Textpattern CMS support forum
You are not logged in. Register | Login | Help
- Topics: Active | Unanswered
Article thumbnail image from YouTube/Flickr code found in Body
I have a client who really just wants to add images and videos to her blog articles from Flickr and YouTube by using the copy/paste embed code that both sites offer. It is simple and easy for my client because all her photos and videos are hosted on these two popular sites.
My task: I want to include thumbnail images next to the article excerpts in article lists on the site. To do this, I’ve compiled two separate pieces of php code.
This block of code checks for the first image in the article body and returns the thumbnail of the image permlinked to the article (I’ve written the code here specifically for Flickr images):
<txp:php>
$u = preg_match('@<img src=([^<]+)/>@',$thisarticle['body'], $matches);
if($u)
{
$surl = $GLOBALS['prefs']['siteurl'];
$sec = $GLOBALS['thisarticle']['section'];
$tperm = $GLOBALS['thisarticle']['url_title'];
$theurl = $matches[1];
$var = explode(" ",$theurl);
$thisimg = trim($var[0], "\"");
$imgbase = substr($thisimg,0,-4);
echo "<a href=\"http://".$surl."/".$sec."/".$tperm."\" /><img src=\"".$imgbase."_t.jpg\" class=\"left\" /></a>";
}
</txp:php>
This block of code checks for the first YouTube object and returns the thumbnail image for the video permlinked to the article:
<txp:php>
$u = preg_match('#<object[^>]+>.+?http://www.youtube.com/v/([A-Za-z0-9\-_]+).+?</object>#s', $thisarticle['body'], $matches);
if($u)
{
$surl = $GLOBALS['prefs']['siteurl'];
$sec = $GLOBALS['thisarticle']['section'];
$tperm = $GLOBALS['thisarticle']['url_title'];
$theid = $matches[1];
$var = explode(" ",$theid);
echo "<a href=\"http://".$surl."/".$sec."/".$tperm."\" /><img src=\"http://i.ytimg.com/vi/".$theid."/default.jpg\" class=\"left\" /></a>";
}
</txp:php>
Here is my question: I only want to display one article thumbnail for each article. The article’s thumbnail should be for the image or video that comes first in the article’s body (if either exist). If an article’s body contains both an image (or images) and a youtube video (or videos), how do you write the php so that it will return the thumbnail for whichever comes first?
I am not a programmer, but I think this might make for a nice plugin. If anyone has an interest in making it into a little plugin let me know! By the way… in my article form, I first test to see if there is a Textpattern article image specified — if there is, then it gets to be the article thumbnail image and the above code is skipped.
Last edited by photonomad (2010-12-01 20:02:52)
Offline
Re: Article thumbnail image from YouTube/Flickr code found in Body
photonomad wrote:
If an article’s body contains both an image (or images) and a youtube video (or videos), how do you write the php so that it will return the thumbnail for whichever comes first?
Combine both into a single if/else block:
<txp:php>
if (preg_match('@<img src=([^<]+)/>@',$thisarticle['body'], $matches))
{
$surl = $GLOBALS['prefs']['siteurl'];
$sec = $GLOBALS['thisarticle']['section'];
$tperm = $GLOBALS['thisarticle']['url_title'];
$theurl = $matches[1];
$var = explode(" ",$theurl);
$thisimg = trim($var[0], "\"");
$imgbase = substr($thisimg,0,-4);
echo "<a href=\"http://".$surl."/".$sec."/".$tperm."\" /><img src=\"".$imgbase."_t.jpg\" class=\"left\" /></a>";
}
elseif (preg_match('#<object[^>]+>.+?http://www.youtube.com/v/([A-Za-z0-9\-_]+).+?</object>#s', $thisarticle['body'], $matches))
{
$surl = $GLOBALS['prefs']['siteurl'];
$sec = $GLOBALS['thisarticle']['section'];
$tperm = $GLOBALS['thisarticle']['url_title'];
$theid = $matches[1];
$var = explode(" ",$theid);
echo "<a href=\"http://".$surl."/".$sec."/".$tperm."\" /><img src=\"http://i.ytimg.com/vi/.".$theid."/default.jpg\" class=\"left\" /></a>";
}
</txp:php>
There’s some cleanup you could do to make the code more compact and portable (e.g., not dependent on a particular URL scheme), but if you’re happy with it as is this should work.
Code is topiary
Offline
Re: Article thumbnail image from YouTube/Flickr code found in Body
Hi jsoo, Thanks! Your code/suggestion is definitely very helpful!
The only thing that I still need to figure out is how get the script to find what comes first (still image or video) and generate the thumbnail based on that. For example, occasionally a video might be placed toward the beginning of an article (before any still images). If so, I’d like the thumbnail to come from the video, rather than a still image that might be placed further down in the article’s body. I’m guessing that there is some way to test for this, but I am staring at the PHP manual and can’t seem to wrap my head around how to test for what comes first (if both are true).
Thanks!
p.s. – I found an error in my original code that made it’s way into your code too. At the end of the YouTube part, there is a period after vi/ that shouldn’t be there. It breaks the image url.
Offline
Re: Article thumbnail image from YouTube/Flickr code found in Body
photonomad wrote:
The only thing that I still need to figure out is how get the script to find what comes first (still image or video) and generate the thumbnail based on that.
OK, sorry, you were clear on that in your OP and I glossed over it. This isn’t necessarily very efficient, but is probably reasonable (but I haven’t tested it):
<txp:php>
if (preg_match('@^(.*?)<img src=([^<]+)/>@',$thisarticle['body'], $matches))
{
$first_flickr = strlen($matches[1]);
$surl = $GLOBALS['prefs']['siteurl'];
$sec = $GLOBALS['thisarticle']['section'];
$tperm = $GLOBALS['thisarticle']['url_title'];
$theurl = $matches[2];
$var = explode(" ",$theurl);
$thisimg = trim($var[0], "\"");
$imgbase = substr($thisimg,0,-4);
$flickr = "<a href=\"http://".$surl."/".$sec."/".$tperm."\" /><img src=\"".$imgbase."_t.jpg\" class=\"left\" /></a>";
}
if (preg_match('#^(.*?)<object[^>]+>.+?http://www.youtube.com/v/([A-Za-z0-9\-_]+).+?</object>#s', $thisarticle['body'], $matches))
{
$first_youtube = strlen($matches[1]); // Edit: corrected (see post below)
$surl = $GLOBALS['prefs']['siteurl'];
$sec = $GLOBALS['thisarticle']['section'];
$tperm = $GLOBALS['thisarticle']['url_title'];
$theid = $matches[2];
$var = explode(" ",$theid);
$youtube = "<a href=\"http://".$surl."/".$sec."/".$tperm."\" /><img src=\"http://i.ytimg.com/vi/".$theid."/default.jpg\" class=\"left\" /></a>";
}
if ( isset($flickr) and isset($youtube) )
echo $first_flickr < $first_youtube ? $flickr : $youtube;
elseif (isset($flickr)) // Edit: see below
echo $flickr;
elseif (isset($youtube)) // Edit: see below
echo $youtube;
</txp:php>
Last edited by jsoo (2010-12-02 00:56:38)
Code is topiary
Offline
Re: Article thumbnail image from YouTube/Flickr code found in Body
thanks!
Unfortunately, it is throwing an error:
Parse error: syntax error, unexpected ‘;’ in /public_html/textpattern/publish/taghandlers.php(3127) : eval()’d code on line 16
I wish I knew if that meant anything in particular. :) I did switch the order of the image vs. video in the body of my test article (just to see if it pertained to one scenario or the other) and it didn’t seem to matter… threw the same error either way. hmm…
Offline
Re: Article thumbnail image from YouTube/Flickr code found in Body
This line:
$first_youtube = strlen($matches[1];
needs to be this:
$first_youtube = strlen($matches[1]);
Code is topiary
Offline
Re: Article thumbnail image from YouTube/Flickr code found in Body
Jeff, you ROCK! It works!
I did find two other little errors that popped up subsequently. I just needed to add closing parentheses to elseif (isset($flickr) and elseif (isset($youtube)
The final working code is here:
<txp:php>
if (preg_match('@^(.*?)<img src=([^<]+)/>@',$thisarticle['body'], $matches))
{
$first_flickr = strlen($matches[1]);
$surl = $GLOBALS['prefs']['siteurl'];
$sec = $GLOBALS['thisarticle']['section'];
$tperm = $GLOBALS['thisarticle']['url_title'];
$theurl = $matches[2];
$var = explode(" ",$theurl);
$thisimg = trim($var[0], "\"");
$imgbase = substr($thisimg,0,-4);
$flickr = "<a href=\"http://".$surl."/".$sec."/".$tperm."\" /><img src=\"".$imgbase."_t.jpg\" class=\"left\" /></a>";
}
if (preg_match('#^(.*?)<object[^>]+>.+?http://www.youtube.com/v/([A-Za-z0-9\-_]+).+?</object>#s', $thisarticle['body'], $matches))
{
$first_youtube = strlen($matches[1]);
$surl = $GLOBALS['prefs']['siteurl'];
$sec = $GLOBALS['thisarticle']['section'];
$tperm = $GLOBALS['thisarticle']['url_title'];
$theid = $matches[2];
$var = explode(" ",$theid);
$youtube = "<a href=\"http://".$surl."/".$sec."/".$tperm."\" /><img src=\"http://i.ytimg.com/vi/".$theid."/default.jpg\" class=\"left\" /></a>";
}
if ( isset($flickr) and isset($youtube) )
echo $first_flickr < $first_youtube ? $flickr : $youtube;
elseif (isset($flickr))
echo $flickr;
elseif (isset($youtube))
echo $youtube;
</txp:php>
I am interested in your thoughts about making it more compact and portable. I guess if it were to become a plugin, those features would be desirable. I do have a version that will resize the full-size flickr image down to my choice of thumbnail size ( using this code ). This is nice because Flickr’s thumbnail size (t) is really tiny.
Does anyone else out there think this would be nice to have as a plugin? I’m not sure if I’m qualified enough in the coding dept. to actually make a plugin, but it might be fun to try… :)
Offline
Re: Article thumbnail image from YouTube/Flickr code found in Body
photonomad wrote:
I did find two other little errors that popped up subsequently. I just needed to add closing parentheses to elseif (isset($flickr) and elseif (isset($youtube)
Right, good catch! More thoughts on your other questions later …
Code is topiary
Offline
Re: Article thumbnail image from YouTube/Flickr code found in Body
photonomad wrote:
I am interested in your thoughts about making it more compact and portable. I guess if it were to become a plugin, those features would be desirable.
I’d look at it the other way around: is this a good candidate for a plugin? If so, you’d almost certainly want to clean up the code and make it more generalized and portable. If not, and this is going to remain a custom solution for a particular site, then refining the code isn’t really called for unless you want more or different functionality, or anticipate future changes such that cleaner code would make for easier maintenance, for you or another admin.
Is this a good plugin candidate? It’s quite a specific problem: scan an article body for the first instance of embedded flickr or youtube content and return the appropriate thumbnail. I’m pretty sure there are existing plugins to handle simple embedding of one or the other, so it really is a question of this particular function. I see this as too specific to merit a public plugin release. There’s nothing wrong with releasing this kind of plugin, but when you actually get users they invariably each need something a little different; to meet their requests you may find that there’s no way to generalize the problem to meet their needs without making your own use of it overly complicated.
If you were to refine the code, the main benefit would be from using built-in Txp functions to generate the permlink URL. This would have the beneficial side effect of getting rid of some of those variable assignments. And there’s further cleanup you could do along the same lines.
Code is topiary
Offline
Re: Article thumbnail image from YouTube/Flickr code found in Body
Jeff, thanks for sharing your thoughts. I agree that this is tailored for pretty specific use and probably won’t be in high demand. In addition, I don’t think I’m prepared to author a plugin. I suppose anyone else with a similar need might find this post helpful and glean from it what they want. Thanks so much for your help with the code!
I do have one last question, out of curiosity…. what is the Edit: jsoo figured out the issue and the script below has been edited!^(.*?)
that you put in front of the <img
and <object
tags in the preg_match lines? I assume it has something to do with regex. I actually had to take it out in order to get the resize script in the version below to work.
Here is the code for users who want to resize-on-the-fly full size images down to a smaller custom size without having to use the small pre-determined size of thumbnails from Flickr or YouTube. With this version, still images in the article body do not have to be from Flickr. However, videos do have to be from YouTube for the code to work. Also, this script by Wes Edling is required. NOTE: you MUST edit his code for YouTube thumbs to work (otherwise, since they all have the same 0.jpg file name, the first one will get cached and no other YouTube thumbs will be processed). Refer to the comment made by Tony C on this page. for specifics on what needs editing.
<txp:php>
if (preg_match('@^([\s\S]*?)<img src=([^<]+)/>@',$thisarticle['body'], $matches)) // Edit: see below
{
$first_flickr = strlen($matches[1]);
$surl = $GLOBALS['prefs']['siteurl'];
$sec = $GLOBALS['thisarticle']['section'];
$tperm = $GLOBALS['thisarticle']['url_title'];
$theurl = $matches[2];
$var = explode(" ",$theurl);
$thisimg = trim($var[0],"\"");
$imgsized = resize("$thisimg",array("w"=>225));
$flickr = "<a href=\"http://".$surl."/".$sec."/".$tperm."\" class=\"article-thumb\" /><img src=\".".$imgsized."\" /></a>";
}
if (preg_match('#^([\s\S]*?)<object[^>]+>.+?http://www.youtube.com/v/([A-Za-z0-9\-_]+).+?</object>#', $thisarticle['body'], $matches)) // Edit: see below
{
$first_youtube = strlen($matches[1]);
$surl = $GLOBALS['prefs']['siteurl'];
$sec = $GLOBALS['thisarticle']['section'];
$tperm = $GLOBALS['thisarticle']['url_title'];
$theid = $matches[2];
$imgsized = resize('http://i.ytimg.com/vi/'.$theid.'/0.jpg',array('w'=>200));
$youtube = "<a href=\"http://".$surl."/".$sec."/".$tperm."\" class=\"article-thumb\" /><img src=\".".$imgsized."\" /></a>";
}
if ( isset($flickr) and isset($youtube) )
echo $first_flickr < $first_youtube ? $flickr : $youtube;
elseif (isset($flickr))
echo $flickr;
elseif (isset($youtube))
echo $youtube;
</txp:php>
Any size can be specified for the thumbnail by editing ("w"=>200)
in both places in the code above on the lines that begin with $imgsized =
Last edited by photonomad (2010-12-03 16:43:01)
Offline
Re: Article thumbnail image from YouTube/Flickr code found in Body
photonomad wrote:
what is the
^(.*?)
that you put in front of the<img
and<object
tags in the preg_match lines? I assume it has something to do with regex. I actually had to take it out in order to get the resize script in the version below to work.
^(.*?)
as used here means take everything that precedes the first matching instance of the rest of the pattern, and store it as a subpattern in the $matches
variable. So it’s a necessary part of my algorithm for determining which comes first, the flickr or youtube content. Without the ^(.*?)
the code should no longer work correctly. It looks as though the resize()
function depends only on having a correct image URL, so there’s no reason you can’t leave in the ^(.*?)
, so long as the rest of the code is correct.
Code is topiary
Offline
Re: Article thumbnail image from YouTube/Flickr code found in Body
However, probably the reason it started failing is because ^(.*?)
excludes line breaks — my mistake. (Would still work in the first paragraph, which is probably why it seemed to work correctly at first.) Should be ^([\s\S]*?)
instead.
Code is topiary
Offline