Jump to content

mcmorry

Members
  • Posts

    33
  • Joined

  • Last visited

  • Days Won

    1

Posts posted by mcmorry

  1. Wow, I'm really impressed on how much interest there is for this module :)

    Sorry if I didn't work on it yet, but I'm focused on a important milestone of a different project that, I hope, should be released tomorrow.

    I really would like to work with you to improve this module and of course if you could host it on GitHub will be the best solution.

    I've seen that I don't have so much experience on PW, but I'll do my best.

    Thanks again

    • Like 3
  2. The toSlug function that I used in the other thread came from a google search... I don't remember from where exactly. It's still that one that is being used, right?

    It would definitely be better to use the same method that is used by PW.

    Yes it's still your code. I'll improve it using the PW Sanitizer plus a map of replacement characters.

  3. Thanks for your feedback. Very appreciated.

    I guessed it, but newcomers maybe could have problems understand that URLsegments needs to be enabled in PW template settings to make it work. :) Maybe suggest the proxy pages could also be made hidden, to avoid showing up in the navigation.

    ....

    Some idea I had would be to have an install method in the module to install the needed template with urlSegments enabled and prepare the default and other proxy pages according to the language settings in PW.

    Yes it's the best solution. I'll try to implement it.

    The module unfortunately doesn't work well with special chars in many languages. Like Umlauts ÜÖÄäöü ... àåéê and a lot more. I end up with /de/1001_-ber-uns/ instead of /de/1001_ueber-uns/.. Note that those conversion are used in the default title -> name relation when creating a new page, and can be configured in the page name inputfield module in processwire. Maybe there is a way to get that config from the module loaded to do the slug. Or if not, add it to this module locally.

    I tried to use the same method used in the Pages->save() funciton:

    $this->fuel('sanitizer')->pageName($localizedTitle, true);
    

    but the behavior is the same. Instead the Javascript code of the admin panel contains a long list of characters to be replaced with latin ones.

    It should be integrated in the Sanitazer object as well. In the meantime I'll implement it locally.

    The mlUrl() seems to work expect the link for homepage "/" doesnt work. It has "".

    Ops, fixed. I'll release the fix soon, together with more features.

    Also to avoid the problem of having doubles in alternative languages, id feature has to be always enabled. As there's nothing preventing me from entering same title for two pages under same tree. Or maybe there's an easy way to prevent it with a hook and do some additional validating on page title language fields.

    The best could be to store a localized unique name when inserting a localized title, using the same method that PW uses for page name. An important question is: what to do if you change a title? Should the localized name change accordingly? From a SEO point of view this could be a problem, and should be avoided. An option box could be added to force it, but I don't know how to add it in the FieldtypePageTitleLanguage.

    Any suggestions?

    Thanks

    mcmorry

  4. Hi Ryan,

    thanks for your nice words :)

    Yes you caught exactly the point.

    Initially I was thinking to hook the path() method to generate all the urls of the website, but I was not sure if it could be too invasive.

    But yes, you could replace $page->url() with $page->mlUrl() without any problems. (to be tested of course).

  5. LanguageLocalizedURL module

    Localized URL generator and parser

    You can find the last version here: http://modules.proce...-localized-url/

    Or from the repository on github: https://github.com/m...e-localized-URL

    This module is useful to generate localized url using the language code as first 'folder', and then the localized titles of the nested pages:

    (removed previous instructions to prevent double maintaining.)

    See more infos in readme of the module with instruction and informations.

    https://github.com/m...aster/README.md

    • Like 11
  6. Thanks guys for your appreciation :)

    Would be more elegant to have a setting on the module for this

    Yes, definitively is the best solution. I just started with ProcessWire and I didn't think about that possibility.

    I'll try to implement it and optimize/document the code and I'll post it here again.

    But my question is: is there a public repository of modules where to share it? I've seen a list in the documentation, but I suppose that is managed directly from Ryan or his colleagues.

  7. @diogo Thanks for sharing your code. I just packed it in a Module adding some features.

    It extends the Page class, by hooking a new method mlUrl(bool includePageId).

    I wanted to generate the localized url too. So instead of using names I use title to generate url.

    That function accepts one boolean parameter to specify if to use the page id:

    www.mydomain.com/it/my-italian-title/

    www.mydomain.com/it/[page id]_my-italian-title

    The id is useful if you can't be sure that the localized title is unique, or in case that there are a lot of contents and you don't want to search by title in a long loop, but seeking directly by id.

    The generated url always contains the language code, for the default one too, that in this case is manually mapped to 'en';

    This is the code (that could be improved, especially in the generation of the url):

    <?php
    class MultiLanguageURL extends WireData implements Module {
    /**
     * getModuleInfo is a module required by all modules to tell ProcessWire about them
     *
     * @return array
     *
     */
    public static function getModuleInfo() {
     return array(
      // The module'ss title, typically a little more descriptive than the class name
      'title' => 'MultiLanguageURL',
      // version: major, minor, revision, i.e. 100 = 1.0.0
      'version' => 100,
      // summary is brief description of what this module is
      'summary' => 'Multi language url',
    
      // Optional URL to more information about the module
      'href' => '',
      // singular=true: indicates that only one instance of the module is allowed.
      // This is usually what you want for modules that attach hooks.
      'singular' => true,
      // autoload=true: indicates the module should be started with ProcessWire.
      // This is necessary for any modules that attach runtime hooks, otherwise those
      // hooks won't get attached unless some other code calls the module on it's own.
      // Note that autoload modules are almost always also 'singular' (seen above).
      'autoload' => true,
      );
    }
    /**
     * Initialize the module
     *
     * ProcessWire calls this when the module is loaded. For 'autoload' modules, this will be called
     * when ProcessWire's API is ready. As a result, this is a good place to attach hooks.
     *
     */
    public function init() {
     $this->addHook('Page::mlUrl', $this, 'mlUrl');
    }
    
    private function mlPath($page) {
     if($page->id === 1) return '/';
     $path = '';
     $parents = $page->parents();
     foreach($parents as $parent) if($parent->id > 1) $path .= "/".$this->toSlug($parent->title);
     return $path . '/' . $this->toSlug($page->title) . '/';
    }
    
    public function mlUrl($event) {
     $page = $event->object;
     $includeId = $event->arguments(0);
     $url = $this->mlPath($page);
     if ($includeId) {
      $segments = explode('/', $url);
      $index = count($segments)-2;
      $segments[$index] = $page->id.'_'.$segments[$index];
      $url = implode('/', $segments);
     }
     $lang = $this->user->language->name;
     if (!$lang || $lang=='default') $lang = 'en';
     $event->return = '/'.$lang.$url;
    }
    
    
    private function toSlug($str) {
     $str = strtolower(trim($str));
     $str = preg_replace('/[^a-z0-9-]/', '-', $str);
     $str = preg_replace('/-+/', "-", $str);
     return $str;
    }
    
    public function parseUrl() {
     $page = $this->fuel('page');
     $user = $this->fuel('user');
     $languages = $this->fuel('languages');
     $pages = $this->fuel('pages');
     $input = $this->fuel('input');
    
     $lang = $page->name;
     if ($lang == 'en') $lang='default';
     $user->language = $languages->get($lang);
     $basePage = $pages->get("/");
     $segments = $input->urlSegments;
     if($segments){
      $page = $basePage;
      foreach($segments as $segment){
    // search of page id inside the segment
    $parts = explode('_', $segment);
    $pageid=null;
    if (count($parts)>1 && is_numeric($parts[0])) {
     $pageid=$parts[0];
     $page = $pages->get($pageid);
    } else {
     $children = $page->children;
     foreach ($children as $child){
      $found = false;
      if($segment==$this->toSlug($child->title)){
       $page = $child;
       $found = true;
       break;
      }
     }
    }
    if (!$found) throw new Wire404Exception();
      }
     } else {
      $page = $basePage;
     }
     $this->fuel->set('page', $page);
     return $page;
    }
    }
    

    This is the code to use the module in your template:

    
    <?php
    $page = $modules->get('MultiLanguageURL')->parseUrl();
    include("./{$page->template}.php");
    ?>
    
    

    and to generate the localized url:

    // to include the page id
    $page->mlUrl(true);
    // to generate without id
    $page->mlUrl(false);
    
    • Like 5
×
×
  • Create New...