I've managed to add a tab to "My Contact Dashboard". The way I did this was by adding my extension using civix and then a hook_civicrm_tabset hook to my extension.

Now, the URL that my tab button is pointing to is civicrm/contact/view/someaction?qstr. The Contact dashboard is making an AJAX request when I click on a tab button, and the server then returns the HTML code for that tab. But since I haven't added any code for that URL/action yet I'd expect either an error response or some default page. (It seems CiviCRM takes the default page action, civicrm/contact/view/someaction?qstr seems to return the same as civicrm/contact/view?qstr)

Can anyone tell me how to make my extension return the HTML for my newly created tab? Should I implement a hook for this somewhere? Or something else? Or perhaps register a route for civicrm/contact/view/someaction? I found https://wiki.civicrm.org/confluence/display/CRMDOC/How+to+Create+Your+Own+Action ("How To Create Your Own Action") which seems to be pretty close. But it says CiviRules module is required, and an optional module for this(adding my own action)..well, it seems sort of far fetched.

1 Answer 1


It seems CiviCRM takes the default page action, civicrm/contact/view/someaction?qstr seems to return the same as civicrm/contact/view?qstr

Civi's router uses a fallback search. (The wisdom of this can be debated elsewhere - I'm just reporting facts.) For example, if you request civicrm/foo/bar/baz, then it will look for the routes in this order:

  • civicrm/foo/bar/baz
  • civicrm/foo/bar
  • civicrm/foo
  • civicrm

The first matching route will handle the page-request.

Or perhaps register a route for civicrm/contact/view/someaction

If I understand correctly, I believe this is what you want.

Since you mentioned civix, look at Create a Module Extension for instructions to "Add a basic web page". It describes the command civix generate:page <ClassName> <web/path>, which will generate scaffolding for a new route.

Aside: When I first read the title, I interpreted the question to mean "How code different handlers for (GET/POST/PUT/DELETE) HTTP requests?" In case that really is the question: Civi's router doesn't distinguish between HTTP verbs. You can just define one route and then use something like switch($_REQUEST['REQUEST_METHOD']).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.