Getting the controller name from a given URL

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

Getting the controller name from a given URL

GavinHogan2
Hi

I am looking into some click capture I want to do within my app and want to record what controller (if any) a user if coming FROM by parsing the referer uri.  I can get the referer easily but cannot determine the best way to parse it such that I can extract the grails-centric info such as controllerName, actionName etc.

I have tried the following in the console plugin and gotten unexpected response.

ctx.grailsUrlMappingsHolder.match('/user/view/4e83d6e3c519737614f34ad0').controllerName
Prints : "console"
I Expect : "user"

ctx.grailsUrlMappingsHolder.match('/user/view/4e83d6e3c519737614f34ad0').actionName
Prints : "execute"
I Expect : "view"


So it seems to be matching the current controller.  

What is the right way to achieve this.

Thanks

Gavin

Reply | Threaded
Open this post in threaded view
|

Re: Getting the controller name from a given URL

Jeff Scott Brown
On Mon, Feb 6, 2012 at 2:52 PM, Gavin Hogan <[hidden email]> wrote:

> Hi
>
> I am looking into some click capture I want to do within my app and want to
> record what controller (if any) a user if coming FROM by parsing the referer
> uri.  I can get the referer easily but cannot determine the best way to
> parse it such that I can extract the grails-centric info such as
> controllerName, actionName etc.
>
> I have tried the following in the console plugin and gotten unexpected
> response.
>
> ctx.grailsUrlMappingsHolder.match('/user/view/4e83d6e3c519737614f34ad0').controllerName
> Prints : "console"
> I Expect : "user"
>
> ctx.grailsUrlMappingsHolder.match('/user/view/4e83d6e3c519737614f34ad0').actionName
> Prints : "execute"
> I Expect : "view"
>
>
> So it seems to be matching the current controller.
>
> What is the right way to achieve this.
>

The question is a little unclear to me.  If for a given request you
want to know what controller the request is heading to, you may be
able to use a filter, something like this:


// grails-app/conf/MyDemoFilters.groovy
class MyDemoFilters {

    def filters = {
        all(controller:'*', action:'*') {
            before = {
                println "Controller: ${controllerName}"
            }
        }
    }
}

Does that help accomplish whatever it is you are trying to do?

The original note says that you want to know "what controller (if any)
a user if coming FROM".  It isn't clear to me what you mean by that.

Let me know if the filter approach works well for your use case.



jb


--
Jeff Brown
SpringSource
http://www.springsource.com/

Autism Strikes 1 in 166
Find The Cause ~ Find The Cure
http://www.autismspeaks.org/

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Getting the controller name from a given URL

GavinHogan2
Jeff thanks for the reply.  I am aware that the current request is easy to parse as you illustrated above but what I want to do differs slightly. I have several scenarios for wanting to do this, the primary one is to track user pathways across my application.  I would like to answer questions such as what page was a user on when he clicked a link to come to execute this action - sort of rudimentary A/B Testing.  Taking your code above I have expanded it a bit.

// grails-app/conf/MyDemoFilters.groovy
class MyDemoFilters {

   def filters = {
       all(controller:'*', action:'*') {
           before = {
               def refUrl = request.getHeader('referer') 
               //I get something like this...
               println "Referring Controller: ${AwesomeGrailsURLParser.parse(refURL).controllerName}"
               println "Referring Action: ${AwesomeGrailsURLParser.parse(refURL).actionName}"
               println "Controller: ${controllerName}"
           }
       }
   }
}

I would like to use grails to extract the controllerName and actionName becuase our app often uses UrlMappings.

Thanks

Gavin


On Mon, Feb 6, 2012 at 6:13 PM, Jeff Brown <[hidden email]> wrote:
On Mon, Feb 6, 2012 at 2:52 PM, Gavin Hogan <[hidden email]> wrote:
> Hi
>
> I am looking into some click capture I want to do within my app and want to
> record what controller (if any) a user if coming FROM by parsing the referer
> uri.  I can get the referer easily but cannot determine the best way to
> parse it such that I can extract the grails-centric info such as
> controllerName, actionName etc.
>
> I have tried the following in the console plugin and gotten unexpected
> response.
>
> ctx.grailsUrlMappingsHolder.match('/user/view/4e83d6e3c519737614f34ad0').controllerName
> Prints : "console"
> I Expect : "user"
>
> ctx.grailsUrlMappingsHolder.match('/user/view/4e83d6e3c519737614f34ad0').actionName
> Prints : "execute"
> I Expect : "view"
>
>
> So it seems to be matching the current controller.
>
> What is the right way to achieve this.
>

The question is a little unclear to me.  If for a given request you
want to know what controller the request is heading to, you may be
able to use a filter, something like this:


// grails-app/conf/MyDemoFilters.groovy
class MyDemoFilters {

   def filters = {
       all(controller:'*', action:'*') {
           before = {
               println "Controller: ${controllerName}"
           }
       }
   }
}

Does that help accomplish whatever it is you are trying to do?

The original note says that you want to know "what controller (if any)
a user if coming FROM".  It isn't clear to me what you mean by that.

Let me know if the filter approach works well for your use case.



jb


--
Jeff Brown
SpringSource
http://www.springsource.com/

Autism Strikes 1 in 166
Find The Cause ~ Find The Cure
http://www.autismspeaks.org/

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

   http://xircles.codehaus.org/manage_email



Reply | Threaded
Open this post in threaded view
|

Re: Getting the controller name from a given URL

Octavian Covalschi
I may be totally off here, but have you thought using interceptors? You could have  a BaseController where you'd define your beforeInterceptor and extend all your controllers that would like to track... this way you'll be able to use grails to determine actions and controllers...

 

On Mon, Feb 6, 2012 at 7:43 PM, Gavin Hogan <[hidden email]> wrote:
Jeff thanks for the reply.  I am aware that the current request is easy to parse as you illustrated above but what I want to do differs slightly. I have several scenarios for wanting to do this, the primary one is to track user pathways across my application.  I would like to answer questions such as what page was a user on when he clicked a link to come to execute this action - sort of rudimentary A/B Testing.  Taking your code above I have expanded it a bit.

// grails-app/conf/MyDemoFilters.groovy
class MyDemoFilters {

   def filters = {
       all(controller:'*', action:'*') {
           before = {
               def refUrl = request.getHeader('referer') 
               //I get something like this...
               println "Referring Controller: ${AwesomeGrailsURLParser.parse(refURL).controllerName}"
               println "Referring Action: ${AwesomeGrailsURLParser.parse(refURL).actionName}"
               println "Controller: ${controllerName}"
           }
       }
   }
}

I would like to use grails to extract the controllerName and actionName becuase our app often uses UrlMappings.

Thanks

Gavin


On Mon, Feb 6, 2012 at 6:13 PM, Jeff Brown <[hidden email]> wrote:
On Mon, Feb 6, 2012 at 2:52 PM, Gavin Hogan <[hidden email]> wrote:
> Hi
>
> I am looking into some click capture I want to do within my app and want to
> record what controller (if any) a user if coming FROM by parsing the referer
> uri.  I can get the referer easily but cannot determine the best way to
> parse it such that I can extract the grails-centric info such as
> controllerName, actionName etc.
>
> I have tried the following in the console plugin and gotten unexpected
> response.
>
> ctx.grailsUrlMappingsHolder.match('/user/view/4e83d6e3c519737614f34ad0').controllerName
> Prints : "console"
> I Expect : "user"
>
> ctx.grailsUrlMappingsHolder.match('/user/view/4e83d6e3c519737614f34ad0').actionName
> Prints : "execute"
> I Expect : "view"
>
>
> So it seems to be matching the current controller.
>
> What is the right way to achieve this.
>

The question is a little unclear to me.  If for a given request you
want to know what controller the request is heading to, you may be
able to use a filter, something like this:


// grails-app/conf/MyDemoFilters.groovy
class MyDemoFilters {

   def filters = {
       all(controller:'*', action:'*') {
           before = {
               println "Controller: ${controllerName}"
           }
       }
   }
}

Does that help accomplish whatever it is you are trying to do?

The original note says that you want to know "what controller (if any)
a user if coming FROM".  It isn't clear to me what you mean by that.

Let me know if the filter approach works well for your use case.



jb


--
Jeff Brown
SpringSource
http://www.springsource.com/

Autism Strikes 1 in 166
Find The Cause ~ Find The Cure
http://www.autismspeaks.org/

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

   http://xircles.codehaus.org/manage_email




Reply | Threaded
Open this post in threaded view
|

Re: Getting the controller name from a given URL

GavinHogan2
Thanks Octvian, I think beforeInterceptors would give me the same tools that the filter does.  

I just want to a way to take an arbitrary URL and determine if it matches a particular grails controller and action I also want the benefit of UrlMappings, otherwise I would be happy to roll my own.

Thanks

Gavin

 

On Mon, Feb 6, 2012 at 9:26 PM, Octavian Covalschi <[hidden email]> wrote:
I may be totally off here, but have you thought using interceptors? You could have  a BaseController where you'd define your beforeInterceptor and extend all your controllers that would like to track... this way you'll be able to use grails to determine actions and controllers...

 

On Mon, Feb 6, 2012 at 7:43 PM, Gavin Hogan <[hidden email]> wrote:
Jeff thanks for the reply.  I am aware that the current request is easy to parse as you illustrated above but what I want to do differs slightly. I have several scenarios for wanting to do this, the primary one is to track user pathways across my application.  I would like to answer questions such as what page was a user on when he clicked a link to come to execute this action - sort of rudimentary A/B Testing.  Taking your code above I have expanded it a bit.

// grails-app/conf/MyDemoFilters.groovy
class MyDemoFilters {

   def filters = {
       all(controller:'*', action:'*') {
           before = {
               def refUrl = request.getHeader('referer') 
               //I get something like this...
               println "Referring Controller: ${AwesomeGrailsURLParser.parse(refURL).controllerName}"
               println "Referring Action: ${AwesomeGrailsURLParser.parse(refURL).actionName}"
               println "Controller: ${controllerName}"
           }
       }
   }
}

I would like to use grails to extract the controllerName and actionName becuase our app often uses UrlMappings.

Thanks

Gavin


On Mon, Feb 6, 2012 at 6:13 PM, Jeff Brown <[hidden email]> wrote:
On Mon, Feb 6, 2012 at 2:52 PM, Gavin Hogan <[hidden email]> wrote:
> Hi
>
> I am looking into some click capture I want to do within my app and want to
> record what controller (if any) a user if coming FROM by parsing the referer
> uri.  I can get the referer easily but cannot determine the best way to
> parse it such that I can extract the grails-centric info such as
> controllerName, actionName etc.
>
> I have tried the following in the console plugin and gotten unexpected
> response.
>
> ctx.grailsUrlMappingsHolder.match('/user/view/4e83d6e3c519737614f34ad0').controllerName
> Prints : "console"
> I Expect : "user"
>
> ctx.grailsUrlMappingsHolder.match('/user/view/4e83d6e3c519737614f34ad0').actionName
> Prints : "execute"
> I Expect : "view"
>
>
> So it seems to be matching the current controller.
>
> What is the right way to achieve this.
>

The question is a little unclear to me.  If for a given request you
want to know what controller the request is heading to, you may be
able to use a filter, something like this:


// grails-app/conf/MyDemoFilters.groovy
class MyDemoFilters {

   def filters = {
       all(controller:'*', action:'*') {
           before = {
               println "Controller: ${controllerName}"
           }
       }
   }
}

Does that help accomplish whatever it is you are trying to do?

The original note says that you want to know "what controller (if any)
a user if coming FROM".  It isn't clear to me what you mean by that.

Let me know if the filter approach works well for your use case.



jb


--
Jeff Brown
SpringSource
http://www.springsource.com/

Autism Strikes 1 in 166
Find The Cause ~ Find The Cure
http://www.autismspeaks.org/

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

   http://xircles.codehaus.org/manage_email





Reply | Threaded
Open this post in threaded view
|

Re: Getting the controller name from a given URL

tomas lin
In reply to this post by GavinHogan2
In one of our projects, we used the afterInterceptor's modelAndView
mechanism to store the visit information we wanted and used this in
subsequent filters. You are guaranteed to have an actionName and
controllerName at that point, so if you just store it in the session,
you can always just query for the last visited controller. Ends up
being cleaner than trying to mess with UrlMapping.


On Mon, Feb 6, 2012 at 8:52 PM, Gavin Hogan <[hidden email]> wrote:

> Hi
>
> I am looking into some click capture I want to do within my app and want to
> record what controller (if any) a user if coming FROM by parsing the referer
> uri.  I can get the referer easily but cannot determine the best way to
> parse it such that I can extract the grails-centric info such as
> controllerName, actionName etc.
>
> I have tried the following in the console plugin and gotten unexpected
> response.
>
> ctx.grailsUrlMappingsHolder.match('/user/view/4e83d6e3c519737614f34ad0').controllerName
> Prints : "console"
> I Expect : "user"
>
> ctx.grailsUrlMappingsHolder.match('/user/view/4e83d6e3c519737614f34ad0').actionName
> Prints : "execute"
> I Expect : "view"
>
>
> So it seems to be matching the current controller.
>
> What is the right way to achieve this.
>
> Thanks
>
> Gavin
>

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Getting the controller name from a given URL

Ian Roberts
In reply to this post by GavinHogan2
On 06/02/2012 20:52, Gavin Hogan wrote:

> I have tried the following in the console plugin and gotten unexpected
> response.
>
> ctx.grailsUrlMappingsHolder.match('/user/view/4e83d6e3c519737614f34ad0').controllerName
> Prints : "console"
> I Expect : "user"
>
> ctx.grailsUrlMappingsHolder.match('/user/view/4e83d6e3c519737614f34ad0').actionName
> Prints : "execute"
> I Expect : "view"

Strange.  When I try the same thing running "grails console" (i.e. the
Swing console, not the web console plugin) I get the correct answers.
Have you tried this approach within your own controllers/services or
only in the web console?

The UrlMappingsHolder is definitely the way to go, but remember that
match() will only give you the first matching mapping whether or not
there's a real controller with that name (i.e. if you have a
/$controller/$action/$id mapping then /foo/bar/baz will match this even
if you don't have a FooController with a bar action).  The
UrlMappingsFilter does a matchAll and then works down the list until it
finds a controller that can handle the URI, you'd have to do something
similar which will rapidly get complex...

Ian

--
Ian Roberts               | Department of Computer Science
[hidden email]  | University of Sheffield, UK

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Getting the controller name from a given URL

GavinHogan2
Thomas, thanks for the suggestion; I was looking to avoid storing stuff in the session but this is getting ugly.

Ian, thanks for confirming that it works for you as I expected it to. I tried it within a controller and a service and it reports the current controller each time.  Also when I tried it in the swing console I get an except due to the lack of a webrequest being tied to the current thread. These tests are with Grails 2

Weird. (too weird)

Gavin





On Tue, Feb 7, 2012 at 12:59 PM, Ian Roberts <[hidden email]> wrote:
On 06/02/2012 20:52, Gavin Hogan wrote:
> I have tried the following in the console plugin and gotten unexpected
> response.
>
> ctx.grailsUrlMappingsHolder.match('/user/view/4e83d6e3c519737614f34ad0').controllerName
> Prints : "console"
> I Expect : "user"
>
> ctx.grailsUrlMappingsHolder.match('/user/view/4e83d6e3c519737614f34ad0').actionName
> Prints : "execute"
> I Expect : "view"

Strange.  When I try the same thing running "grails console" (i.e. the
Swing console, not the web console plugin) I get the correct answers.
Have you tried this approach within your own controllers/services or
only in the web console?

The UrlMappingsHolder is definitely the way to go, but remember that
match() will only give you the first matching mapping whether or not
there's a real controller with that name (i.e. if you have a
/$controller/$action/$id mapping then /foo/bar/baz will match this even
if you don't have a FooController with a bar action).  The
UrlMappingsFilter does a matchAll and then works down the list until it
finds a controller that can handle the URI, you'd have to do something
similar which will rapidly get complex...

Ian

--
Ian Roberts               | Department of Computer Science
[hidden email]  | University of Sheffield, UK

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

   http://xircles.codehaus.org/manage_email



Reply | Threaded
Open this post in threaded view
|

Re: Getting the controller name from a given URL

GavinHogan2
For the sake of anyone who reads this later.  

The answer was simple enough, I just needed to look within the params
property or the returned DefaultUrlMappingInfo instance.


assert
ctx.grailsUrlMappingsHolder.match('/myController/myView/4e83d6e3c519737614f34ad0').params.controller
= 'myController'

assert
ctx.grailsUrlMappingsHolder.match('/myController/myView/4e83d6e3c519737614f34ad0').params.view
= 'myView'


etc.






--
View this message in context: http://grails.1312388.n4.nabble.com/Getting-the-controller-name-from-a-given-URL-tp4362768p4638963.html
Sent from the Grails - user mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Getting the controller name from a given URL

GavinHogan2
In reply to this post by GavinHogan2
For the sake of anyone who reads this later.  

The answer was simple enough, I just needed to look within the params property or the returned DefaultUrlMappingInfo instance.


assert ctx.grailsUrlMappingsHolder.match('/myController/myView/4e83d6e3c519737614f34ad0').params.controller == 'myController'

assert ctx.grailsUrlMappingsHolder.match('/myController/myView/4e83d6e3c519737614f34ad0').params.view == 'myView'


etc.
Reply | Threaded
Open this post in threaded view
|

Re: Getting the controller name from a given URL

Mike Powers
Thanks for sharing a solution, this might come in handy down the road. :-)


On Wed, Dec 12, 2012 at 7:59 PM, GavinHogan2 <[hidden email]> wrote:
For the sake of anyone who reads this later.

The answer was simple enough, I just needed to look within the params
property or the returned DefaultUrlMappingInfo instance.


assert
ctx.grailsUrlMappingsHolder.match('/myController/myView/4e83d6e3c519737614f34ad0').params.controller
== 'myController'

assert
ctx.grailsUrlMappingsHolder.match('/myController/myView/4e83d6e3c519737614f34ad0').params.view
== 'myView'


etc.



--
View this message in context: http://grails.1312388.n4.nabble.com/Getting-the-controller-name-from-a-given-URL-tp4362768p4638964.html
Sent from the Grails - user mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email



Reply | Threaded
Open this post in threaded view
|

Re: Getting the controller name from a given URL

zyro
In reply to this post by GavinHogan2
reviving this thread cause i was bitten by this behavior too.

use case: i want to match some uri (/a/b/1) to my urlmappings and see which controller/action would handle that uri. that check is made inside a web request that pointed to a different uri (/x/y/9).

behavior observed:

def info = grailsUrlMappingsHolder.match("/a/b/1")
info.controllerName == "x"
info.actionName == "y"
info.params.controller == "a"
info.params.controller == "b"

--> so it seems as if the urlMappingInfo properties always refer to the currently bound web request (if any), while urlMappingInfo.params contain the resulting values from the matched uri?

i doubt that this behavior is intentional?

thanks for feedback,

zyro