How can I see a Panel Page, having the node title as an argument?

Ex:
The product "samplepanel" has the "product/sample" URL alias which resolve the node/10.

Of course I can see the node in the "product/sample" URL, but now I also want to see it in the following URL: "thebestproduct/sample".

So, I've created a panel with "thebestproduct/%node" path.
The "thebestproduct/10" URL works, but the "thebestproduct/sample" URL gives me the "Page not found".
In conclusion, I only can see the panel with the nodeid which is a little bit ugly.

I can achieve it by creating one more URL alias (with rules) everytime a product is created. But I believe there is a better solution for this.

Anyone can help me?
Many thanks

Comments

mattmcegg’s picture

looking for this solution...

JohnnyBeGood-dupe2’s picture

anyone?

mradcliffe’s picture

I ran into a similar issue with needing to include url aliases to node paths as arguments.

In order to accomplish this or something similar as in the OP you need to code a custom ctools arguments plugin. You don't need separate contexts or content_types as the advanced help page for the example ctools plugin leads you to suspect. You can just use the node keyword.

Here's a code snippet from what I just wrote for aliases, but it's obviously not the entire module as you'll see a required setting:

  $args = arg();
  $lookup = ''; 
  for ($i = $conf['arg_number']; $i < count($args); $i++) {
    $lookup .= $args[$i];
    if ($i < count($args)-1) {
      $lookup .= '/';
    }   
  }
  if ($sys_path = drupal_lookup_path('source', $lookup, NULL)) {
    if (substr($sys_path, 0, 4) == 'node') {
        $nid = arg(1, $sys_path);
    }   
  }

  // Return FALSE if $nid isn't set
  if (!isset($nid)) {
    return FALSE;
  }

  if ($node = node_load($nid)) {
    // We generate a ctools context for a node... This part works, but it does not actually do anything.
    return ctools_context_create('node', $node);
  }

Note: I'm bumping this up from a few months back... Mainly to give people better search results. Ignore if you want. ;-)

edulterado’s picture

I´m looking for the same solution that let me include the node title in the URL and I´m dealing with Panels arguments with no results so far.

So, where that snippet must be included?

Thanks!

acondiff’s picture

Could you explain how you accomplished this? I am trying to replace the node id with the node title in the panels argument. Thanks.

Renee S’s picture

Hi M Radcliffe, I was hoping you'd be able to attach the plugin that you've written to do this. Or add it to the ctools queue. It would be VERY helpful :)

demon326’s picture

BUMP, need it to... got stuck without it!

adam-delaney’s picture

subscribing

StoraH’s picture

subscribing

andrbmgi’s picture

A solution based on mradcliffe's comment:

Make a new module with the following three files in the exact paths:

new_module/new_module.info

name = New Module
description = Provides ability to use node title as panel argument
dependencies[] = ctools
core = 7.x

new_module/new_module.module

<?php
function new_module_ctools_plugin_directory($module, $plugin) {
  if ($module == 'ctools' && !empty($plugin)) {
    return "plugins/$plugin";
  }
}

new_module/plugins/arguments/node_title.inc

<?php
$plugin = array(
  'title' => t("Node: Title"),
  'description' => t('Creates a node context from a node title argument.'),
  'context' => 'new_module_argument_node_title_context',
  'placeholder form' => array(
    '#type' => 'textfield',
    '#description' => t('Enter the node title of a node for this argument'),
  ),
);

function new_module_argument_node_title_context($arg = NULL, $conf = NULL, $empty = FALSE) {
  // watchdog('ctools',
  //         'I am running. arg: ' . $arg,
  //         WATCHDOG_NOTICE); // uncomment and watch wd for debug 
  
  if ($empty) {
    return ctools_context_create_empty('node');
  } // not sure ...

  if (is_object($arg)) {
    return ctools_context_create('node', $arg);
  } // ...if these two are really necessary. Do we ever get an object?

  $query = new EntityFieldQuery();
  $node = NULL;

  $entities = $query->entityCondition('entity_type', 'node')
                    ->propertyCondition('title', $arg)
                    ->propertyCondition('status', 1)
                    ->range(0,1)
                    ->execute();

  if (!empty($entities['node'])) {
    $node = node_load(array_shift(array_keys($entities['node'])));
  }

  if (!$node) {
    return FALSE;
  }

  return ctools_context_create('node', $node);
}

Hope this can speed up someones process. :)