netcarver Posted October 13, 2012 Share Posted October 13, 2012 Thanks to Ryan, I've managed to knock my next module into usable shape. The URL Shortener adds a link shortening feature to ProcessWire, so you can host your own short URL service from a PW site now. You can create as many bins for short links as you need & the module sets up an example bin when you install it. Each bin is a PW page that uses the LinkShortenerHome template. This template allows you to set the length of the shortened links that will reside in it. Shortened links are simply child pages that automatically use the LinkShortener template. As these links are normal PW pages you can manipulate them from the admin page tree just like any other page. Anytime you create a new short-link page in any of your bins, it will automatically be named with a random string that is not already in use in that bin. You get the chance to review this short string before adding the full URL and saving the page. Once the page is saved any visit to the short link's URL will be redirected to the full URL. 9 Link to comment Share on other sites More sharing options...
Nico Knoll Posted October 14, 2012 Share Posted October 14, 2012 Just for inspiration: My version of an URL-Shortener (kind of older code previously featured on my blog): require_once('database.class.php'); $db = new database('localhost', '', '', ''); $pass = '123'; $base_url = 'http://go.nico.is/'; function is_url($url) { if(!preg_match("#^http(s)?://[a-z0-9-_.]+\.[a-z]{2,4}#i", $url)) { return false; } else { return true; } } function url_encrypt($id) { $codeset = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; $base = strlen($codeset); $converted = ""; while ($id > 0) { $converted = substr($codeset, ($id % $base), 1) . $converted; $id = floor($id/$base); } return $converted; } function url_decrypt($converted) { $codeset = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; $base = strlen($codeset); $c = 0; for ($i = strlen($converted); $i; $i--) { $c += strpos($codeset, substr($converted, (-1 * ( $i - strlen($converted) )),1)) * pow($base,$i-1); } return $c; } if($_GET['do'] != '' && isset($_GET['url']) && $_GET['pass'] == $pass) { $url = rawurldecode($_GET['url']); if($_GET['do'] == 'remove') { if($db->delete('urls', '`url`=\''.$url.'\'')) { $note = 'true'; } else { $note = 'false'; } } elseif($_GET['do'] == 'stats') { $note = (($db->get_element('urls', 'stats', '`url`=\''.$url.'\'')) ? $db->get_element('urls', 'stats', '`url`=\''.$url.'\'') : '0'); } elseif($_GET['do'] == 'add') { if(!$db->get_element('urls', 'converted', '`url`=\''.$url.'\'')) { $id = $db->get_next_id('urls'); if($db->insert('urls', array('id' => $id, 'url' => $url, 'converted' => $converted, 'stats' => 0))) { $note = $base_url.url_encrypt($id); } else { $note = 'false'; } } else { $note = $base_url.$db->get_element('urls', 'converted', '`url`=\''.$url.'\''); } } } elseif(isset($_GET['converted'])) { $id = url_decrypt($_GET['converted']); $url = $db->get_element('urls', 'url', '`id`=\''.$id.'\''); $db->update('urls', array('stats' => ((int)$db->get_element('urls', 'stats', '`id`=\''.$id.'\'') + 1)), '`id`=\''.$id.'\''); header('HTTP/1.1 301 Moved Permanently'); header('Location: '.$url); exit; } if($note != '') { echo $note; } 1 Link to comment Share on other sites More sharing options...
netcarver Posted October 14, 2012 Author Share Posted October 14, 2012 Thanks for sharing that Nico. I like that you get to use upper-case characters in your shortlinks. 1 Link to comment Share on other sites More sharing options...
netcarver Posted October 14, 2012 Author Share Posted October 14, 2012 Just added some fine-grained control over how link names are generated if the containing bin is nearly full. This also bumps the version to 1.0.0. Link to comment Share on other sites More sharing options...
netcarver Posted October 14, 2012 Author Share Posted October 14, 2012 @Ryan, Is there any way to prevent PW from using all lowercase characters in a page's path? For this module, allowing uppercase characters in the shortened URL would really increase the bin sizes -- or allow shorter links for a given bin capacity. Currently I use a 31 character alphabet for generating the short links giving a maximum of 887,503,681 links using 6 characters. If I could add 19 visually distinct uppercase characters to the alphabet this would increase to 15,625,000,000. Link to comment Share on other sites More sharing options...
ryan Posted October 15, 2012 Share Posted October 15, 2012 I think it might be a fairly major change to the PW core to make it work with uppercase characters in URLs built on page names (though not 100% certain). But I think there are a lot of good reasons to normalize the case for URLs, so it's a change that might not be ideal for the larger system. Obviously those reasons don't apply to a URL shortener, and I can totally see the benefits for the URL shortener. The best way may be to have some kind of translation system in place where an underscore preceding a page name means the following character is uppercase, or something like that. Then your module's __construct() method could modify the value of $_GET['it'] before PW gets to it, i.e. if(strpos($_GET['it'], '/r/') === 0) { // if URL matches the format you are looking for // replace uppercase character with the lowercase version preceded by an underscore $_GET['it'] = strtolower(preg_replace('/([A-Z])/', '_$1', $_GET['it'])); } Btw, that $_GET['it'] is set by your htaccess file and it's where ProcessWire looks for the URL from Apache's RewriteEngine. It's nothing more than the currently requested URL. Another thing I want to mention is that there is no lowercase restriction with URL segments. So if you had your LinkShortenerHome.php template allowing URL segments, you could do something like this: if($input->urlSegment1) { $name = strtolower(preg_replace('/([A-Z])/', '_$1', $input->urlSegment1); $p = $page->child("name=$name"); if($p->id) $session->redirect($p->full_link); else throw new Wire404Exception(); } Also using URL segments, Another alternative is that you could just use your own custom text field to hold the short link (using upper and lower), and just let the page name take on the page's ID or something that wouldn't crossover with your short link names. Another idea, but maybe for a future version. If you wanted to handle short links right from your homepage rather than /r/ (which would further shorten the URL), you could hook in before Page::render when the $page->id is 1 and have your module check if there is an $input->urlSegment1 present. 1 Link to comment Share on other sites More sharing options...
netcarver Posted October 15, 2012 Author Share Posted October 15, 2012 Thanks for the reply Ryan, lots of good ideas in there. I agree that there is no real benefit for the request other than for my module so absolutely no need to worry about core mods. I did consider using URL segments for this module in the beginning but assumed, in ignorance, that enabling URL segments on the bin template would preclude me having the links as child pages and, as I definitely wanted to have the links as child pages, I chose not to explore that route. It's also good to know that URL segments can have uppercase characters. I'll probably look at moving over to a URL segment based solution for version 2 of this module. For now I've moved on to another module project. Link to comment Share on other sites More sharing options...
Marty Walker Posted October 16, 2012 Share Posted October 16, 2012 Hey Steve, Could the full_link field be changed to a Page type? I have a site with some really long urls and it'd be a cinch to create short url links with this. Regards Marty Link to comment Share on other sites More sharing options...
netcarver Posted October 16, 2012 Author Share Posted October 16, 2012 Hi Marty, I must admit I hadn't considered using the URL shortener for links to the same site so that's an interesting use-case for me. I've just tried this locally and it's not as simple as just changing the type of the full_link field as you then need to go on and setup some of its more advanced options and tell it where in the page tree it can reference pages etc. I will think about this some more and get back to you. Link to comment Share on other sites More sharing options...
apeisa Posted October 16, 2012 Share Posted October 16, 2012 Marty: one option for you could be a processRedirect module. Link to comment Share on other sites More sharing options...
Marty Walker Posted October 17, 2012 Share Posted October 17, 2012 @steve - Cheers - no rush at all. Kind of a side point: I have a YOURLS setup on a short domain that I use through my twitter account which gives me short links like: http://stlmv.in/4l. I'm not a fan of 3rd party url shorteners because there's no guarantee they'll bee around in the future. YOURLS just works. Perhaps I'll sponsor a module that can automatically create a shortened URL from your YOURLS install. The API is here if anyone is interested: http://yourls.org/#API. And other side point is that some of my web clients actually print newsletters (crazy, I know) and reference urls in them. Having shorter urls makes that easier. @antti: Oh yeah. I never thought to use it like that! Regards Marty 2 Link to comment Share on other sites More sharing options...
netcarver Posted October 17, 2012 Author Share Posted October 17, 2012 Thanks for the feedback folks. I just added a link shortening routine to the module so you can use its features programmatically. This addition bumps the version to 1.1.0 1 Link to comment Share on other sites More sharing options...
netcarver Posted October 17, 2012 Author Share Posted October 17, 2012 @Marty, Could you give this branch a try and let me know if it addresses your needs? It integrates with the ProcessRedirects module (if you have it installed) to automatically generate the short 'redirect_from' field for you. 1 Link to comment Share on other sites More sharing options...
Marty Walker Posted October 18, 2012 Share Posted October 18, 2012 @Steve, That's cool. Thanks! Link to comment Share on other sites More sharing options...
Crssp Posted October 24, 2012 Share Posted October 24, 2012 Intrigued by this module. Could anybody provide some screenshots of the interface in action? It would really help people decide to participate and install the URL Shortener, me thinks. thanks! Link to comment Share on other sites More sharing options...
netcarver Posted October 24, 2012 Author Share Posted October 24, 2012 Once installed, you'll see a new "Short Links" page under your site root. This is a bin for storing shortlinks - which are simply child pages. If you edit the "Short Links" page you'll see various parameters that control the automatic generation of link names. You should be able to leave these as-is with no problems (unless you need more than 27,000,000,000+ links in your bin!) The parameters, if curious, are... You can add as many bins for shortlinks as you like to your site, just create a new page using the template "LinkShortenerHome" and give it a relatively short page name.Anyway, let's add a short link now. From the page tree just click new next to the "Short Links" page. This creates a new shortlink page (uses the "LinkShortener" template) and automatically creates an unused, random, page name using the parameters we just looked at from the parent bin. Something like this... If you are not happy with the spelling of the generated shortlink (if it happens to be offensive in your native language for example) then you can change it now and hit the save button which takes us to... ..where we just type/paste in the target for the redirect this shortlink will make and then hit the publish button... ... and we can see the short link and a "Go!" link for testing it. That's about all there is to it except to say that it will help out the ProcessRedirects module if it is installed and you have configured the URL Shortener to help generate names for it.HTH. 4 Link to comment Share on other sites More sharing options...
Crssp Posted October 25, 2012 Share Posted October 25, 2012 Sweet thanks for going to the trouble NetCarver, I need to change my forum posts to notify me by email of replies. Almost didn't see this. Awesome job, thank you very much! -ty Link to comment Share on other sites More sharing options...
Crssp Posted October 26, 2012 Share Posted October 26, 2012 I have a quick question (sorry if it was covered I missed it). If I install Processwire in a directory on my site, let's just say a folder named 'i'. Would there be a way then that the path to the short link would not include the i in the path, but be made to just use the domain root? For example: Crssp.com/i/ujn3gi vs. Crssp.com/ujn3gi Not really a big deal, I'm thinking I will install Processwire in a folder, maybe I should even label the directory pw. Link to comment Share on other sites More sharing options...
netcarver Posted October 26, 2012 Author Share Posted October 26, 2012 Hmmm, probably not. However, here is an untested idea you could try if the only thing you want at your site root is the link shortener: set the template of the home page to LinkShortenerHome and use that as the bin for shortlinks. Link to comment Share on other sites More sharing options...
Crssp Posted October 26, 2012 Share Posted October 26, 2012 Have there been any thoughts on how or if this could be a publically available service? I don't think I would ever setup a URL for public use, with so many out there, but would it be doable. The idea now is it is more of a backend resource rather than frontend, does that sound right? Link to comment Share on other sites More sharing options...
Crssp Posted January 16, 2013 Share Posted January 16, 2013 Any new activity or use on this one. Just wondering if anyone if finding good uses, or is using the module. I got an install of LessN More running today, it has an easy interface. My only real use case, now is to shorten links in a Tweet, and it will be novel to have my own. On the backburner will be toying with the module. It would be useful to shorten the path for news articles on a new beta site, if I can ever manage to get a beta in the wild. Link to comment Share on other sites More sharing options...
xeo Posted September 13, 2013 Share Posted September 13, 2013 Hi,I am trying to get url's mode like www.site.com/artilce instead of www.site.com/parent/page/article. Can I achieve this with the plugin? So far I don't see such an opportunity. If not, can anyone advice how to do that if possible.. Link to comment Share on other sites More sharing options...
diogo Posted September 14, 2013 Share Posted September 14, 2013 @xeo, what you want to do is not the intention of the module. In PW the urls follow the structure of the tree, if you would shorten your urls like you are saying, there would be problems with pages overriding other with the same name. Imagine that you have a page called "About" in the root of the website (mydomain.com/about), and you would write an article with the title "About". You would have a problem because they would share the same url. If you want to have short urls for your articles, you can put them under a parent that is on the root, and has a short name (not short title) -home --about --contacts --articles (name: a) ---article1 ---article2 This way, your article1 url would be mydomain/a/article1 If you want to have an even shorter url for the articles (avoiding urls like: mydomain/a/my-new-article-with-a-very-very-veeeeeeeeery-long-title), you can create a system that accepts their IDs on the URL (mydomain/a/123): <?php // on top of the template file of the "articles" page ("/a/") // url segments have to be activated on this template if ($input->urlSegments) { // if there are segments in the URL $id = (int)$input->urlSegment1; // get the first segment ant turn it into an integer $myURL = $pages->get("/a/")->find("id={$id}")->first()->url; // get the url of the page with the id in the segment if ($myURL && !$input->urlSegment2) { // if page exists and there's not a second segment $session->redirect($myURL); // redirect to the correct page } else { throw new PageNotFoundException(); // if not, throw a 404 } } 4 Link to comment Share on other sites More sharing options...
xeo Posted September 15, 2013 Share Posted September 15, 2013 Thanx for the explanation. The problem is not about the length of urls as such. The reason I want those urls is that pages or articles can be moved from on parent page to another. For example, I have a parent page, say, Poetry and I publish a child page with American poets' stuff, then in the future I may want to divide poetry into American, European etc. poetry pages. Then I have to move my page to the American poetry which is child of the Poetry. In this case my url will be different. I want to avoid it. Link to comment Share on other sites More sharing options...
diogo Posted September 15, 2013 Share Posted September 15, 2013 You shouldn't be changing the parents of pages like that. Use page fields to categorize the articles and you will be fine http://processwire.com/talk/topic/3579-tutorial-approaches-to-categorising-site-content/ 1 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now