[SOLVED] Overriding the Reference Application Login Page & Controller with a Custom One

Module: Reference Application

Module Version: 2.3

System Version: 1.11.5

Issue or Question: How can I replace the current version of the home page and login controller with my own without having to hack the reference application module to release my own? I have added a mapping to the /login.htm page but it is being ignored while the reference application one is being displayed

2 Likes

I don’t believe this is possible, with the current codebase.

The idea is that you would fork the reference application module, and modify just the login.gsp file. (And if you aren’t making other modifications, you can pull in changes from upstream easily.)

If the changes you want to make can be covered purely with additional CSS, there is another way to inject that, but I presume that’s not what you mean.

@darius I have tried setting up a filter to catch calls to /login.htm before they are executed by the Reference Application Servlet however my filter mapping is being ignored from my module config file - is there anything special that I have to do to get my module filter to be activated by OpenMRS?

I think you can do some ‘aggressive’ things to achieve this, how about the following:

  • Registering a filter that intercepts requests for the home and login pages and redirects them.
  • Introducing a new spring URL handler mapping with a higher priority than those in core that handles mappings to the home and login pages which are backed by a custom controller that does something different OR you could possibly use spring’s handler interceptors for this handler mapping, if the handlers in core supported interceptors this would have been the straight forward thing to do.
  • Adding some before advice around the reference application home and login page controller methods that forwards the requests to a custom controller. I would assume AOP can work for any class and method

@wyclif I am doing the first one. How do I achieve the second one registering a handler with higher priority?

In core there is this DefaultAnnotationHandlerMapping which has a higher priority than SimpleUrlHandlerMapping which makes it possible for annotated controllers to override xml based ones, i think along these lines you can add another either DefaultAnnotationHandlerMapping or SimpleUrlHandlerMapping bean with a higher priority than both of these, note that the order property is what determines the priority where a lower order value implies higher priority and vice versa This page shows how you add a url handler mapping from a module to override a page, but note that your scenario is a little different in that you’re trying to override a page that’s already overriden, so you might need more tweaks.

Again, I recommend that instead of jumping through these hoops, you just fork the referenceapplication module and change the one gsp page there. (And, of course, regularly pull in updates from upstream.)

@darius I am trying look for options that will help future maintainers of the distribution across a multitude of facilities, and would fork as a last option as that increases the burden for updates. Given there are some installations with 1.6.0 - there is a precedence of longevity of deployed code.

1 Like

For details on how to approach it see [SOLVED] Overriding Module Fragments in other modules

This involves:

  1. Creating a PageRequestMapper that maps the referenceapplication/login.page to a new url

  2. Creating a custom page, but do not use the @Controller tag on the page controller as Spring does not allow multiple controllers to be mapped to the same url

@ssmusoke, for future reference, could you update this FAQ to describe this new and better way of doing things?

@darius I am working on it even with a demo module to illustrate an example that can be followed hope to complete this week

@darius took longer than planned but updated the FAQ and added a new page https://wiki.openmrs.org/display/docs/Overriding+Requests+to+Pages+and+Fragments

1 Like

@ssmusoke thanks for this. While this works, I noticed that the url does not change. So when I intercept the home page and show my custom page the URL still remains http://localhost:8080/openmrs/referenceapplication/home.page even though what’s displayed is my own page. Now which controller will be backing that page? Is it the one from referenceapplication or my custom controller?

@ivange94 it would be your custom controller since it is being redirected without changing the url

Yeah you are right. Not sure why but In my mind i was thinking that POST request will post on the url that’s on the browser. Forgot that you can specify a URL via javascript or using the forms action attribute.

@ivange94 That is the difference between an HTTP forward and redirect - the forward uses the same url that was originally used while the redirect changes the url to the new one

1 Like

@ssmusoke seems it’s not my controller that’s called after all. I’ve added a controller and I noticed I’m getting UI errors because of missing properties that should be there. When I debug the module and place a breakpoint in my controller module and refresh my breakpoint is never hit.

Can’t advise without seeing the code