# Access to request object from within tags (answer?)

**URL:** <https://www.ruby-forum.com/t/access-to-request-object-from-within-tags-answer/83444>\
**Category:** Radiant CMS\
**Created:** [January 26, 2007, 3:16am UTC](https://www.ruby-forum.com/t/access-to-request-object-from-within-tags-answer/83444 "2007-01-26T03:16:52Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Kaleb\_Walton](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/779978/32.png) [@Kaleb\_Walton](https://www.ruby-forum.com/u/Kaleb_Walton)\
**Post date:** [January 26, 2007, 3:16am UTC](https://www.ruby-forum.com/t/access-to-request-object-from-within-tags-answer/83444/1 "2007-01-26T03:16:52Z")

</div>

Well, I spoke 5 minutes too soon. I tried a few more things and found  
out how to get it to work - now this may be completely wrong on a  
number of levels but this got me the request within snippets that  
previously had a nil request.

Does anyone know any ramifications of doing this? I haven’t yet  
checked if it will break caching… we’ll see about that.

I notated the lines I changed or added with a \<----

In page\_context.rb

def initialize(page, request)  
super()

```
@page = page
globals.request = request <----
globals.page = @page

```

… …

define\_tag ‘snippet’ do |tag|  
if name = tag.attr[‘name’]  
if snippet = Snippet.find\_by\_name(name.strip)  
page = tag.locals.page  
page.behavior.request = tag.globals.request \<----  
page.behavior.render\_snippet(snippet)  
else  
raise TagError.new(‘snippet not found’)  
end  
else  
raise TagError.new(“`snippet' tag must contain`name’ attribute”)  
end  
end

behavior.rb

def lazy\_initialize\_parser\_and\_context  
unless @context and @parser  
@context = PageContext.new(@page, @request) \<----  
self.class.additional\_tag\_definition\_blocks.each { |block|  
instance\_eval &block }  
add\_tags\_from\_parent\_to\_context  
@parser = Radius::Parser.new(@context, :tag\_prefix =\> ‘r’)  
end  
end

---

<div class="post-metadata">

**Author:** ![Kaleb\_Walton](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/779978/32.png) [@Kaleb\_Walton](https://www.ruby-forum.com/u/Kaleb_Walton)\
**Post date:** [January 26, 2007, 2:57pm UTC](https://www.ruby-forum.com/t/access-to-request-object-from-within-tags-answer/83444/2 "2007-01-26T14:57:27Z")

</div>

Kaleb,

Interesting technique. I don’t think you have to worry about it  
breaking  
caching. If your page/behavior is very dynamic, I would just make it  
uncached. Interestingly enough, in mental you have complete access to  
the  
request and response variables because your tag definitions are defined  
inside the Page model rather than in PageContext.

Sean

---

<div class="post-metadata">

**Author:** ![Kaleb\_Walton](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/779978/32.png) [@Kaleb\_Walton](https://www.ruby-forum.com/u/Kaleb_Walton)\
**Post date:** [January 26, 2007, 3:12pm UTC](https://www.ruby-forum.com/t/access-to-request-object-from-within-tags-answer/83444/3 "2007-01-26T15:12:30Z")

</div>

I’m quite unfamiliar with Mental and only recently started working  
with Radiant - I’ll look into Mental to see if it meets my needs.  
Thanks!

---

<div class="post-metadata">

**Author:** ![Kaleb\_Walton](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/779978/32.png) [@Kaleb\_Walton](https://www.ruby-forum.com/u/Kaleb_Walton)\
**Post date:** [January 30, 2007, 10:53pm UTC](https://www.ruby-forum.com/t/access-to-request-object-from-within-tags-answer/83444/4 "2007-01-30T22:53:46Z")

</div>

Kaleb Walton wrote:

> I’m quite unfamiliar with Mental and only recently started working  
> with Radiant - I’ll look into Mental to see if it meets my needs.  
> Thanks!

Hi I’m fighting this too on Mental.  
My problem is that included pages (via r:find) have no access to the  
request.  
This is because in app/models/page.rb Page stores the request into  
instance  
variables, but the find tag will construct a new page - and since nobody  
will call  
process(request, response) on that, it will have these instance  
variables left on nil.

I tried to fix this in an extension, I “reopened” the Page class and  
clobbered the request= and request definitions with a new implementation  
wich stores into a class level variable.  
This is almost ok, except that the process() call is not very nice, and  
accesses  
the @request directly and not via the attr\_writer function, so I had to  
clobber  
that too.

This works if I edit page.rb directly, but when I try to “reopen” the  
class,  
and rewrite a few functions mysterious failures pop up - like no layout  
being  
rendered, broken admin pages… etc.

Please someone smarter than me: What is wrong with this:  
in vendor/extensions/example/app/models/page.rb

require “app/models/page”  
class Page \< ActiveRecord::Base  
@@request = nil  
def request= rq  
@@request = rq  
end  
def request  
@@request  
end  
def process(request, response)  
self.request = request  
self.response = response  
if layout  
content\_type = layout.content\_type.to\_s.strip  
@response.headers[‘Content-Type’] = content\_type unless  
content\_type.empty?  
end  
headers.each { |k,v| @response.headers[k] = v }  
@response.body = render  
self.request = nil  
self.response = nil  
end  
end

I do require this file from the example\_extension.rb so it does run

My guess is that some magic must be happening inside Page with the  
subclasses  
which prevent me from successfully patch it from an extension.

---

<div class="post-metadata">

**Author:** ![Kaleb\_Walton](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/779978/32.png) [@Kaleb\_Walton](https://www.ruby-forum.com/u/Kaleb_Walton)\
**Post date:** [January 31, 2007, 4:04am UTC](https://www.ruby-forum.com/t/access-to-request-object-from-within-tags-answer/83444/5 "2007-01-31T04:04:22Z")

</div>

> Hi I’m fighting this too on Mental.  
> My problem is that included pages (via r:find) have no access to the  
> request.  
> This is because in app/models/page.rb Page stores the request into  
> instance  
> variables, but the find tag will construct a new page - and  
> since nobody  
> will call  
> process(request, response) on that, it will have these instance  
> variables left on nil.

Do you need access to the request from the page objects or from the  
tags? If it’s just the tags:

class PageContext  
alias \_\_old\_initialize initialize

def initialize(page)  
\_\_old\_initialize(page)  
globals.request = page.request  
end  
end

If you need it set on the page object for one of your tags to work, just  
do the setting in that tag.

Dan.

---

<div class="post-metadata">

**Author:** ![Kaleb\_Walton](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/779978/32.png) [@Kaleb\_Walton](https://www.ruby-forum.com/u/Kaleb_Walton)\
**Post date:** [January 30, 2007, 11:08pm UTC](https://www.ruby-forum.com/t/access-to-request-object-from-within-tags-answer/83444/6 "2007-01-30T23:08:50Z")

</div>

Storing the request at a class level is a very bad idea. At least I  
think it is…

Isn’t it possible that the same class could be used for multiple  
requests?

It sounds to me like any solution would have to involve directly  
populating the request on the found pages within the tag definitions for  
r:find and r:children.

---

<div class="post-metadata">

**Author:** ![Kaleb\_Walton](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/779978/32.png) [@Kaleb\_Walton](https://www.ruby-forum.com/u/Kaleb_Walton)\
**Post date:** [February 1, 2007, 4:52pm UTC](https://www.ruby-forum.com/t/access-to-request-object-from-within-tags-answer/83444/7 "2007-02-01T16:52:11Z")

</div>

Daniel!

Thanks for trying to help.

I must admit my ruby-kungfu is weak.

Your suggestion on letting the tag know about the request seems to be  
right,  
but when I did what you suggested:

require “app/models/page\_context”  
class PageContext  
alias initialize\_before\_reformhaz initialize

def initialize(page)  
initialize\_before\_reformhaz(page)  
globals.request = page.request  
end  
end

in my reformhaz\_extansion.rb

I got

SystemStackError in SiteController#show\_page  
stack level too deep  
vendor/extensions/reformhaz/reformhaz\_extension.rb:29:in  
`initialize_before_reformhaz' vendor/extensions/reformhaz/reformhaz_extension.rb:29:in`initialize\_before\_reformhaz’  
vendor/extensions/reformhaz/reformhaz\_extension.rb:29:in `initialize' app/models/page.rb:226:in`lazy\_initialize\_parser\_and\_context’  
app/models/page.rb:126:in `render' app/models/page.rb:121:in`process’

Since I have a similar experience with reopening and redefining methods  
in the Page class, albeit that explodes in a different way, I just  
boldly edited PageContext directly to have-a-look.

The exact situation is : root page \<r:find\>s the products page and  
renders  
it’s body. The outcome is the same: the tags in product can’t read the  
request  
to determine the offset and length. It’s only okay if I redirect to  
/products  
and the first page that gets dug up from the db is my ProductPage.  
I guess I would have to tweak r:find too to pass down the info to the  
found one.  
(the way Kaleb did with the snippet up front)

The other way is to hack Page to store the request in a class variable.  
This isn’t bad -methinks- since we have the luxury of having our whole  
process to answer a lonely request. Another request gets it’s own  
interpreter.

You’re right about that I might just need my own controller to handle  
the  
search-paging request, and then feed the params to the tags, but so far  
I can  
only do this for the directly requested page.

My only true headache is: I just can’t reliably redefine methods in Page  
and  
PageContext. On SiteController on the other hand it does work. Why?

Daniel S. wrote:

> Do you need access to the request from the page objects or from the  
> tags? If it’s just the tags:
> 
> class PageContext  
> alias \_\_old\_initialize initialize
> 
> def initialize(page)  
> \_\_old\_initialize(page)  
> globals.request = page.request  
> end  
> end
> 
> If you need it set on the page object for one of your tags to work, just  
> do the setting in that tag.
> 
> Dan.

---

<div class="post-metadata">

**Author:** ![Kaleb\_Walton](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/779978/32.png) [@Kaleb\_Walton](https://www.ruby-forum.com/u/Kaleb_Walton)\
**Post date:** [February 2, 2007, 12:18am UTC](https://www.ruby-forum.com/t/access-to-request-object-from-within-tags-answer/83444/8 "2007-02-02T00:18:33Z")

</div>

> in my reformhaz\_extansion.rb
> 
> I got
> 
> SystemStackError in SiteController#show\_page  
> stack level too deep  
> vendor/extensions/reformhaz/reformhaz\_extension.rb:29:in  
> `initialize\_before\_reformhaz’

The problem is the aliasing, which is happening each time your extension  
is loading (so on the second load, it re-aliased your new method to  
initialize\_before\_reformaz, so the your method ended up calling itself).

Try:

class PageContent  
unless method\_defined? :\_\_initialize\_before\_reformhaz  
alias initialize\_before\_reformhaz initialize

```
def initialize(page)
  __initialize_before_reformhaz(page)
  globals.request = page.request
end

```

end  
end

Dan.
