We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 26435
    • 1,193 Posts
    This is an auto-generated support/comment thread for [PLUGIN] application/xhtml+xml.

    Use this forum to post any comments about this addition or any questions you have regarding its use.

    Brief Description:
    <strong>For MODx users who create XHTML valid templates:</strong>
    This plugin (Set to onWebPagePrerender) first checks to see if the users browser can accept mime type "application/xhtml+xml" and if it can, replaces the content type of "text/html" with "application/xhtml+xml".
      Husband, Father, Brother, Son, Programmer, Atheist, Nurse, Friend, Lover, Fighter.
      All of the above... in no specific order.


      I send pointless little messages
      • 26435
      • 1,193 Posts
      For MODx users who create XHTML valid templates:
      This plugin (Set to onWebPagePrerender) first checks to see if the users browser can accept mime type "application/xhtml+xml" and if it can, replaces the content type of "text/html" with "application/xhtml+xml".

      What determines if my document is HTML or XHTML?

      You may be a bit thrown off by the talk of treating an XHTML as HTML. After all, if my document is XHTML, that should be the end of the story, right? After all, I put an XHTML doctype! But it turns out that things are not so simple.

      So what really determines if a document is HTML or XHTML? The one and only thing that controls whether a document is HTML or XHTML is the MIME type. If the document is served with a text/html MIME type, it is treated as HTML. If it is served as application/xhtml+xml or text/xml, it gets treated as XHTML. In particular, none of the following things will cause your document to be treated as XHTML:

      * Using an XHTML doctype declaration
      * Putting an XML declaration at the top
      * Using XHTML-specific syntax like self-closing tags
      * Validating it as XHTML

      In fact, the vast majority of supposedly XHTML documents on the internet are served as text/html. Which means they are not XHTML at all, but actually invalid HTML that’s getting by on the sloppy (lenient) error handling of HTML parsers. All those “Valid XHTML 1.0!” links on the web are really saying “Invalid HTML 4.01!”.
      HTML is probably what you want

      Perhaps you’re just now realizing that your lovingly crafted valid XHTML document is actually invalid HTML. You have a couple of choices:

      1. Serve your content as application/xhtml+xml. That’s probably not such a good idea though. Microsoft Internet Explorer will not handle XHTML at all, and serving it such a MIME type will lead it to download. Unless you’re willing to completely lock out IE users, you probably don’t want to take this option.

      2. Serve as text/html to IE, but as application/xhtml+xml to other browsers. This way your content at least has a chance of working in IE, and uses HTML-compatible XML for its original intended purpose, as a fallback compatibility hack. However, there are still downsides. Your documents will be processed in entirely different ways in IE vs other browsers. A construct that may be perfectly valid HTML could totally break XML parsing, due to the strict error handling rules. Or conversely, some kinds of valid XHTML changes might result in an HTML document that looks wrong. Furthermore, the XHTML modes of the browsers that support it are not nearly as mature or well tested as the HTML modes. This is definitely the case for Safari. And Mozilla also discourages this practice due to lack of support for incremental rendering. And they have a list of some of the many differences in processing XHTML vs HTML.

      3. Stick with the status quo. Another option is to just stick with the status quo - generate XHTML content but serve it as HTML. The disadvantages here are mainly that you are losing out on HTML validators, which will validate the document in a way that matches how browsers parse it; and that you run the risk of subtle incompatibilities if your document is ever actually processed as XHTML. But this also raises the question: what do you think you are getting out of using XHTML? You may have heard a lot of hype about it, experts may have told you it’s the next big thing, but what kind of benefits do you get if in the end it’s just treated as HTML tag soup?

      -sD-
      Dr. Scotty Delicious, Scientist.
        Husband, Father, Brother, Son, Programmer, Atheist, Nurse, Friend, Lover, Fighter.
        All of the above... in no specific order.


        I send pointless little messages
        • 19315
        • 84 Posts
        I’ve noticed that the current version results in documents that I think should be served as "text/xml", such as RSS feeds, end up being served as "text/html" or "application/xhtml+xml". Specifically, it sends the W3C validator http://validator.w3.org/feed/ the feed as "text/html", which it complains about.

        Would a test on the type of document being served be appropriate? I’m a bit of a php/modx newbie, but I’ve tried out the following code:

        $event = &$modx->Event;
        switch ($event->name) {
        	case "OnWebPagePrerender":
        	if (stristr($_SERVER['HTTP_ACCEPT'],'application/xhtml+xml') && $modx->documentObject['contentType']=="text/html") {
        		header("Content-type: application/xhtml+xml; charset=utf-8");
        	}
        	else if ($modx->documentObject['contentType']=="text/xml"){
        		header("Content-type: text/xml; charset=utf-8");
        	}
        	else {
        		header("Content-type: text/html; charset=utf-8");
        	}
        	break;
        
        	default :
        	return;
        	break;
        }


        and so far it seems to work. (I’ve removed the code that changes the strings in the document itself, as I don’t have the meta http-equiv tag in my template).

        Michal.
          • 19315
          • 84 Posts
          ... or now I have set all my XHTML documents to have content-type "application/xhtml+xml" in their drop down menu. Now, the plugin needs to fix the content type to "text/html" in the appropriate cases. This does allow for individual pages to be served as text/html if necessary (for example if you want to have a Google Map in your page - which must be served as "text/html" if you want it to work in Firefox).

          $event = &$modx->Event;
          switch ($event->name) {
          	case "OnWebPagePrerender":
                  $browserAcceptsXHTMLMIME = stristr($_SERVER['HTTP_ACCEPT'],'application/xhtml+xml');
                  $documentIsXHTML = $modx->documentObject['contentType']=="application/xhtml+xml";
          	if ($documentIsXHTML && !$browserAcceptsXHTMLMIME) {
          		header("Content-type: text/html; charset=UTF-8");
          	}
          	break;
          
          	default :
          	return;
          	break;
          }


          Edit: I corrected the sent MIME type in the if block.
            • 6726
            • 7,075 Posts
            How did I miss this ?

            This kind of MODx easter egg is just GREAT, Scotty !
            Another one for standards aware designers grin

              .: COO - Commerce Guys - Community Driven Innovation :.


              MODx est l&#39;outil id
              • 26435
              • 1,193 Posts
              Quote from: michalc at Dec 30, 2006, 04:29 PM

              I’ve noticed that the current version results in documents that I think should be served as "text/xml", such as RSS feeds, end up being served as "text/html" or "application/xhtml+xml". Specifically, it sends the W3C validator http://validator.w3.org/feed/ the feed as "text/html", which it complains about.

              Would a test on the type of document being served be appropriate? I’m a bit of a php/modx newbie, but I’ve tried out the following code:

              Michal.

              Michal...
              I think you are missing the simplicity of how this works. you serve ALL your XHTML pages as content="text/html". Then, IF... and ONLY IF the client browser can parse application/xhtml+xml, at the last minute the string "text/html" is replaced with "application/xhtml+xml".

              So you must understand that if you are serving an RSS page as "text/xml" that is not equal to the string "text/html" so it is not replaced. There is no need to make this unnecessarily complicated.

              1. check if browser can serve xhtml+xml
              2. if yes replace the single meta tag of content="text/html" with content="application/xhtml+xml"
              3. if no, replace nothing, serve as is. Also, if not exactly "text/html" do nothing.

              I know it does not make sense, but the W3C validator does not SPECIFICALLY identify itself as capable of parsing "application/xhtml+xml" (although it obviously is) so this plugin serves it a page that is unchanged... content="text/html". Get it?

              Thank you for your contributions, but I am sure that once you understand how this plugin works, you will see that all that extra code is not necessary.

              -sD-
              Dr. Scotty Delicious, Scientist.
                Husband, Father, Brother, Son, Programmer, Atheist, Nurse, Friend, Lover, Fighter.
                All of the above... in no specific order.


                I send pointless little messages
                • 19315
                • 84 Posts
                Hi,

                So you must understand that if you are serving an RSS page as "text/xml" that is not equal to the string "text/html" so it is not replaced. There is no need to make this unnecessarily complicated.

                1. check if browser can serve xhtml+xml
                2. if yes replace the single meta tag of content="text/html" with content="application/xhtml+xml"
                3. if no, replace nothing, serve as is. Also, if not exactly "text/html" do nothing.

                If you are serving all your XHTML pages as initially text/html, I agree this is the what to do. You are right that my code (in my first post) was needlessly complicated. However, I don’t think the original code in the plugin adheres to the "If not exactly text/html do nothing" part. It seems to me that if the user did not accept application/xhtml+xml, then all pages are served as text/html, as there was no test on the original content-type. Something like:

                $event = &$modx->Event;
                switch ($event->name) {
                	case "OnWebPagePrerender":
                	if (stristr($_SERVER['HTTP_ACCEPT'],'application/xhtml+xml') && $modx->documentObject['contentType']=="text/html") {
                		header("Content-type: application/xhtml+xml; charset=utf-8");
                	}
                	break;
                
                	default:
                	return;
                	break;
                }

                seems to fix that. I think I see now that there is no extra "else" block required. So I think perhaps we were both being needlessly complicated? ;-)

                However, it seems that the original code, and my code just above, does not allow individual pages to be served as "text/html". The code in my second post, I think, allows this, but it does require all XHTML pages to be set as application/xhtml+xml. I don’t really present this as a fix to the plugin, but I thought that someone may have found this useful if this is what they were trying to do.
                  • 26435
                  • 1,193 Posts
                  It is not my intention to sound rude, so please do not read this response as rude:
                  I believe that you do not have a firm understanding of how the MODx document parser works, nor do you understand how to properly set document types in the manager.

                  I will try to explain this to you completely.

                  For any page you want to serve as "application/xhtml+xml" but don’t want to break in IE and any other browsers that may not be able to interpret, in the manager when you create or edit the page, you click on the "Page Settings" tab and choose "text/html" for the "Content type". This is what you would do for any page most people would refer to as a "Web page".

                  For other types of pages such as RSS feeds or Podcasts, you would select "text/xml" for the content type. For CSS pages, select "text/css", etc... etc...

                  The MODx document parser will select this content type from the database table "[prefix]_site_content" from the third field called "contentType" prior to rendering this to the screen in the form of a meta tag. What this plugin does is simply check to see if the browser can handle xhtml, then if it can , it replaces the text in the document that matches exactly "text/html" with the text "application/xhtml+xml".

                  Now... pay attention here, because this seem to be the part you are really struggling with!
                  If you have an RSS page in your MODx site, you should be setting the content type in the manager as "text/xml". If you are not doing this, then you are doing it wrong.

                  So if you are actually doing this correctly, serving your RSS pages as "text/xml" and your CSS pages as "text/css", then when they are requested by a browser and the modx document parser starts preparing the page, the content type it finds in the database is "text/xml". When the plugin searches the document for the text line "text/html", do you imagine it would find an exact match?

                  The answer is no. It would not find an exact match.

                  Next question. If the plugin only replaces the text if it is an EXACT match to "text/html" (which it does), do you think it will replace anything if the document parser is outputting your page as "text/xml"?

                  The answer to that question is also no.

                  I am at a loss to what you could possibly be doing wrong in your manager that you would need to make things this complicated. Perhaps it is the lack of documentation on how to manage pages and how the document parser collects data and creates those pages on request. Perhaps your are simply overzealous.

                  I hope this has helped clear this up.

                  -sD-
                  Dr. Scotty Delicious, Scientist.
                    Husband, Father, Brother, Son, Programmer, Atheist, Nurse, Friend, Lover, Fighter.
                    All of the above... in no specific order.


                    I send pointless little messages
                    • 19315
                    • 84 Posts
                    It is not my intention to sound rude, so please do not read this response as rude:
                    It was never my intention to annoy you (or anyone), sorry if I did so. I’m sorry if I come accross as acting as if I understand this all, when I don’t. I thought I could help, albeit just a little bit, - I didn’t want this to turn into an argument.

                    For any page you want to serve as "application/xhtml+xml" but don’t want to break in IE and any other browsers that may not be able to interpret, in the manager when you create or edit the page, you click on the "Page Settings" tab and choose "text/html" for the "Content type". This is what you would do for any page most people would refer to as a "Web page".
                    I agree completely this is what to do if working with your original plugin.

                    However, I created a custom type "applicatation/xhtml+xml" In Manager->Tools->Configuration->Site, and I set the content type for my pages to that. If left as that, I believe MODx would serve those documents as "applicatation/xhtml+xml" (in their HTTP header information), and that pages would break in IE. However, using the alternative code posted above, the content type would be changed (using the "header" function). Note that my code does not change anything in the document content, only the HTTP header. I don’t have a meta http-equiv tag in my html "head" section, as it seems a bit superfluous when setting the content type, with encoding, in the HTTP header. This is just for my own personal use, as I have a single page XHTML page that I would actually like served as text/html, and it seems that this is the only way to do it.

                    For other types of pages such as RSS feeds or Podcasts, you would select "text/xml" for the content type. For CSS pages, select "text/css", etc... etc...
                    I agree wholeheartedly.

                    When the plugin searches the document for the text line "text/html", do you imagine it would find an exact match?

                    The answer is no. It would not find an exact match.
                    This is where I think this is where the confusion is coming from. The str_replace function in the plugin does search for this "text/html", and only replace that (it seems like it would also replace the string text/html anywhere in the document content also, but this is a whole other discussion!). However, to quote from the original plugin:
                    if ( stristr($_SERVER['HTTP_ACCEPT'],'application/xhtml+xml') ) {
                    	$content_type = 'application/xhtml+xml';
                    	header("Content-type: application/xhtml+xml");
                    }
                    else {
                    	$content_type = 'text/html';
                    	header("Content-type: text/html");
                    }

                    The "header" function seems to change the HTTP header content-type. The else block is executed if the browser does not seem to accept application/xhtml+xml, and in the else block the HTTP header is changed to text/html. Thus, whatever the orignal content type of the document, be it text/html, text/xml, text/css - if it is served through this plugin, the content type in the HTTP header will be changed to text/html if the browser does not identifty itself as accepting application/xhtml+xml. This was my point I was trying to make.

                    However, come to think of it, I have now realised that the first "if" block also has a problem. There is no test on the original content type of the document. Thus if a RSS feed, set to text/xml in the manager, is served, but the browser says it _can_ accept application/xhtml+xml, then its content-type in the HTTP header is changed. I feel as though there has to be some test on the original content type, $modx->documentObject[’contentType’], or similar.

                    I’m sorry I just don’t see a flaw in my logic. I’m sorry if I’m being a bit slow and wasting your time. Perhaps I misunderstand what the "header" function does, but from my limited testing (with help of the livehttpheaders extension for Firefox, and access to a version of IE) it does seem to do what I think it does.
                      • 26435
                      • 1,193 Posts
                      ok
                        Husband, Father, Brother, Son, Programmer, Atheist, Nurse, Friend, Lover, Fighter.
                        All of the above... in no specific order.


                        I send pointless little messages