I'd like a way to alter the options of a handler. For instance a Field might have an extra access option, or a Filter an extra condition.

The logic to use the option is doable in other views hooks, like hook_views_query_alter() or hook_views_pre_build(), for any module, but an outside module can't add options to the Field or Filter handler.

Views very cleverly uses option_definition() to clean up handler options before saving, and when exporting, but this means handlers aren't extensible.

My solution is very simple: add an option_definition alter to allow any module to add options, or change defaults.

Adding form, validate and submit alters aren't even necessary, because the outside module can do that with normal form alters.

Comments

rudiedirkx created an issue. See original summary.

rudiedirkx’s picture

Status: Active » Needs review
FileSize
2.11 KB

Patch adds a method altered_option_definition() to wrap around option_definition() to alter the result. Since it's executed for handlers and plugins, it calls 2 different alters:

  • views_plugin_option_definition
  • views_handler_option_definition

Since it's to high up in the Views process, not much changes.

I ran a few performance tests and on big views, or pages with several views, the total time spent altering (with 0 implementations) is 1.5 ms.

flaviovs’s picture

Do you have any pointers about how this is a standard idiom to alter views handlers options? Any other module doing this?

IMHO, the right way to do this would be to use hook_views_data_alter() to plug in your our handler, which would be a subclass of the handler with the method(s) you want to override. In this specific case, you would override the option_definition().

This requires no patch. And it's plain simple, effective, and elegant, isn't?

rudiedirkx’s picture

I don't know of any other module needing this, but I've needed it a few times in different projects. Sometimes it could be solved with a Display Extender, sometimes with a new Field/Filter handler etc. It was always easier to add options. This time I went for it.

Your solution is very elegant, and correct, but there are SOOO many handlers, I can't override them all, and that's exactly what I want. In this case I want to add an access fieldset & options to all fields and filters, to hide/disable them for different users & context.

It's also a good way to change views defaults, see #1244576: Consider allowing configuration of the default options for field handlers.

rudiedirkx’s picture

Project: Views image » Views
Version: » 7.x-3.x-dev

Crap. I didn't mean Views image, I meant Views.

flaviovs’s picture

:-)

BTW, one thing that came to mind: what's the purpose of altering option_definition() only?

I mean, OK, you'll be able to add options here and there, and now what? How do you process them? How do you make them useful?

You'd need to alter other methods, don't you?

I still think that sub-classing a handler is the API-wise way to go.

rudiedirkx’s picture

The rest of the methods, you can form-alter and views-hook. I've used it in Views Arguments for adding access options to all Fields and Filters, using a normal form alter. Then in hook_views_pre_build I use those options. Because they're real options, they have defaults and are exported and imported. You can't add options without option_definition.

It'd be very very nice if there were such a thing as Display Extender for all handlers. Maybe Field Extender or Handler Extender.

Sub classing is impossible. I need ALL handlers, including all contrib etc.

rudiedirkx’s picture

It would be much nicer to have hooks for the form/validate/submit too though... What I do now is

  1. hook_form_views_ui_config_item_form_alter() extends form and adds #element_validate
  2. #element_validate validates and rewrites values and saves it back info $form_state

See http://cgit.drupalcode.org/views_arguments/tree/views_arguments.module?h...

The access plugin is much cleaner, using options_form(), options_validate() and options_submit()

See http://cgit.drupalcode.org/views_arguments/tree/views/views_arguments_pl...

MustangGB’s picture

Status: Needs review » Reviewed & tested by the community

I encountered the same issue, needing to extend every single field handler to add a new option to the base class seems like lunacy, especially considering that everything else, excluding option_definition(), can be hooked.

Patch does the job advertised perfectly.

DamienMcKenna’s picture

Status: Reviewed & tested by the community » Needs work

This needs an update to views.api.php.

MustangGB’s picture

Status: Needs work » Needs review
FileSize
4.3 KB

So I don't profess to being that great at writing docs, but I gave it a go.

rudiedirkx’s picture

Status: Needs review » Needs work

I like it. If you add some @param and @return it's perfect IMO. And maybe a more realistic example in the hook itself. Maybe something that illustrates the difference between a plugin and a handler.

MustangGB’s picture

If you add some @param and @return it's perfect IMO.

I've added @param, but as alter functions don't return anything I don't think @return is needed.

And maybe a more realistic example in the hook itself. Maybe something that illustrates the difference between a plugin and a handler.

Suggestions on a postcard please, the example is almost exactly what I'm using for my use-case.

rudiedirkx’s picture

Status: Needs work » Reviewed & tested by the community

I don't know a good example =) I like it. Maybe @DamienMcKenna will like it too.

DamienMcKenna’s picture

Status: Reviewed & tested by the community » Needs work

One very minor thing, altered_option_definition() needs an explanation of its @return.

MustangGB’s picture

Status: Needs work » Needs review
FileSize
4.9 KB

Updated block comment for altered_option_definition().

MustangGB’s picture

Waiting for DamienMcKenna's review, in the meantime adding to #2866162: Plan for Views 7.x-3.17 release so it doesn't get lost/forgotten.

MustangGB’s picture