Automatically add auto-generated short URLs to your sNews CMS
This is my first sNews CMS mod/hack to be made public in quite some time, I hope someone finds it useful. This modification will add rel="shortlink" & rel="shorturl" tags to the head of your published items.
What do I mean by published items? Basically all your articles & "pages", not the default category/home page views or hard-coded sNews pages (contact, sitemap, etc). We don't really need/want shortlinks to ever-changing pages (home, category views, etc) anyways.
Why?
Unless you've been living under a rock, you've no doubt used or at least heard of Twitter, and the 140 character limitation for Twitter entries. So when posting URLs, people have relied on URL shortening services, such as bit.ly to reduce the long SEO-Friendly URLs into as few characters as possible. With this mod you can skip using bit.ly or others services for publishing shortlinks on your own site, for any published items (articles/pages). Another big plus about using these short urls is they never change, as they are based on the unique article IDs from the database. Helps prevent linkrot and eases redirect management.
Adding the code
We will be editing 2 pages for this one, index.php & snews.php. So make a back-up of these files now & let's get started. Now open snews.php and add this function to the very bottom of the file, just above the closing PHP tag;
function redirectShortUrl() {
$url = trim($_GET['category'],"/"); // fetch & trim the category
if (ctype_digit($url) && strlen($url) < '7') { // url is a short number, let's process it
$url = clean($url);
$query = 'SELECT a.id AS aid,a.seftitle AS asef, c.seftitle AS subsef,x.seftitle AS csef
FROM '._PRE.'articles'.' AS a
LEFT OUTER JOIN '._PRE.'categories'.' as c
ON category = c.id
LEFT OUTER JOIN '._PRE.'categories'.' as x
ON c.subcat = x.id AND x.published =\'YES\'
WHERE a.published = \'1\' AND a.visible = \'YES\' AND a.id ='.$url;
$result = mysql_query($query);
$num_rows = mysql_num_rows($result);
$row = mysql_fetch_row($result);
if ($num_rows == '0') {
$error = true;
} else {
if (empty($row[2]) && empty($row[3])) { // found a matching page
$goto = '/'.$row[1];
} elseif (!empty($row[2]) && empty($row[3])) { // found a matching article w/cat
$goto = '/'.$row[2].'/'.$row[1];
} elseif (!empty($row[2]) && !empty($row[3])) { // found a matching article w/cat & subcat
$goto = '/'.$row[3].'/'.$row[2].'/'.$row[1];
}
}
if ($error != true) {
header ('HTTP/1.1 301 Moved Permanently');
header ('Location: '.$goto.'');
exit;
}
} // not a number, pass to snews as-is
}
That function will sniff out the shortlinks and check for them in the database, perform the redirect if necessary, or simply pass the url on sNews. Now within the function title(), and the following code below the meta keywords output;
// BEGIN SHORTLINK
$query = 'SELECT id FROM '._PRE.'articles WHERE title = \''.$_TITLE.'\'';
$result = mysql_query($query);
$numrows = mysql_num_rows($result);
if ($numrows == '1') {
$row = mysql_fetch_row($result);
echo '<link rel="shortlink" type="text/html" href="'._SITE.$row[0].'" />
<link rel="shorturl" type="text/html" href="'._SITE.$row[0].'" />';
}
// END SHORTLINK
That little bit of code checks for a matching title and inserts the shortlinks if there is a match. Now lastly, open index.php, and add the redirectShortUrl fucntion just below the snews.php include;
include('snews.php');
redirectShortUrl();
That's it! Now upload your modified files and you should see the shortlinks on your articles & pages now. Clicking a valid shortlink should redirect you to the SEO Friendly URL on your site.
Extending
So now you've got short URLs for your pages & articles... what do you do with them? Well obviously you can post the shortlinks by hand in your Twitter/SMS/Facebook posts, but I've also created a simple script that will generate a shortlink for 3rd party services. I use TwitterFeed to automatically post all my articles to Twitter. How? Simply sign-up, add your rss-articles feed to TwitterFeed & link your account to Twitter. Now, to use your own sNews site for short URLs, we have to do a little magic, OK, not magic, we have to convert the URL back to a shortlink for TwitterFeed.
This is how we will do this. Download shortenurl.txt, save it as shortenurl.php, edit the database variables and upload to your server. Now, after you have linked your Twitter, Facebook, etc. accounts to TwitterFeed, go to the TwitterFeed dashboard and do the following;
- click the edit button to edit your feed.
- click the "Advanced Settings" option.
- on the "Shorten link through" dropdown, select "custom"
- in the "Custom endpoint" box, type "http://site.com/shortenurl.php?url=%@"
Obviously change site.com above to whatever your domain is. Now whenever you post a new article to your RSS feed, TwitterFeed will pick it up, post it to Twitter and use your own short URL as the linkback.
Caveats & Gotchas
There are 2 major considerations that might cause problems for users;
- This script uses the unique IDs from the articles table in the database to generate the shortlinks. This works well, I have allowed up to 6 digits in the code, so unless you've created 1 million articles/pages, you should be fine. However, if you started the MySQL auto-increment at a large number, this could be a problem, but there are work-arounds for that.
- Because this script uses the unique table IDs, if you have an article or page with a name of just digits, under 1 million (ex. mysite.com/24312), it will conflict. Do not use this script as it is, or consider adding a letter to your article/page names.
Wrap up
Well, if all goes according to plan (this is my first real post using this new shortlink system), then I should see this article posted to twitter soon, with a linkback containing my domains shortlink. As always, any questions or comments, feel free to leave a comment.
Comments
RSS Comments Feed
Matt
http://static.mdj.us/media/images/shortlinks/twitter-shortened-url.jpg
:)
KuJoe
Philippe
glad to see ya back.
That Mod is a great idea but,
your guinea pig couldn't make it work (as usual.
Is there a syntax error there :
$query = 'SELECT id FROM '._PRE.'articles WHERE title = ''.$_TITLE.''';
Or did I make a typo somewhere?
Matt
Both queries need them;
$query = 'SELECT a.id AS aid,a.seftitle AS asef, c.seftitle AS subsef,x.seftitle AS csef FROM '._PRE.'articles'.' AS a LEFT OUTER JOIN '._PRE.'categories'.' as c ON category = c.id LEFT OUTER JOIN '._PRE.'categories'.' as x ON c.subcat = x.id AND x.published =\'YES\' WHERE a.published = \'1\' AND a.visible = \'YES\' AND a.id ='.$url; $query = 'SELECT id FROM '._PRE.'articles WHERE title = \''.$_TITLE.'\'';Philippe
Now, what is this "function count_mysql_query()" you got? Is it a PHP built-in function?
Matt
Philippe
Okey...
I'm gonna test it tomorrow "on air".
See you.
Matt
BTW, if you want the function, add this to your snews.php;
function count_mysql_query($sql) { global $query_count; $query_count++; return mysql_query($sql); }Then do a find & replace all the mysql_query calls with count_mysql_query, that will count them all.
Lastly, add this to the bottom of your index.php file;
Add then it will show you how many queries you've used within the current page.
Philippe
Just a little question:
why do you place those 2 "link rel=" in the head?
Matt
http://microformats.org/wiki/rel-shortlink
Philippe
I use it for the permalink:
See http://normandie-web.hiseo.fr/36 (right col)...
I'll try the twitter service one day.
Thanks a lot Matt.
What else about sNews do you have under your hat?
Matt
I've looked at a few ideas people have had, but I'm so busy at work these days I really don't have much time to devote to hacking around.
David
I have a problem with this. Where must I see those links? I've done whats written. But its really wierd :)
Nothing happens!
Cheers
Dai
Matt
The links should be in the head of the HTML document you're viewing, on "pages" & "articles"
--Matt
David
//TITLE function title() { global $categorySEF, $_DESCR, $_KEYW, $_TITLE, $_NAME, $_XNAME; echo ''; $title = $_TITLE ? $_TITLE.' - ' : ''; $title .= $_NAME ? $_NAME.' - ' : ''; $title .= $_XNAME ? $_XNAME.' - ' : ''; if (check_category($categorySEF) == true && $categorySEF != 'administration' && $categorySEF) $title .= l($categorySEF).' - '; $title .= s('website_title'); echo ' '.$title.' '; // BEGIN SHORTLINK $query = 'SELECT id FROM '._PRE.'articles WHERE title = ''.$_TITLE.'''; $result = mysql_query($query); $numrows = mysql_num_rows($result); if ($numrows == '1') { $row = mysql_fetch_row($result); echo ' '; } // END SHORTLINK if (_ADMIN) { echo ''; include('js/admin.js'); echo ''; } }Thanks Matt!
Matt
if ($numrows == '1') { $row = mysql_fetch_row($result); echo '<link rel="shortlink" type="text/html" href="'._SITE.$row[0].'" /> <link rel="shorturl" type="text/html" href="'._SITE.$row[0].'" />'; }David
Nothing happes and Ive copied the code below:
';
Matt
David
found something out. When I'm on the correct post.
For example: http://www.ryuu-dev.net/uncategorized/testek
And when I click CTRL+U I see the shorturl...but why its not displayed under the Title of the post?
Or this script works like this? If it works like this, how would I echo the url below the title of the post?
I thinks something here must be changed:
echo '
';
But dunno what =)
Cheers,
Dai
Matt
That's the way it's supposed to work. The shortcut url isn't currently echo'd under the title of the post.
I'll have a look at what can be done to make that happen & repost here later.
Matt
Place that under the post title in the articles() function. I've added it at the bottom of my articles.
Fred K
Oh, if you have time on your hands and feel up to it, maybe you could suggest a solution to my question here: http://snewscms.com/forum/index.php?topic=10278.0
I'm planning on working it into a couple of new themes but I'm a bit stuck (to no-one's surprise ... :D)
Cheers
Fred K
function redirectShortUrl() if (empty($row[2]) && empty($row[3])) { // found a matching page $goto = $row[1].'/'; } elseif (!empty($row[2]) && empty($row[3])) { // found a matching article w/cat $goto = $row[2].'/'.$row[1].'/'; } elseif (!empty($row[2]) && !empty($row[3])) { // found a matching article w/cat & subcat $goto = $row[3].'/'.$row[2].'/'.$row[1].'/'; } } if ($error != true) { header ('HTTP/1.1 301 Moved Permanently'); header ('Location: '._SITE.$goto); exit;In other words, I had to remove the slash preceding $goto for each $row[] as well as adding ._SITE. to the header('Location...') line. This makes the redirect work. Note though that this test was only done locally, I haven't added the TwitterFeed bits yet.
Makes sense?
Matt
Philippe HTML5 autres geek
Yes! Fred is right. His fix makes the job locally and online.
Kudos.
27 comments, page 1 of 2 [ 1 2 » ]