Tapestry 5
  1. Tapestry 5
  2. TAP5-1330

Position of Injected Stylesheets changed from 5.1 to 5.2

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 5.2.0, 5.2.1, 5.2.2
    • Fix Version/s: 5.2.3
    • Component/s: tapestry-core
    • Labels:
      None

      Description

      5.1 items placed into the <head> element of the template were rendered after stylesheets that were added via the @Import. This meant you could add code or style sheets that would override the stylesheets added by @Import. As of 5.2 it appears that this has changed and now the @Import style sheets show up AFTER items that are added in the <head>. This means there isn't a way to override the stylesheets by adding <style> to the <head> element.

      Here is an example of what is occurring in 5.2.2

      Layout.tml:

      <head>
      <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
      <title>$

      {title}

      </title>
      <style type="text/css">
      <t:outputraw value="cssFromDatabase"/>
      </style>
      </head>

      Is rendered as:

      <head>
      <meta content="text/html; charset=utf-8" http-equiv="content-type"></meta>
      <title>My App</title>
      <style type="text/css">
      /My CSS/
      </style>
      <link type="text/css" rel="stylesheet" href="/register/assets/1.0-SNAPSHOT/tapestry/default.css"></link>
      <link type="text/css" rel="stylesheet" href="/register/assets/1.0-SNAPSHOT/ctx/layout/layout.css"></link>
      <meta content="Apache Tapestry Framework (version 5.2.2-SNAPSHOT)" name="generator"></meta>
      </head>

        Activity

        Hide
        Howard M. Lewis Ship added a comment -

        This does seem like a regression, not sure why there was a change.

        A workaround: on your Layout component, implement an empty afterRender() render phase method, and place an @Import on that method (yes, you can do that!). Doesn't work as well for your inline <style>, but couldn't that also go at the bottom of the page?

        Show
        Howard M. Lewis Ship added a comment - This does seem like a regression, not sure why there was a change. A workaround: on your Layout component, implement an empty afterRender() render phase method, and place an @Import on that method (yes, you can do that!). Doesn't work as well for your inline <style>, but couldn't that also go at the bottom of the page?
        Hide
        Mark Shead added a comment -

        If I add an item using @Import, it does add it after default.css. (See layout.css in the above example.) The problem is that anything Tapestry adds to the <head> tag comes right before </head> instead of right after <head>. This means you can't override anything that comes from a CSS file that is imported. As far as I can tell adding an additional css file on the filesystem via @Import would put it after the default.css which would work, but...

        @Import can only link to an asset--a physical file on the filesystem somewhere. You can't add a link to an external CSS file or to something that is generated by the program itself. I have a page called CustomCSS, that will generate the CSS I need, but it doesn't appear that there is a way to add it using @Import because it isn't a resource file sitting on the file system. I eventually got it to work using:

        @SetupRender
        public void setupRender()

        { renderSupport.addStylesheetLink("CustomCSS", null); }

        In my Layout.java, but RenderSupport appears to be deprecated and replaced by JavaScriptSupport which doesn't contain any way to add a CSS file using just its name as a String. You have to create an Asset which appears to have the same problems as trying to put the CustomCSS page into an @Import.

        I can get the <style> tag to work and pull the content from the database by putting it after </head> and the browsers I've tested seem to render correctly but it doesn't appear to be valid HTML. So while I can get it to work, it probably isn't the best long term solution.

        Show
        Mark Shead added a comment - If I add an item using @Import, it does add it after default.css. (See layout.css in the above example.) The problem is that anything Tapestry adds to the <head> tag comes right before </head> instead of right after <head>. This means you can't override anything that comes from a CSS file that is imported. As far as I can tell adding an additional css file on the filesystem via @Import would put it after the default.css which would work, but... @Import can only link to an asset--a physical file on the filesystem somewhere. You can't add a link to an external CSS file or to something that is generated by the program itself. I have a page called CustomCSS, that will generate the CSS I need, but it doesn't appear that there is a way to add it using @Import because it isn't a resource file sitting on the file system. I eventually got it to work using: @SetupRender public void setupRender() { renderSupport.addStylesheetLink("CustomCSS", null); } In my Layout.java, but RenderSupport appears to be deprecated and replaced by JavaScriptSupport which doesn't contain any way to add a CSS file using just its name as a String. You have to create an Asset which appears to have the same problems as trying to put the CustomCSS page into an @Import. I can get the <style> tag to work and pull the content from the database by putting it after </head> and the browsers I've tested seem to render correctly but it doesn't appear to be valid HTML. So while I can get it to work, it probably isn't the best long term solution.
        Hide
        Howard M. Lewis Ship added a comment -

        The logic in 5.2 is actually smarter than the logic in 5.1, in that it attempts to locate the first <link> and place the new <links> (from imported stylesheets) before it. You're putting an inline <style> in your head, that's what's tripping things up.

        I'm going to change the logic to just put import ed<link>s and imported <script>s first.

        Show
        Howard M. Lewis Ship added a comment - The logic in 5.2 is actually smarter than the logic in 5.1, in that it attempts to locate the first <link> and place the new <links> (from imported stylesheets) before it. You're putting an inline <style> in your head, that's what's tripping things up. I'm going to change the logic to just put import ed<link>s and imported <script>s first.
        Hide
        Hudson added a comment -

        Integrated in tapestry-5.2-freestyle #225 (See https://hudson.apache.org/hudson/job/tapestry-5.2-freestyle/225/)

        Show
        Hudson added a comment - Integrated in tapestry-5.2-freestyle #225 (See https://hudson.apache.org/hudson/job/tapestry-5.2-freestyle/225/ )

          People

          • Assignee:
            Howard M. Lewis Ship
            Reporter:
            Mark Shead
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development