Does Rails suppports XHTML for views for inline SVG's?


#1

I have following piece of code(which when saved in a file with .xhtml
extension and opened in Mozilla 1.5.0.2 works fine);

SVG within XHTML Demo

You can embed SVG into XHTML, provided that your browser natively implements SVG. E.g. Firefox 1.5 supports most of static SVG.

The SVG part starts below



HELLO cher visiteur


The SVG part ended above

Now I want to use above code, which basically has inline SVG, in rails
view(which has .rhtml extension), the output is not how it is seen in
mozilla directly(using xhtml file mentioned above), which means Rails
doesn’t send the data of rhtml files in xhtml?

What could I possibly do to make rails understand that my .rhtml file is
acutally an .xhtml file with inline svg? or is there any other way I
could
use inline svg’s in rails?

Thanks,

Jatinder


#2

When you access the .rhtml file, are you sure it’s not rendering it
inside a layout? Did you set :layout => false in the render() action on
your controller?

jatinder saundh wrote:

I have following piece of code(which when saved in a file with .xhtml
extension and opened in Mozilla 1.5.0.2 works fine);

SVG within XHTML Demo

You can embed SVG into XHTML, provided that your browser natively implements SVG. E.g. Firefox 1.5 supports most of static SVG.

The SVG part starts below


<svg xmlns=“http://www.w3.org/2000/svg” version=“1.1” width=“400”
height=“300”…

::snip::

Now I want to use above code, which basically has inline SVG, in rails
view(which has .rhtml extension), the output is not how it is seen in
mozilla directly(using xhtml file mentioned above), which means Rails
doesn’t send the data of rhtml files in xhtml?

What could I possibly do to make rails understand that my .rhtml file is
acutally an .xhtml file with inline svg? or is there any other way I
could
use inline svg’s in rails?


#3

jatinder saundh writes:

What could I possibly do to make rails understand that my .rhtml file
is
acutally an .xhtml file with inline svg? or is there any other way I
could
use inline svg’s in rails?

Firefox 1.5 will only handle inline SVG correctly in responses that
were served with a content-type of “application/xhtml+xml”, not in
files that were served as “text/html”. On the other hand, IE gags on
responses served that way completely. So, for my IvyGIS maps with
SVG/VML overlays, I wind up doing this, in a protected method in
application.rb which is invoked by controllers:

# We want to display graphic overlays, as inline SVG if possible.
# For inline SVG to work, Firefox requires that the page be marked
# in the HTTP header as containing "application/xhtml+xml".  But
# IE gags on that.  So, we export that content-type only to browsers
# that explicitly advertise that they support it.

if (@request.env['HTTP_ACCEPT'].match(/application\/xhtml\+xml/))
  @headers['Content-Type'] = "application/xhtml+xml; charset=utf-8"
end

Note that if you do this, Firefox (or the other Gecko-based browser
of your choice) will be a lot stricter about other things, and some
of your other helpers may trip over that.

Working examples available, once again, here:

http://ivygis.justec.co.in/

An alternative might be to use embedded SVG — that is, an
tag which makes the browser make a second request for pure SVG. That
works just fine in views served as plain HTML. The problem with that
is that the SVG is treated as part of a logically separate document
for scripting purposes (like HTML loaded into an

Robert Thau
removed_email_address@domain.invalid


#4

jatinder saundh writes:

Currently in one of my svg files, I have Javascript function which
dynamically updates color of a circle, can I somehow use to ruby(or
some feature of rails, like rjs) instead of javascript to perform the
color
change operation using Ajax; please note that I want to have this
behaviour within files saved as svg.

If you want the behavior within files saved as SVG, then you most
likely don’t want Ajax — that pretty much means going back to
the server to handle the request (as with the autocomplete stuff).
If you don’t want the Javascript cluttering up your templates, you
could write a Ruby template helper to generate it. (Put a function
in the appropriate file in app/helpers, and your templates can
invoke it. If you want more detail, it might be best to look at a
working example; the source code for Typo has lots of them).

rst


#5

Thanks Robert,
The solution of setting the content header to application/xhtml+xml
solved
the problem.
I have one more doubt related to SVG’s; can I have ruby code inside svg
files(files with svg extension).
Currently in one of my svg files, I have Javascript function which
dynamically updates color of a circle, can I somehow use to ruby(or
some feature of rails, like rjs) instead of javascript to perform the
color
change operation using Ajax; please note that I want to have this
behaviour within files saved as svg.

Steve, I am not sure are if it’s not rendering it inside a layout. I did
not set :layout => false in the controller. I am pretty new to rails
hence
not aware of many features of it, can you please explain in a bit more
detail?

Thanks
Jatinder


#6

By default, when Rails performs an action in a controller and serves out
a corresponding RHTML view, it places the view inside the coresponding
layout in app/views/layouts.

This is why views are usually RHTML snippets without the enclosing

, and tags. Those portions of the page are usually part of the layout. The idea is that layouts serve as a master template for all the views belonging to a controller unless otherwise specified.

So if your view is being rendered inside a layout, your own ,

and tags are all getting output inside the body of an enclosing layout that already has a set of these tags, which would mean the headers and HTML doctype declarations in your view would be ignored.

The easy way to check if this is happening is to access your page in a
browser and view source. If it looks right, you’ve probably solved
things some other way through the type of render() call you’re making…
but if you see two sets of HTML and HEAD tags, the outer ones getting
used by the browser are coming from the layout and may be causing the
SVG recognition problem you had.

jatinder saundh wrote:

Thanks Robert,
The solution of setting the content header to application/xhtml+xml
solved
the problem.
I have one more doubt related to SVG’s; can I have ruby code inside svg
files(files with svg extension).
Currently in one of my svg files, I have Javascript function which
dynamically updates color of a circle, can I somehow use to ruby(or
some feature of rails, like rjs) instead of javascript to perform the
color
change operation using Ajax; please note that I want to have this
behaviour within files saved as svg.

Steve, I am not sure are if it’s not rendering it inside a layout. I did
not set :layout => false in the controller. I am pretty new to rails
hence
not aware of many features of it, can you please explain in a bit more
detail?

Thanks
Jatinder


#7

Steve, thanks for explaining what layouts are !
Yes they could have caused a problem, had I been using any layouts, I
hope
there aren’t any default layouts.

Thanks
Jatinder


#8

I am getting what you are saying…
To elaborate a little more, following is the piece of code in a file
named "
pic.svg" which I am embedding inside rhtml file using “object” tag.

<?xml version="1.0"?>

From rhtml file, on clicking of a link, I am calling a rjs file, which
internally calls javascript method “changeColor” present in pic.svg
file;
DOM of rhtml has a child DOM of pic.svg, is this not AJAX effect here?
Is
there is server round trip involved after javascript method
“changeColor” is
called.

Now my question is if I can replace this javascript in pic.svg with ruby
code; I am not sure how will I achieve this effect with the help of
Helpers?

Thanks
Jatinder


#9

Yes there are default layouts. Rails first checks for the one
corresponding
to the controller you are calling layouts/.rhtml then if
it
doesn’t find it, it checks for layouts/application.rhtml

I believe you can also tell your controller that it won’t use a layout
by
specifiying it in the controller but you’ll have to lookup the call
since I
don’t remember off the top of my head something like

layout nil

Best,

Jeff