Hi,
I have a situation where we have a default view which we'd like to extend in the code. We'd like to add an argument handler for the view of $node->type, but we dont want to duplicate the current view and add the handlers through the interface. It would be ideal if we could just extend our current view programmatically to allow this.
I've searched the docs and cant find anything that allows you to do this through the code.
Since it's a default argument handler within views, It would be brilliant if this was possible through a views hook by doing something like...


function(){
 $output = '';
 $view = views_get_view($viewname);
 $view = views_add_argument_handler($view, 'handlername');
 $output .= views_embed_view($view, $arg);

return $output;

I have raised this as a support request initially and 'not' a feature request as i am unsure and this may actually be possible currently i have just missed it in my searching = (.

Graham.

Comments

merlinofchaos’s picture

Status: Active » Fixed

What you want is this:

  $view->add_item('display_id', 'argument', 'tablename', 'fieldname', $options);

$options should be an array containing whatever options the argument handler needs. As argument handlers are quite configuration heavy, you probably will need this. You can get the options by setting up a view the way you want it in the UI, then exporting it and looking through the view code for the options portion of the argument in question.

tayzlor’s picture

Great, thanks, that works a treat for adding args to the view =)

i managed to get all my args attached to the view and was able to render the view to a page using a hook_menu(). all worked fine.

for the next step i tried to do the following:

in views_default_views() for one of my modules -

create a new view object.
use views_get_view() to get a default view provided by another module.
change the $view->name to my new viewname
use $view->add_item() to add my additional argument items to the view
return the view object.

somehow, drupal crashes with the message:

connection to server reset while the page was still loading...

when i try to call the views_get_view() function from inside views_default_views().

I am basically trying to do it this way because my view needs to be available to the services module for views.get to work on it.

any ideas?

Thanks
G.

merlinofchaos’s picture

Unfortunately, using views_get_view during that hook is probably causing a recursion problem. views_get_view loads all default views; and since the default views aren't loaded, so it tries to load them, you call views_get_view. Repeat ad infinitum.

To get a default view from another module in that situation, you are going to need to get your view from the other module directly. Try $views = module_invoke('modulename', 'views_default_views'), and then you'll have an array of all views that module provides. It will only work if your module has a higher weight (i.e, runs after) the previous module, or its *.views_default.inc file may not have been loaded.

tayzlor’s picture

brilliant, that works a treat =) .
that makes views really powerful by being able to extend them in this way!

one small hitch is if i try to add arguments using $view->add_item to the view inside the view_default_views() function it throws an error.

Fatal error: view::get_path() [<a href='function.view-get-path'>function.view-get-path</a>]: The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition &quot;views_plugin_display_default&quot; of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition in C:\Boston\Defaqto Websites\www\sites\all\modules\contribs\views\includes\view.inc on line 1040

note: this error only occurs if you go in to admin/build/views and click to 'edit' the view, then try to click 'list' to take you back to admin/build/views.

also, if you clear caches, the error disappears until you try to do the same again.

I want my extended arguments that i intend to add to the view to be available to the default view for services, should i be adding them elsewhere via a different function? or is there another technique to programmatically add the arguments other than $view->add_item inside views_default_views() in order for this to work?

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.

tayzlor’s picture

Status: Closed (fixed) » Active

bumping this, no resolution as yet =(

merlinofchaos’s picture

You will need to turn off caching on the views tools page.

domesticat’s picture

Status: Active » Closed (fixed)

Closed while closing all Views support requests with no activity for 6 months. If you still need help, you may re-open this issue at any time.

jonskulski’s picture

Status: Closed (fixed) » Active

I am trying to add an argument programatically and set it. I am having a very difficult time acheiving this. I don't have a clear understanding of when this is supposed to happen, so I am sure that is why I am having trouble.

I have tried using add_item in both pre_build and pre_view like this:

$items = $view->add_item($view->current_display, 'argument', 'node', 'nid', $options);

with $options being a var_export of options from a node: nid arugment view I set up through the UI. A subsequent call to

$items = $view->get_items('argument');

Gives me back what I put in. Perhaps a good sign.

Where things go wrong is that in _build_arguments() of view.inc there is a check at the top

 427     if (empty($this->argument)) {
 428       return TRUE;
 429     }

that fails for my added argument. I don't see in the code where this is ever set. I can't seem to get argument set via this method.

Any information would be appreciated.

Letharion’s picture

Status: Active » Closed (fixed)

@jonskulski
While your question is very similar to the original one, this issue had been closed for nearly a year when you re-opened it. This is only confusing. If you still need help, please open a new issue.

merlinofchaos’s picture

The question can be answered pretty easily -- using add_item() on an already initialized view won't work. Once init_handlers() have been called, the handlers are instantiated and add_item() does not work for you.

At that point, you have to instantiate your handler object directly and add it to $view->argument[]