• Babel, use_alias_path, and shortcut to entering URLs#

  • nicboyde Reply #1, 3 months, 2 weeks ago

    Reply
    I have an odd problem. A client wants his clients to be able to type in the alias of any resource, and go straight to the resource page, but without having to type in the whole path. The site is a Babel Multilingual site, and has use_alias_path turned on, and the URLs are long, because the content is nested, for good reasons, some levels down.

    So I need a little form that takes the alias, adds the context/path information in front, and then tells the browser where to go by sending the whole string as if it had all been typed in to the address bar. It need not be error-checking.

    I thought of using simpleSearch, but the documentation says it doesn't search TVs, and the resource alias is a TV. (If it did, I could build a proper search system - overkill, but it might do the job). But as it doesn't, on the face of it, I'm stuck.

    It struck me that this is probably something very simple, but I have no idea how to create this functionality.

    Any clues, ladies and gentlemen, will be most gratefully-received.

    Nic Boyde

    Modx Revo 2.1.2


  • Wanze Reply #2, 3 months, 2 weeks ago

    Reply
    You can write a short snippet that searches for a resource with your alias sent over the form and redirect to that page.
    $alias = $_POST['alias']; //Do more santinize stuff here...
    $res = $modx->getObject('modResource',array('alias' => $alias));
    if($res && is_object($res)){
       $id = $res->get('id');
       $modx->sendForward($modx->makeUrl($id));
    }else{
      //No page with alias $alias was found...
    }

    The problem here ist that if you have multiple resources with the same alias, it will find always the first. So maybe you want to expand the query and add the context (language) as a criteria.
    That does not solve the problem when you have multiple aliases in the same context ;-)


  • nicboyde Reply #3, 3 months, 2 weeks ago

    Reply
    Very many thanks! I'll try it out and see how it goes - the aliases are duplicated for each context, but not within a context, so this should be manageable.

    Thanks again.




  • nicboyde Reply #4, 3 months, 2 weeks ago

    Reply
    Dear Wanze - your script doesn't work. I hate to bother you on something so trivial, but I'm at my wits' end here.

    I use this form to make a Post_variable called 'alias'

    <h5>If you know the property ID, type it here.</h5>
    <form id="PID"action="[[goThere]]" method="post">
            <label for="alias">
            Property Id:
            </label>
        <input type="text" name="alias" id="alias" size="10" />
        <br class="clear" />
        <div class="form-buttons">
            <input type="submit" value="Go" />
        </div>
    </form>


    I pass control, as you see to a snippet. Here's the snippet:

    <?php
    $alias = $_POST['alias']; //Sanitise later. Still dangerous.
    $res = $modx->getObject('modResource',array('alias' => $alias));
    if($res && is_object($res)){
       $id = $res->get('id');
       $modx->sendForward($modx->makeUrl($id));
    }else{
      //No page with alias $alias was found...
    }


    A straight copy of your script.

    For an incorrect "alias" - I get a page refresh - numerical or alphanumerical alias;
    for a correct numerical alias, I get a page refresh;
    for a correct alias beginning with alpha characters I get a 503 error, showing the valid url of the page from which the snippet was activated - but not all the time. If the alias is "XXnnnnXX", ie alpha then numbers then alpha, I get a refresh. I only get the 503 if the alias is alpha then numerical AND correct. Weird.

    I've played with your script, trying to test it, adding in echos etc. The echos get passed to the address box - (which I have to admit I wasn't expecting), but I just cannot be sure that there is anything being passed from the form to the snippet, except that I get this good (if start with alpha) - 503 error, bad - refresh, behaviour.

    I started out with something more elaborate, getting the current context etc, and tried putting in 'abs' and 'full' in the makeUrl call, all to no avail, so eventually cut everything out except your suggestion, and I'm still stuck. As far as I can see it should work. I tried using 'pagetitle' instead of 'alias', and tried using a guaranteed non-reserved word for the Post_variable in case 'alias' meant something to MODx or PHP. No joy.

    I'm stuck.

    Can you point out my error?


    Nic Boyde


  • nicboyde Reply #5, 3 months, 2 weeks ago

    Reply
    I've now realised that putting snippet names into form" fields probably won't work, so I've used FormIt, and the code looks like this:

    [[!FormIt?
    &hooks=`goThere`
    &submitVar=`PID`
    &validate=`alias:required:striptags`
    ]]
    <h5>If you know the property ID, type it here.</h5>
    <form id="PID" name="PID" action="[[~[[*id]]]]" method="post">
            <label>
            Property Id:
            </label>
        <input type="text" name="alias" id="alias" size="10" />
        <br class="clear" />
        <div class="form-buttons">
            <input type="submit" value="Go" />
        </div>
    </form>


    The snippet code unchanged.

    Now, no matter what I do, correct alias or otherwise, I get a completely uniform response: nothing - a page refresh.


  • nicboyde Reply #6, 3 months, 2 weeks ago

    Reply
    The thing becomes clearer. I've found out what was wrong with the FormIt snippet call, and fixed it, and now get a universal 503 error. Seems like there was nothing wrong with my original form action statement after all.

    I've studded the snippet with log-writing lines, and this is the snippet now:

    <?php
    $modx->log(xPDO::LOG_LEVEL_ERROR,'Testing the gothere custom hook.');
    $alias = $_POST['alias']; //Sanitise later. Still dangerous.
    $modx->log(xPDO::LOG_LEVEL_ERROR,$alias);
    $res = $modx->getObject('modResource',array('alias' => $alias,));
    $context = $modx->context->key;
    $modx->log(xPDO::LOG_LEVEL_ERROR,$context);
    if($res && is_object($res)){
       $id = $res->get('id');
    $modx->log(xPDO::LOG_LEVEL_ERROR,$id);
    $modx->log(xPDO::LOG_LEVEL_ERROR,($modx->makeURL($id)));
    $modx->log(xPDO::LOG_LEVEL_ERROR,($modx->makeURL($id,$context,'','full')));
       $modx->sendForward($modx->makeUrl($id,$context,'','full'));
    return true;
    }
    else
    {
    $modx->log(xPDO::LOG_LEVEL_ERROR,'Got to the false condition.');
    return false;  //No page with alias $alias was found...
    }


    And here's the relevant part of the log:

    [2012-02-07 06:05:16] (ERROR @ /index.php) Testing the gothere custom hook.
    [2012-02-07 06:05:16] (ERROR @ /index.php) se1677
    [2012-02-07 06:05:16] (ERROR @ /index.php) web
    [2012-02-07 06:05:16] (ERROR @ /index.php) 1265
    [2012-02-07 06:05:16] (ERROR @ /index.php) index/property-container/se1677
    [2012-02-07 06:05:16] (ERROR @ /index.php) http://aquitainerealestate.com/en/index/property-container/se1677
    

    So in other words everything is working except the $modx->sendForward

    I will keep investigating - but what a nightmare this simple-looking job has turned out to be... 30 hours of work so far...


  • nicboyde Reply #7, 3 months, 2 weeks ago

    Reply
    Solved: sendForward is wrong - should be sendRedirect.

    sendForward wants a property id, thus:

    sendForward (integer $id, [string|array $options = null])


    Funnily-enough, when I gave it $id, or even an absolute id number (sendForward(1234) hard-coded in the snippet, I got a 500 error, or a 30-second max processing error, and hundreds of log entries. Bug? I haven't time to investigate.

    $modx->sendRedirect($modx->makeUrl($id,$context,'','full'));


    works fine.

    An education...

    Thanks for kicking me off in the right direction.


  • Wanze Reply #8, 3 months, 2 weeks ago

    Reply
    Hi nicboyde,
    glad you did it and sorry for the problems with sendForward/sendRedirect.
    <form id="PID"action="[[goThere]]" method="post">

    You should not put the snippet itself into the action parameter, but the page where you put your snippet inside.

    Also make sure when dealing with POST, GET data, that you call your snippet which processes these requests uncached. Otherwise, the result gets cached after the first visit.
    Nice solution with the formit hook
    Cheers