Integration with WP3 Nav Menu Feature

Having Problems? Need Help? Post here!

Integration with WP3 Nav Menu Feature

Postby bedex78 » Tue Oct 05, 2010 7:42 pm

Awesome plugin, Qian!!! Thanks a heaps!!!

Anyway, I've been scratching my head on how to integrate qTranslate with the new Nav Menu feature in WP3 (Appearance > Menus)... I might have missed something, but anyway....

#1 [Solved]
First of all, in regards to directing the menu links (created using the Nav Menu feature) to the current language... The plugin works to some degrees, but failed when linking to posts from custom post types (at least this is my experience)... and also the link doesn't work when creating custom links, such as a 'Home' link, and I'm doing a lot of custom links on my current project...

I don't know if anybody had found a solution yet... without resorting to hard-coding the menu, that is... So I went to search for a solution and found this really neat trick: http://www.kriesi.at/archives/improve-y ... nu-output/

From this knowledge, I came up with this code:

Code: Select all
// QTRANSLATE NAV MENU INTEGRATION //

class qtrans_walker extends Walker_Nav_Menu
{
    function start_el(&$output, $item, $depth, $args)
    {
        global $wp_query;
        $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';

        $class_names = $value = '';

        $classes = empty( $item->classes ) ? array() : (array) $item->classes;

        $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
        $class_names = ' class="'. esc_attr( $class_names ) . '"';

        $output .= $indent . '<li id="menu-item-'. $item->ID . '"' . $value . $class_names .'>';

        $attributes  = ! empty( $item->attr_title ) ? ' title="' . esc_attr( $item->attr_title ) .'"' : '';
        $attributes .= ! empty( $item->target ) ? ' target="' . esc_attr( $item->target ) .'"' : '';
        $attributes .= ! empty( $item->xfn ) ? ' rel="' . esc_attr( $item->xfn ) .'"' : '';
       
        // Determine integration with qTranslate Plugin
        if (function_exists('qtrans_convertURL')) {
            $attributes .= ! empty( $item->url ) ? ' href="' . qtrans_convertURL(esc_attr( $item->url )) .'"' : '';
        } else {
            $attributes .= ! empty( $item->url ) ? ' href="' . esc_attr( $item->url ) .'"' : '';
        }

        $item_output = $args->before;
        $item_output .= '<a'. $attributes .'>';
        $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
        $item_output .= '</a>';
        $item_output .= $args->after;

        $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
    }
}


Basically, I just changed this line:

Code: Select all
        $attributes .= ! empty( $item->url ) ? ' href="' . esc_attr( $item->url ) .'"' : '';


To this:
Code: Select all
        // Determine integration with qTranslate Plugin
        if (function_exists('qtrans_convertURL')) {
            $attributes .= ! empty( $item->url ) ? ' href="' . qtrans_convertURL(esc_attr( $item->url )) .'"' : '';
        } else {
            $attributes .= ! empty( $item->url ) ? ' href="' . esc_attr( $item->url ) .'"' : '';
        }


Notice the use of qtrans_convertURL()...

Then you just add 'walker' => new qtrans_walker() to your wp_nav_menu function call like so:

Code: Select all
wp_nav_menu( array(
'container' =>false,
'menu_class' => 'nav',
'echo' => true,
'before' => '',
'after' => '',
'link_before' => '',
'link_after' => '',
'depth' => 0,
'walker' => new qtrans_walker()
));


I guess this will make the links more qTranslate proof...

#2 [Unsolved]
Secondly, I wonder how we can beautify the appearance of the posts/pages titles both in the selection panels and in the menu editor panel.

Currently it shows '<!--:id-->Test ID<!--:--><!--:en-->Test EN<!--:-->', which is very ugly and unpleasant... and we are forced to use '[:en]Test EN[:id]Test ID' when creating custom link titles, which is quite inconvenient for clients.

Anybody knows how we can display only the current languages for the selection panels? And to have an extra field for translation in the menu editor panel?? Maybe from the knowledge that I provided above??

Thank you to the sharing community! Many thanks to Qian for the great plugin!!

Hope to hear from you guys!

Cheers!!
bedex78
 
Posts: 31
Joined: Mon Oct 04, 2010 9:11 am

Re: Integration with WP3 Nav Menu Feature

Postby tamerax » Wed Oct 06, 2010 3:40 am

thank you SOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO much!!
I spent like 2 days trying to solve my "home" link issue.
perfect!!
tamerax
 
Posts: 2
Joined: Tue Oct 05, 2010 10:18 am

Re: Integration with WP3 Nav Menu Feature

Postby bedex78 » Wed Oct 06, 2010 7:20 pm

Here's another method to direct the links correctly... This time using FILTER, so you can skip the 'Walker' argument in the wp_nav_menu function call.

Code: Select all
add_filter('walker_nav_menu_start_el', 'qtrans_in_nav_el', 10, 4);
function qtrans_in_nav_el($item_output, $item, $depth, $args){
    $attributes  = ! empty( $item->attr_title ) ? ' title="'  . esc_attr( $item->attr_title ) .'"' : '';
    $attributes .= ! empty( $item->target )     ? ' target="' . esc_attr( $item->target     ) .'"' : '';
    $attributes .= ! empty( $item->xfn )        ? ' rel="'    . esc_attr( $item->xfn        ) .'"' : '';
   
   // Determine integration with qTranslate Plugin
   if (function_exists('qtrans_convertURL')) {
      $attributes .= ! empty( $item->url ) ? ' href="' . qtrans_convertURL(esc_attr( $item->url )) .'"' : '';
   } else {
      $attributes .= ! empty( $item->url ) ? ' href="' . esc_attr( $item->url ) .'"' : '';
   }
   
   $item_output = $args->before;
   $item_output .= '<a'. $attributes .'>';
   $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
   $item_output .= '</a>';
   $item_output .= $args->after;
      
   return $item_output;
}
bedex78
 
Posts: 31
Joined: Mon Oct 04, 2010 9:11 am

Re: Integration with WP3 Nav Menu Feature

Postby bedex78 » Wed Oct 06, 2010 8:40 pm

[UPDATED] And another method... :D

Code: Select all
add_filter('wp_nav_menu_items','qtrans_in_nav_function');
function qtrans_in_nav_function ($nav){

   $url = get_bloginfo('url');
   $url_preg = preg_replace('/\//', '\/', $url);
   
   $qtrans_url = qtrans_convertURL($url);
   
   $nav = preg_replace('/('.$url_preg.')(\/id)/', $url, $nav);
   $nav = preg_replace('/('.$url_preg.')/', $qtrans_url, $nav);
   
   return $nav;
}


My apologies for posting variation of methods on this one. I'm just experimenting to see how far I can manipulate the Nav Menu.

(UPDATED: problem when viewing pages in the earlier version of the 3rd method... but fixed now... ;) )
bedex78
 
Posts: 31
Joined: Mon Oct 04, 2010 9:11 am

Re: Integration with WP3 Nav Menu Feature

Postby daobydesign » Tue Oct 12, 2010 2:40 am

Awesome -- cheers for this! ;)
daobydesign
 
Posts: 6
Joined: Wed May 06, 2009 7:48 am

Re: Integration with WP3 Nav Menu Feature

Postby bedex78 » Tue Oct 12, 2010 9:30 am

I found this really good plugin that modifies the nav menu editor. It is called Gecka Submenu (http://wordpress.org/extend/plugins/gecka-submenu/). You can learn from the script how you can manipulate the editor to a certain degree. From the knowledge I get from this plugin I managed to 'beautify' the appearance of the title in the menu editor section (the right column in the nav menu page). That is, I managed, after saving a menu or refreshing the page, to display the title in accordance to the current language and automatically change something like this:

<!--:en-->Home<!--:--><!--:id-->Beranda<!--:-->

...to this:

[:en]Home[:id]Beranda

...in the 'Navigation Label' field so that it is easier to read and edit... and more understandable to noobie clients ;) . This may also be beneficial for theme builders.

As for the code, I made a call to the walker class and copied and pasted the script from the core. Then I just modified accordingly from there:

Code: Select all
add_filter( 'wp_edit_nav_menu_walker', 'editor_walker' );

function editor_walker($a) {
   return 'qTrans_Walker_Nav_Menu_Edit';
}

class qTrans_Walker_Nav_Menu_Edit extends Walker_Nav_Menu  {
   /**
    * @see Walker_Nav_Menu::start_lvl()
    * @since 3.0.0
    *
    * @param string $output Passed by reference.
    * @param int $depth Depth of page.
    */
   function start_lvl(&$output) {}

   /**
    * @see Walker_Nav_Menu::end_lvl()
    * @since 3.0.0
    *
    * @param string $output Passed by reference.
    * @param int $depth Depth of page.
    */
   function end_lvl(&$output) {
   }

   /**
    * @see Walker::start_el()
    * @since 3.0.0
    *
    * @param string $output Passed by reference. Used to append additional content.
    * @param object $item Menu item data object.
    * @param int $depth Depth of menu item. Used for padding.
    * @param int $current_page Menu item ID.
    * @param object $args
    */
   function start_el(&$output, $item, $depth, $args) {
      global $_wp_nav_menu_max_depth;
      $_wp_nav_menu_max_depth = $depth > $_wp_nav_menu_max_depth ? $depth : $_wp_nav_menu_max_depth;

      $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';

      ob_start();
      $item_id = esc_attr( $item->ID );
      $removed_args = array(
         'action',
         'customlink-tab',
         'edit-menu-item',
         'menu-item',
         'page-tab',
         '_wpnonce',
      );

      $original_title = '';
      if ( 'taxonomy' == $item->type ) {
         $original_title = get_term_field( 'name', $item->object_id, $item->object, 'raw' );
      } elseif ( 'post_type' == $item->type ) {
         $original_object = get_post( $item->object_id );
         $original_title = $original_object->post_title;
      }

      $classes = array(
         'menu-item menu-item-depth-' . $depth,
         'menu-item-' . esc_attr( $item->object ),
         'menu-item-edit-' . ( ( isset( $_GET['edit-menu-item'] ) && $item_id == $_GET['edit-menu-item'] ) ? 'active' : 'inactive'),
      );

      $title = $item->title;

      if ( isset( $item->post_status ) && 'draft' == $item->post_status ) {
         $classes[] = 'pending';
         /* translators: %s: title of menu item in draft status */
         $title = sprintf( __('%s (Pending)'), $item->title );
      }

      $title = empty( $item->label ) ? $title : $item->label;

      ?>
      <li id="menu-item-<?php echo $item_id; ?>" class="<?php echo implode(' ', $classes ); ?>">
         <dl class="menu-item-bar">
            <dt class="menu-item-handle">
               <span class="item-title"><?php echo esc_html__( $title ); ?></span>
               <span class="item-controls">
                  <span class="item-type"><?php echo esc_html( $item->type_label ); ?></span>
                  <span class="item-order">
                     <a href="<?php
                        echo wp_nonce_url(
                           add_query_arg(
                              array(
                                 'action' => 'move-up-menu-item',
                                 'menu-item' => $item_id,
                              ),
                              remove_query_arg($removed_args, admin_url( 'nav-menus.php' ) )
                           ),
                           'move-menu_item'
                        );
                     ?>" class="item-move-up"><abbr title="<?php esc_attr_e('Move up'); ?>">&#8593;</abbr></a>
                     |
                     <a href="<?php
                        echo wp_nonce_url(
                           add_query_arg(
                              array(
                                 'action' => 'move-down-menu-item',
                                 'menu-item' => $item_id,
                              ),
                              remove_query_arg($removed_args, admin_url( 'nav-menus.php' ) )
                           ),
                           'move-menu_item'
                        );
                     ?>" class="item-move-down"><abbr title="<?php esc_attr_e('Move down'); ?>">&#8595;</abbr></a>
                  </span>
                  <a class="item-edit" id="edit-<?php echo $item_id; ?>" title="<?php _e('Edit Menu Item'); ?>" href="<?php
                     echo ( isset( $_GET['edit-menu-item'] ) && $item_id == $_GET['edit-menu-item'] ) ? admin_url( 'nav-menus.php' ) : add_query_arg( 'edit-menu-item', $item_id, remove_query_arg( $removed_args, admin_url( 'nav-menus.php#menu-item-settings-' . $item_id ) ) );
                  ?>"><?php _e( 'Edit Menu Item' ); ?></a>
               </span>
            </dt>
         </dl>

         <div class="menu-item-settings" id="menu-item-settings-<?php echo $item_id; ?>">
            <?php if( 'custom' == $item->type ) : ?>
               <p class="field-url description description-wide">
                  <label for="edit-menu-item-url-<?php echo $item_id; ?>">
                     <?php _e( 'URL' ); ?><br />
                     <input type="text" id="edit-menu-item-url-<?php echo $item_id; ?>" class="widefat code edit-menu-item-url" name="menu-item-url[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->url ); ?>" />
                  </label>
               </p>
            <?php endif; ?>
            <p class="description description-thin">
               <label for="edit-menu-item-title-<?php echo $item_id; ?>">
                  <?php _e( 'Navigation Label' ); ?><br />
                  
                  <?php
                  // Beautify 'Navigation Label' here
                  $tval = $item->title;
                  $new_tval = preg_replace('/<!--(:.[a-z])-->(.+?)(<!--:-->)/', '[$1]$2', $tval);
                  ?>

                  <input type="text" id="edit-menu-item-title-<?php echo $item_id; ?>" class="widefat edit-menu-item-title" name="menu-item-title[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $new_tval ); ?>" />
               </label>
            </p>
            <p class="description description-thin">
               <label for="edit-menu-item-attr-title-<?php echo $item_id; ?>">
                  <?php _e( 'Title Attribute' ); ?><br />
                  <input type="text" id="edit-menu-item-attr-title-<?php echo $item_id; ?>" class="widefat edit-menu-item-attr-title" name="menu-item-attr-title[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->post_excerpt ); ?>" />
               </label>
            </p>
            <p class="field-link-target description description-thin">
               <label for="edit-menu-item-target-<?php echo $item_id; ?>">
                  <?php _e( 'Link Target' ); ?><br />
                  <select id="edit-menu-item-target-<?php echo $item_id; ?>" class="widefat edit-menu-item-target" name="menu-item-target[<?php echo $item_id; ?>]">
                     <option value="" <?php selected( $item->target, ''); ?>><?php _e('Same window or tab'); ?></option>
                     <option value="_blank" <?php selected( $item->target, '_blank'); ?>><?php _e('New window or tab'); ?></option>
                  </select>
               </label>
            </p>
            <p class="field-css-classes description description-thin">
               <label for="edit-menu-item-classes-<?php echo $item_id; ?>">
                  <?php _e( 'CSS Classes (optional)' ); ?><br />
                  <input type="text" id="edit-menu-item-classes-<?php echo $item_id; ?>" class="widefat code edit-menu-item-classes" name="menu-item-classes[<?php echo $item_id; ?>]" value="<?php echo esc_attr( implode(' ', $item->classes ) ); ?>" />
               </label>
            </p>
            <p class="field-xfn description description-thin">
               <label for="edit-menu-item-xfn-<?php echo $item_id; ?>">
                  <?php _e( 'Link Relationship (XFN)' ); ?><br />
                  <input type="text" id="edit-menu-item-xfn-<?php echo $item_id; ?>" class="widefat code edit-menu-item-xfn" name="menu-item-xfn[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->xfn ); ?>" />
               </label>
            </p>
            <p class="field-description description description-wide">
               <label for="edit-menu-item-description-<?php echo $item_id; ?>">
                  <?php _e( 'Description' ); ?><br />
                  <textarea id="edit-menu-item-description-<?php echo $item_id; ?>" class="widefat edit-menu-item-description" rows="3" cols="20" name="menu-item-description[<?php echo $item_id; ?>]"><?php echo esc_html( $item->description ); ?></textarea>
                  <span class="description"><?php _e('The description will be displayed in the menu if the current theme supports it.'); ?></span>
               </label>
            </p>

            <div class="menu-item-actions description-wide submitbox">
               <?php if( 'custom' != $item->type ) : ?>
                  <p class="link-to-original">
                     <?php printf( __('Original: %s'), '<a href="' . esc_attr( $item->url ) . '">' . esc_html__( $original_title ) . '</a>' ); ?>
                  </p>
               <?php endif; ?>
               <a class="item-delete submitdelete deletion" id="delete-<?php echo $item_id; ?>" href="<?php
               echo wp_nonce_url(
                  add_query_arg(
                     array(
                        'action' => 'delete-menu-item',
                        'menu-item' => $item_id,
                     ),
                     remove_query_arg($removed_args, admin_url( 'nav-menus.php' ) )
                  ),
                  'delete-menu_item_' . $item_id
               ); ?>"><?php _e('Remove'); ?></a> <span class="meta-sep"> | </span> <a class="item-cancel submitcancel" id="cancel-<?php echo $item_id; ?>" href="<?php   echo add_query_arg( array('edit-menu-item' => $item_id, 'cancel' => time()), remove_query_arg( $removed_args, admin_url( 'nav-menus.php' ) ) );
                  ?>#menu-item-settings-<?php echo $item_id; ?>"><?php _e('Cancel'); ?></a>
            </div>

            <input class="menu-item-data-db-id" type="hidden" name="menu-item-db-id[<?php echo $item_id; ?>]" value="<?php echo $item_id; ?>" />
            <input class="menu-item-data-object-id" type="hidden" name="menu-item-object-id[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->object_id ); ?>" />
            <input class="menu-item-data-object" type="hidden" name="menu-item-object[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->object ); ?>" />
            <input class="menu-item-data-parent-id" type="hidden" name="menu-item-parent-id[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->menu_item_parent ); ?>" />
            <input class="menu-item-data-position" type="hidden" name="menu-item-position[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->menu_order ); ?>" />
            <input class="menu-item-data-type" type="hidden" name="menu-item-type[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->type ); ?>" />
         </div><!-- .menu-item-settings-->
         <ul class="menu-item-transport"></ul>
      <?php
      $output .= ob_get_clean();
   }
}


But I have yet to 'beautify' the appearance of the list of articles (posts/pages) that is on the left column. I don't think a hook or filter is available for that yet.

Anyway, the plugin I mentioned above also demonstrates how we can add meta boxes in the menu item editor. I think this can be useful to create different language fields for the 'Navigation Labels'. I might have a look at that later.

I hope this is useful. Maybe Qian Qin can implement these in the plugin...?
bedex78
 
Posts: 31
Joined: Mon Oct 04, 2010 9:11 am

Re: Integration with WP3 Nav Menu Feature

Postby abmcr » Sun Oct 17, 2010 4:04 pm

I have solved the problem 2


<!--:en-->Page<!--:--><!--:it-->Pagina<!--:-->

but with an edit on the core file :-(
I post this edit , may be someone put the code in the functions

I have edited the nav-menu.php file into the wp-admin/includes folder


i have changed the line 240 as
Code: Select all
   $output .= empty( $item->label ) ? esc_html( $item->title ) : esc_html( $item->label );


in
Code: Select all
      $output .= empty( $item->label ) ? esc_html( get_language($item->title) ) : esc_html( get_language($item->title) );


And i have added this small and stupid function at line
257

Code: Select all
function get_language($mystring,$lg='it'){
      //find the position of the strin needed
      $pos=strpos($mystring, $lg."-->");
      if (!$pos) return $mystring;
      $string=substr($mystring, $pos+5, (strlen($mystring)-($pos+5)));
      //now search the end of the language identifier
      $pos=strpos($string, "<!--:-->");
      $string=substr($string, 0, -(strlen($string)-$pos));
      return $string;
   }

NB: in this function the filter is based on the code of language: in this example the italian language. Change as your preference

Bad code, i know :-(
If this function goes on the functions php file of the theme....
abmcr
 
Posts: 13
Joined: Sat Feb 06, 2010 4:04 pm

Re: Integration with WP3 Nav Menu Feature

Postby caribbeanviolin » Mon Oct 18, 2010 3:50 am

@bedex78: Thanks for the many solutions!

Could you specify where are we to paste your code inside WordPress and which solution you prefer?
It sounds like you got it totally figured out, but I can't even find what code you are replacing!

I'm using Dominion, one of the new GANTRY framework themes made by RocketTheme.com

This is the site I am working on: www.Villa-Lobos.org

Many thanks =)
caribbeanviolin
 
Posts: 3
Joined: Mon Oct 18, 2010 2:41 am

Re: Integration with WP3 Nav Menu Feature

Postby bedex78 » Mon Oct 18, 2010 8:52 am

@abmcr:

Yes, I have noticed that piece of code as well. And an interesting method you have there. However, there is a much easier way of doing that. That is, instead of using 'esc_html', you can just change it to 'esc_html__' (double underscores). This is a built-in function in WP. It translates automatically before encoding.

So the code can be like this:

Code: Select all
   $output .= empty( $item->label ) ? esc_html__( $item->title ) : esc_html__( $item->label );


But I'm still trying to figure out a way that does not involve editing the core (with the current state of WP, that is).

Thanks for the input, though. ;)


@caribbeanviolin:

Well, I haven't actually "got it totally figured out" ;) . But it does fix some of the problems. Anyway, the solutions that I provided can be put in the functions.php file. As for problem #1, I personally use method no. 2. But of course, in the end it all depends on your needs.

Good luck!
bedex78
 
Posts: 31
Joined: Mon Oct 04, 2010 9:11 am

Re: Integration with WP3 Nav Menu Feature

Postby caribbeanviolin » Mon Oct 18, 2010 12:42 pm

@bedex78: still trying to make it work!
Obviously being a violinist doesn't help much here....
I'm copy/pasting the second solution at the end of my functions.php file - inside the WP admin (I'm guessing this is my theme's funcitons.php file?).
Should I be replacing something in the code? Or does it go inside WP's functions.php?
Sorry for the stupid questions, just trying to learn.
@abmcr: I don't mind messing with the core via FTP, but so far I only get "Fatal Error" when making changes! =)
caribbeanviolin
 
Posts: 3
Joined: Mon Oct 18, 2010 2:41 am

Next

Return to qTranslate Support Forum

Who is online

Users browsing this forum: Google [Bot], Google Adsense [Bot] and 12 guests