0
votes

I am trying to implement an option for the user to set his own CSS in the front end.

I created an XPage like this:

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" rendered="false">
<xp:this.afterRenderResponse><![CDATA[#{javascript:

var externalContext = facesContext.getExternalContext();
var writer = facesContext.getResponseWriter();
var response = externalContext.getResponse();


response.setContentType("text/css");

response.setHeader("Cache-Control", "no-cache");
var param = context.getUrlParameter("myParam");
//HERE I WILL READ THE USER FIELD
writer.write("body{font-size:100pt;}");
writer.endDocument();

}]]>
  </xp:this.afterRenderResponse>
</xp:view>

If I try to implement the CSS (XPage) like this

<xp:styleSheet href="/myCssXPages.xsp"></xp:styleSheet>

everything works fine until I set the property xsp.resources.aggregate to true. If I try to implement the file like this:

<xp:linkResource type="text/css" loaded="true" href="./myCssXPages.xsp">
<xp:this.attrs>
<xp:attr name="rel" value="stylesheet" loaded="true"></xp:attr>
</xp:this.attrs>
</xp:linkResource>

It could work, because now every CSS file will be aggregate except this file, but the order is wrong. This file is always loaded before the aggregated files are loaded but I need this file at the last position.

Is there any solution to set the order of the resources or why I can't use a XPage as CSS resource with aggregate true? Or is there another solution to implement a functionality like this?

UPDATE

The user created an settings document where he got a textfield. So he will save his css as string in an document.

I created also some default css file resources. But when the user sets his own css config, this shut override the content from the default files resources.

I can't use themes because themes are also implemented befor the aggregated css files a implemented.

2
I'm not sure i understand your problem, but can you explain why you need it be loaded after the others? - Gabriel Netto
I have an XPage and an CSS ressourcefile. That CSS file is in this XPage implemented. I have in that CSS a line like this body{color:#ff0000}. Now the user can set in an document his own CSS like body{color:#00ff00} now i want that his CSS is in that XPage and if i want to override the content from the CSS default fileressource than i have to load his CSS after the default. I'm realy sorry for my bad declaration. - Pudelduscher
What about using a passthrough tag (which would add the CSS to HTML body)? - Sven Hasselbach
Yes, that is what i currently do. But that is not the best way. - Pudelduscher
@Pixel: Why? It works. Does what it should do. Sounds like a good solution... - Sven Hasselbach

2 Answers

1
votes

You could load your CSS with a CSJS script and append it to the HTML head:

<xp:scriptBlock id="scriptBlockCss">
   <xp:this.value><![CDATA[
      function loadCss(url) {
         var link = document.createElement("link");
         link.type = "text/css";
         link.rel = "stylesheet";
         link.href = url;
         document.getElementsByTagName("head")[0].appendChild(link);
      }
      loadCss( '/yourDB.nsf/myCssXPages.xsp' );
    ]]></xp:this.value>
</xp:scriptBlock>

Code shamelessly copied from http://requirejs.org/docs/faq-advanced.html#css

1
votes

I'm not quite sure whether I really understand your use case. But my first thought is using an Xpages theme where you load a specific css file in a resource node, probably with the rendered attribute set appropriately.

For reference have a look at how the standard discussion template is using various themes, each of them using their own set of style sheet resources.

If that's not what you have in mind you'd have to tell us more about hwo and when your users should be able to select their own css, and where those specific css files shall be created and stored