using svg in an activity module

using svg in an activity module

by Matthieu Nué -
Number of replies: 12
Hello everybody,

I make an activity module which needs svg technology. I would like to create inline svg (in the view.php file).
For that i need to add the command "@header('Content-Type: image/svg+xml');" before coding my picture and that's work.

BUT, I want to keep the header and the footer. In this case, i can't put my command before or after the header but i must put it in the function "print_header".

Do you have a solution to not touch the print_header function or if it's not possible, do you think i can propose a patch with a proposition of "$usesvg" in the argument's "print_header" function.

Thank you
Average of ratings: -
In reply to Matthieu Nué

Re: using svg in an activity module

by Mauno Korpelainen -

Print_header in weblib.php includes meta tags from (standard) theme meta.php - have you tried it? Does it not work in theme header.html?

In reply to Mauno Korpelainen

Re: using svg in an activity module

by Matthieu Nué -
"@header("Content-type: image/svg+xml"); " is a php command.

meta tags include html command (with echo)

or i don't know how to do this.
In reply to Matthieu Nué

Re: using svg in an activity module

by Mauno Korpelainen -
And meta.php is a php file that is included to function print_header so you can add php tags to meta.php - something like:

<?php
@header("Content-type: image/svg+xml");
?>
In reply to Mauno Korpelainen

Re: using svg in an activity module

by Matthieu Nué -
I have tested. It doesn't work.

Thanks for your help Mauno.
In reply to Matthieu Nué

Re: using svg in an activity module

by sam marshall -
Picture of Core developers Picture of Peer reviewers Picture of Plugin developers
Hi,

I think you may have misunderstood.

The content-type setting you give is only required for a separate SVG file i.e. if you are making a whatever.svg which serves the SVG only and is not an html document.

If you want to do inline SVG then you do not need to set that content-type. It would not be possible because a document can only have one content type whereas yours would need two (XHTML and SVG). In XML the mechanism for specifying these types is namespaces.

For it to work in Firefox etc the part of the document with the SVG in MUST be xml (not html) so that the namespace works. There are two options for achieving this:

1) easy, no javascript, but has many consequences and will cause critical failures unless you're careful

Set the content-type (in header as given) application/xhtml+xml. (I think there is a Moodle option which will make it do this. Use a tool such as the LiveHTTPHeaders Firefox extension to verify that the page is being sent like that and not as text/html.)

Once you have done that you must use the correct namespace for your HTML document and for the SVG itself.

Note that setting XHTML has other consequences; some of Moodle's JavaScript might not work, for instance, and if there are any minor errors on the page they will cause it not to display. Also it won't display at all (it will offer to save) on Internet Explorer.

2) harder, javascript, but won't cause any problems

If you don't want to use an XML or XHTML mime type for the document, you CAN still add inline svg but you need to use JavaScript. The document.createElementNS function can create elements in the SVG namespace. Here is some example code (this is not complete but you should be able to see what I'm doing):

var SVGNS='http://www.w3.org/2000/svg',XLINKNS='http://www.w3.org/1999/xlink';
 function textrotate_make_svg(el)
{
 var string=el.firstChild.nodeValue;
 // Create SVG
 var svg=document.createElementNS(SVGNS,'svg');
 svg.setAttribute('version','1.1');
 var width=(el.offsetHeight*9)/8;
 svg.setAttribute('width',width);
 svg.setAttribute('height',el.offsetWidth+20);
 var text=document.createElementNS(SVGNS,'text');
 svg.appendChild(text);
 text.setAttribute('x',el.offsetWidth);
 text.setAttribute('y',-el.offsetHeight/4);
 text.setAttribute('text-anchor','end');
 text.setAttribute('transform','rotate(90)');
 text.appendChild(document.createTextNode(string));
 
 // Replace original content with this new SVG
 el.parentNode.insertBefore(svg,el);
 el.parentNode.removeChild(el);
}
There might be a way to do this using innerHTML (innerXML, anyone?) but I despise such laziness. smile

--sam
In reply to sam marshall

Re: using svg in an activity module

by Marc Grober -
Apologies jumping in as I have not seen the whole thread yet and really don;t have time to follow through right now, but asciimathml does svg via d.svg and you might look at that by way of example as that works very well in activities.
In reply to sam marshall

Re: using svg in an activity module

by Matthieu Nué -
Ok thanks for explanations sam.

Yes, there is an option to use the content-type "application/xhtml+xml" when we call the "print_header_simple" function but there is a problem because in this case, there are 2 declarations of DOCTYPE which cause a bug.
The first declaration is in the "print_header_simple" function (when use the xhtml+xml option), the second in the top of "header.html".

I think the first declaration may be deleted.
What do you think of declare it as a bug in the tracker ?

When the first declaration is deleted, the svg works fine.

Matthieu
In reply to Matthieu Nué

Re: using svg in an activity module

by sam marshall -
Picture of Core developers Picture of Peer reviewers Picture of Plugin developers
Yes if that happens I think it should be filed as a bug.

Glad your SVG is now working! As I mentioned earlier though, you do have to be careful as turning on that option is highly unsafe. Moodle is supposed to be valid XHTML (bugs aside) but it does not always check that user-entered content is valid XHTML. So if, for example, a user enters some HTML without a closing tag in certain places, it might render e.g. a forum completely unusable for visitors on Firefox. An admin would have to go in using Internet Explorer (otherwise they can't see the page either) and edit or delete the offending message.

So, good for testing but not for real sites at present - you need to go for a fancy javascript option (that's what the asciimathmlsvgwhatever script is doing - incidentally at the OU we have a MathML filter* that uses a similar approach to include MathML inline).

We enquired with moodle.com about the possibility of funding work in 2.0 to ensure that all user content was guaranteed XHTML, but they didn't have time. We've since found another way to achieve our objective so I guess we probably won't be funding it in future either, but I hope it does happen eventually because proper XHTML support would be nice (even though IE8 still doesn't support XHTML).

--sam

* Which we haven't released to public yet because it involves a non-Moodle component, which is open source but we had to mess with it... sigh... I ought to talk to that guy...
In reply to sam marshall

Re: using svg in an activity module

by Matthieu Nué -
I don't understand something.

If i turn on the XHTML option in my activity module (in the view.php file), it affects only this page, no ?
The rest of the site is on HTML option. no ?

Matthieu
In reply to Matthieu Nué

Re: using svg in an activity module

by sam marshall -
Picture of Core developers Picture of Peer reviewers Picture of Plugin developers
Ohhh you mean just hacking the config variable for this view.php page before you print the header? Yes that's correct, it will only affect this page, so if you are controlling all the html for the page and not allowing any direct user input, that will be a whole lot safer.

I thought we were talking about changing the site option (in admin under 'server/debugging').

--sam