Fork me on GitHub

Help getting shorturls for pnEncyclopedia 0.2.0  Bottom

Go to page 1 - 2 [+1]:

  • Hi,

    the module in question can be found here http://pnencyclopedia.sourceforge.net/

    and here is my question:
    i thought i was pretty good at getting shorturls on my site, i even managed to get the pnphpbb shorturls but now i'm stuck. i created my htaccess for pnEncyclopedia as follows:

    Code

    # Rules for Encyclopedia
    RewriteRule ^medTerms\.html$ /index.php?module=pnEncyclopedia [L,NC,NS]
    RewriteRule ^medTerms-([^-]+)\.html$ /index.php?module=pnEncyclopedia&func=$1 [L,NC,NS]
    RewriteRule ^medTerms-Vol-([^-]+)\.html$ /index.php?module=pnEncyclopedia&func=display_vol&vid=$1 [L,NC,NS]
    RewriteRule ^medTerms-Letter-([^-]+)-([^-]+)\.html$ /index.php?module=pnEncyclopedia&func=search_letter&get_letter=$1&vid=$2 [L,NC,NS]
    RewriteRule ^medTerms-([^-]+)-([^-]+)\.html$ /index.php?module=pnEncyclopedia&func=display_term&id=$1&vid=$2 [L,NC,NS]


    and my functions.php looks like this:

    Code

    $prefix . 'index.php\?module=pnEncyclopedia"|',
    $prefix . 'index.php\?module=pnEncyclopedia&(?:amp;)?func=([\w\d\.\:\_\/]+)"|',
    $prefix . 'index.php\?module=pnEncyclopedia&(?:amp;)?func=display_term&(?:amp;)?id=([\w\d\.\:\_\/]+)&(?:amp;)?vid=([\w\d\.\:\_\/]+)"|',


    Code

    '"medTerms.html"',
    '"medTerms-.html"',
    '"medTerms--.html"',


    everything works, i've tested it by adding the direct link on my browser, and when i add the "index.php\?module=pnEncyclopedia" in my main menu block, the short urls work and it loads...however when i go to the encyclopedia itself, it doesnt' convert any of the links. i'm wondering if it has to do with a API compliant issue...

    because all the links in the pnuser.php file are

    Code

    (pnModURL('pnEncyclopedia', 'user', 'display_vol', array('vid'=> $vid)));



    anyone know anything about this and i how i can implement short urls for the new pnEncyclopedia 0.2.0
  • As far as I remember, pnEncyclopedia use the new API, as your snippet from pnuser.php indicate. ShortURLs function doesn't work on the New modules themselves, just the links to them. Same as for PostCalendar. Only way is to modify pnEncyclopedia, to detect the shortURL variable is set, and output that instead, wherever you have pnModURL.
  • I knew it had something to do with that and thanks so much for helping me. now is there anyone who can guide me in how to remove pnModURLs and replace them with something to make this short URL work. for me short URL is more important than 'new API' issues. please anyone. thanks so much in advance.
  • msandersen

    Only way is to modify pnCalendar, to detect the shortURL variable is set, and output that instead, wherever you have pnModURL.

    Actually, there are other ways to make short URL's work with pnAPI compliant modules. Unfortunately, all those ways require hacking of core PN files...
  • ColdRolledSteel

    msandersen

    Only way is to modify pnCalendar, to detect the shortURL variable is set, and output that instead, wherever you have pnModURL.

    Actually, there are other ways to make short URL's work with pnAPI compliant modules. Unfortunately, all those ways require hacking of core PN files...
    that's fine like i said, could someone please show me? i really need my sites to have shorturls. my sites are not meant for community portal websites and so, any hack i do, as long as it benefits my shorturls is key for me. thank you :)
  • Hmm... Let me go see if I have it somewhere under the layers of dust over my old software projects...
  • You realize that it will make life very difficult when it's time to upgrade PostNuke? It also doesn't sound like it will be a simple process, so I hope you have some PHP programing experiance.

    --
    Home Page | Find on Facebook | Follow on Twitter
  • Much as hacking the core isn't desirable, I thought I'd have a go at modifying the pnModURL() function in includes/pnMod.php. This is only a specific solution for pnEncyclopedia, though, but could be extended or made more generic.
    I've only tested it on a small test install, so some more extensive testing may be in order. Also, I've used the extension .phtml to distinguish them from regular HTML pages. As always when trying core modifications, back up the original, and replace the pnModURL function in includes/pnMod.php from line 646 (pn0.726) with the following 2 functions. Only the top section of pnModURL has been modified, down to "// The arguments", the rest is the same.
    I've enabled the short urls at the top of the pnModURL function with $ShortURLs=true

    Code

    function pnShortURLs($modname, $type, $func, $args) {
      if ($modname=='pnEncyclopedia') {
    if (($func=="search_letter" or $func=="create") && empty($args)) return false;  //  Don't convert form fields
        $url="medTerms";
        $vars="";
            foreach ($args as $k=>$v) {
                if (is_array($v)) {
                    foreach($v as $l=>$w) {
                        if ($w!="") {      
                          $vars.="-$k[$l]$w"; // -[\w-]+\[[\d\w]+\]\d{1,3}
                        }
                    }
                } elseif($v!="") {
                    if ($k=="get_letter") $k="get";
            $vars .= "-$k$v"; // -[\w-]+\d{1,3}
                }
            }
        if ($func=="display_term") {
                $func="term";
        }
        elseif($func=="display_vol"){
            $func="Vol";
        }
        elseif($func=="search_letter"){
            $func="letter";
        }
        $url.=($type!="user"?"-$type":"").($func!="main"?"-$func":"").$vars;
        return $url.".phtml";
      }
    // elseif($modname=='Postcalendar')  {
        // Postcalendar or some other module ShortURLs
      //}
      return false;
    }
    /**
     * generate a module function URL
     * @param modname - registered name of module
     * @param type - type of function
     * @param func - module function
     * @param args - array of arguments to put on the URL
     * @returns string
     * @return absolute URL for call
     */

    function pnModURL($modname, $type='user', $func='main', $args=array()) {
        $ShortURLs=true; // "true" turn on - "false" turn off

        if (empty($modname))  return false;
    if (phpversion() < "4.1.0") {
        global $HTTP_SERVER_VARS;
        if (isset($HTTP_SERVER_VARS) and !empty($HTTP_SERVER_VARS))
          $_SERVER = $HTTP_SERVER_VARS;
    }
        // Hostname
    $host = empty($_SERVER['HTTP_HOST']) ? getenv('HTTP_HOST') : $_SERVER['HTTP_HOST'];
    if (empty($host))   return false;

    if (empty($GLOBALS['SiteRoot'])) {
        $nukeurl = pnGetBaseURI();  
        global $SiteRoot;
        $SiteRoot = "http".($_SERVER['HTTPS']=="on"?"s":"")."://".(empty($_SERVER['HTTP_HOST'])?getenv('HTTP_HOST'):$_SERVER['HTTP_HOST']).$nukeurl."/";
    }

    if ($ShortURLs) {
        $url=pnShortURLs($modname, $type, $func, $args);
        if ($url!==false) return $SiteRoot.$url;
    }

        // The arguments
        $urlargs[] = "module=$modname";
        if ((!empty($type)) && ($type != 'user')) {
            $urlargs[] = "type=$type";
        }
        if ((!empty($func)) && ($func != 'main')) {
            $urlargs[] = "func=$func";
        }
        $urlargs = join('&', $urlargs);
        $url = "index.php?$urlargs";


        // <rabbitt> added array check on args
        // April 11, 2003
        if (!is_array($args)) {
            return false;
        } else {
            foreach ($args as $k=>$v) {
                if (is_array($v)) {
                    foreach($v as $l=>$w) {
                        $url .= "&$k" . "[$l]=$w";
                    }
                } else {
                    $url .= "&$k=$v";
                }
            }
        }

        // The URL
        return pnGetBaseURL() . $url;
    }


    The .htaccess file:

    Code

    # Don't process if not .phtml files
    # To have other rules after, use [Skip]: RewriteRule ^.*$ - [skip=12]
    RewriteCond %{REQUEST_URI} !^.*\.phtml$
    RewriteRule ^.*$ - [PT]

    # Rules for pnEncyclopedia
    RewriteRule ^medTerms\.phtml$ /index.php?module=pnEncyclopedia [L,NC,NS]
    RewriteRule ^medTerms-admin\.phtml$ /index.php?module=pnEncyclopedia&type=admin [L,NC,NS]
    RewriteRule ^medTerms-admin-([^-\.]+)\.phtml$ /index.php?module=pnEncyclopedia&type=admin&func=$1 [L,NC,NS]
    RewriteRule ^medTerms-admin-([^-\.]+)-([a-zA-Z]+)([1-9]+)\.phtml$ /index.php?module=pnEncyclopedia&type=admin&func=$1&$2=$3 [L,NC,NS]
    RewriteRule ^medTerms-term-([a-zA-Z]+)([1-9]+)\.phtml$ /index.php?module=pnEncyclopedia&func=display_term&$1=$2 [L,NC,NS]
    RewriteRule ^medTerms-term-([a-zA-Z]+)([1-9]+)-([a-zA-Z]+)([1-9]+)\.phtml$ /index.php?module=pnEncyclopedia&func=display_term&$1=$2&$3=$4 [L,NC,NS]
    RewriteRule ^medTerms-Vol-([a-zA-Z]+)([1-9]+)\.phtml$ /index.php?module=pnEncyclopedia&func=display_vol&$1=$2 [L,NC,NS]
    RewriteRule ^medTerms-letter-get([a-zA-Z]+)-([a-zA-Z]+)([1-9]+)\.phtml$ /index.php?module=pnEncyclopedia&func=search_letter&get_letter=$1&$2=$3 [L,NC,NS]
    RewriteRule ^medTerms-letter-([a-zA-Z]+)([1-9]+)\.phtml$ /index.php?module=pnEncyclopedia&func=search_letter&$1=$2 [L,NC,NS]
    RewriteRule ^medTerms-([^-\.]+)\.phtml$ /index.php?module=pnEncyclopedia&func=$1 [L,NC,NS]
    RewriteRule ^medTerms-([^-\.]+)-([a-zA-Z]+)([1-9]+)\.phtml$ /index.php?module=pnEncyclopedia&func=$1&$2=$3 [L,NC,NS]
    RewriteRule ^medTerms-([^-])-([^0-9\.\-])\.phtml$ /index.php?module=pnEncyclopedia&func=$1&type=$2 [L,NC,NS]
  • wow thank you so much...it worked till i tried accessing one of the volume. i changed the .phtml to .html both in the PHP file and the htaccess file...but i get an error

    Error: Can't get data from database.

    this is probably due to some kind of configuration on the PHP file you gave me...when you did the test, did you add some test terms to see if it all worked?

    its a great effort and i really appreciate it. please let me know.
  • I installed it yesterday, added 2 volumes and 3 terms, then after writing the functions tweaked the RewriteRules until all the links I tried worked, including Search and modify forms and Admin links, adding and deleting terms. I'm not overly familiar with pnEncyclopedia, and my limited test volumes could easily miss something, but I have no database errors here.

    Before you changed the extensions, did you test it first? Moreover, did you change the pnEncyclopedia files? I'm using a clean install of v0.2. It's easy to overlook something when converting something. Both the last line in pnShortURLs return $URL.".phtml"; and all the htaccess file rules has to be changed, as you mention. But then, your error is a PN database error, not a 403 Not Found.
    I've uploaded the file I worked on (pn0.726), along with a modified Menu block (includes/blocks/menu.php) for the hell of it.
    pnEncyclopedia-ShortURLs.zip
    About the Menu block: I modded a few modules and blocks a while back before it was announced pn0.8 would have shortURLs. I thought it might be around the corner, but the corner has been a little further away than I thought. I'm a little myopic :)
    Anyway, I included the Menu block (pn0.726) in the above so you can remove the pnEncylopedia RegEx rules completely from the functions.php file if you like. Better for performance. Although it should be pointed out it was designed to go with my ShortURLs function, which you can see in one of my converted themes, eg Helius, which use the .phtml format, and use the variable $ShortURLs set in the theme.php file. It may be slightly off-topic, but basically, it has this at the top

    Code

    global $ShortURLs;
    if (!defined($ShortURLs))  $ShortURLs==false;

    and down the bottom in the addMenuStyledUrl function, does things like this:

    Code

    if ($GLOBALS['ShortURLs']) {
                $url = $url[0].(isset($url[1]) ? '-'.$url[1]:'').'.phtml';
            } else {
                $url = 'modules.php?op=modload&amp;name='.$url[0].'&amp;file='.((isset($url[1])) ? $url[1]:'index');
            }
    You could search-and-replace ".phtml" for ".html" if you like, as long as the RewriteRules are replaced too.

    Incidentally, I've edited the above post a little to tweak performance by adding an IF statement around the generation of the site base URL. In the original pnModURL function, it calls the pnGetBaseURL() function, which in turn calls pnGetBaseURI(), every time it is run for each and every link. Even for a small test install of pnEncyclopedia like mine, there are quite a few links using the pnModURL function. Now, I think it safe to assume that the website won't jump around on the server in between each link being rendered, so the Base URL won't change. The pnGetBaseURL call is replaced with a one-line condensed version of the same.

    Code

    if (empty($GLOBALS['SiteRoot'])) {
        $nukeurl = pnGetBaseURI();  
        global $SiteRoot;
        $SiteRoot = "http".($_SERVER['HTTPS']=="on"?"s":"")."://".(empty($_SERVER['HTTP_HOST'])?getenv('HTTP_HOST'):$_SERVER['HTTP_HOST']).$nukeurl."/";
    }
  • The most likely reason for your database error is you htaccess file. The order is important. If you've plonkled them at the end of an existing htaccess file, it is not unlikely the shortURLs have been intercepted by another rule, especially if you didn't remove the old pnEncyclopedia rules.
    So, try temporarily removing the existing htaccess file and replace it with the one I provided above and see if it works that way.
    First, though, you'd have to modify it to .html extension (quick search-and-replace in any decent text editor; I didn't have time to modify), and also remember to remove or edit the first RewriteCondition:

    Code

    # To have other rules not for .html after, use [Skip=12] instead
    RewriteCond %{REQUEST_URI} !^.*\.html$
    # RewriteRule ^.*$ - [skip=12]
    RewriteRule ^.*$ - [PT]
    It ensures only files with the right extension are processed, there are a lot of image links, CSS links, and Javascript links etc in PN.
    If that works, put the rules at the top of you list of RewriteRules., and remove relevant RegEx rules in the functions.php file.
  • Hi and the issue with the database connection was solved with your suggestion of moving the shorturl codes in the htaccess up top and removing my previous attempts at the function.php file. now it all works splendidly. wow thanks a lot! but now there is a minor problem.

    you mentioned this

    msandersen


    Incidentally, I've edited the above post a little to tweak performance by adding an IF statement around the generation of the site base URL. In the original pnModURL function, it calls the pnGetBaseURL() function, which in turn calls pnGetBaseURI(), every time it is run for each and every link. Even for a small test install of pnEncyclopedia like mine, there are quite a few links using the pnModURL function. Now, I think it safe to assume that the website won't jump around on the server in between each link being rendered, so the Base URL won't change. The pnGetBaseURL call is replaced with a one-line condensed version of the same.

    Code

    if (empty($GLOBALS['SiteRoot'])) {
        $nukeurl = pnGetBaseURI();  
        global $SiteRoot;
        $SiteRoot = "http".($_SERVER['HTTPS']=="on"?"s":"")."://".(empty($_SERVER['HTTP_HOST'])?getenv('HTTP_HOST'):$_SERVER['HTTP_HOST']).$nukeurl."/";
    }


    and i replaced the orignial code above to the pnMod.php and now all my admin links related to API are medTerms-admin.html

    my issue is now trying to add the link to my block which now i can't since accessing the block admin doesn't work :) wink

    so for example, accessing my 'blocks' via admin, now directs me to medTerms-admin.html. its real clever what you have done, but is there a work around this so the pnMod.php only recognizes the pnEncyclopedia instead of all API functions. I saw the if clause but its not working. looking forward to your response. :).
  • Always a BUT... :) Damn, you're right, a bug in the code... This is why you shouldn't code late at night. It's nothing to do with the IF statement, though. I hadn't checked the Admin section, because it shouldn't affect them at all. There's a check for the module name in the pnShortURL function... And that's where I made an elemental typo any seasoned PHP scripter will point out. I've corrected the post again.
    Line 2 of the pnShortURL function:

    Code

    function pnShortURLs($modname, $type, $func, $args) {
      if ($modname=='pnEncyclopedia') {

    In languages like PHP, '$a==$b' is a comparison of two elements, whereas '$a=$b' assigns a value of $b to the left element $a. I'd left out one of the equal signs, so $modname was always equal to "pnEncyclopedia", rather than checking if it was...
    oops...

    Martin
  • well that sure did it :).

    i really like your support and i really truely appreciate your help. just out of curiousity, if i wanted to use this piece of code for another module similar to pnEncyclopedia...what should i change or generally speaking. thanks :)
  • Don't have time for a detailed explanation right now, the code singles out the pnEncyclopedia modules as indicated above, as making a generic one that works in all instances can be tricky, as the system isn't designed for it - yet.
    At the end of the pnShortURLs code, though, you'll notice

    Code

    //    elseif($modname=='Postcalendar')  {
    //  Postcalendar ShortURLs or some other module
    //  }

    it's been commented out, but by removing the // slashes, you could put a different module name here, like Postcalendar in this case. Observing the URL variables produced my the module, and deciding how you want them used in ShortURLs determines what you do in between.
    Because pnEncyclopedia was silly enough to use the pnModURL function to make Action URLs for forms, yet add variables in the form, I have to filter those out first.

    Code

    if (($func=="search_letter" or $func=="create") && empty($args)) return false; // Don't convert form fields

    the "search_letter" (search fields) and "create" (add terms/volumes forms) are posted, and have no value in ShortURLs anyway, they are also detected by the fact there are no argumetns in the URL, they're sent by the form. You find that when the module breaks with an error on using the forms, and checking the browser source.

    Code

    $url="medTerms";
    is the basis of the ShortURL in this case. Simply using the Module name may make better sense in a generic sense

    Code

    $url=$modname;

    It parses the arguments, shortening one of them when encountered, and tags it onto the base URL as -VarValue since I know the variable consist only of letters and underscores, but the value is always a number in this case, which can be used in the Rerite Rules.

    Code

    if ($k=="get_letter") $k="get";
    $vars .= "-$k$v";

    "$var .=" is shorthand for $var=$var."-$k$v". The dot joins strings.
    Some of the longer function names are located and shortened

    Code

    if ($func=="display_term") {
                $func="term";
    }

    and in the end, the final URL is constructed, tagging the arguments onto the base URL "medTerm", along with the Type and Function names unless type=user or function=main, cause PN assumes those and leaves them out, and will get confused if you send them along. Then the full URL is Returned as the result of the function, with the appropriate extension.

    Code

    $url.=($type!="user"?"-$type":"").($func!="main"?"-$func":"").$vars;
        return $url.".phtml";
      }

    ($type!="user"?"-$type":"") uses the Ternary operator, a kind of shorthand IF statement, in the form $arg1 ? $arg2 : $arg3 if the first statement is true, then execute the second statement, else execute the 3rd instead. "!=" means "Not equal to", hence if Type is not User, then tag on the Type variable.

    Then comes the bit about writing the appropriate rewrite rules, until they match the returned values properly. Something about the ShortURLs must be specific enough as to not catch other URLs, such as the functon name first, like medTerm.

    Guess I explained most of it after all... in a brief way. It helps to understand PHP. Everything I know I learnt here: http://www.php.net/manual/en/ plus seeing other people's code.

    Martin

Go to page 1 - 2 [+1]:

This list is based on users active over the last 60 minutes.