0

I'm trying to figure out how to add CSS in Genshi to some markup which is dynamically generated. I'm trying to avoid inline CSS, and ideally the rules would appear in the <head/> tag of the parent document.

I'm working with existing code that looks like this (I rewrote this from the original, to simplify, so I might have some syntax mistakes; but the original works, so I think you can ignore syntax mistakes if any):


templates/widgets/file_widget.html

<html xmlns:py="http://genshi.edgewall.org/"
  xmlns:xi="http://www.w3.org/2001/XInclude"
  py:strip="">
<head>
  <style type="text/css">
      .file-widget {
          background-color:#eee; display:inline-block; padding:4px;
      }
  </style>
</head>
<py:def function="file_widget(file_name)">
  <div class=".file-widget">
    ...
  </div>
</py:def>
</html>

widgets.py

class FileWidget:

...

    def html():
        markup_template = genshi.template.MarkupTemplate('''
            <html xmlns="http://www.w3.org/1999/xhtml" xmlns:py="http://genshi.edgewall.org/" xmlns:xi="http://www.w3.org/2001/XInclude">
                <xi:include href="my_project/widgets/file_widget.html" />
                ${description}
                ${file_widget(file_name)}
            </html>''')
        markup = markup_template.generate(file_name = self.file_name,  description = genshi.core.Markup(self.description))
        return markup.render('html', doctype = 'html')

templates/main_page.html

<div py:for='widget in app.widgets'>
    ${ genshi.core.Markup( widget.html() ) }
</div>

Unfortunately, the <style/> tag gets rendered twice: once, as I want it to be, inside the original document <head/>, and then the widget <head/> gets rendered again.

How can I change the code to properly include the CSS in the right place? Since this is collaborative code, little changes and clearer code are appreciated!

Thanks for reading and for your help.

Yuval
  • 3,207
  • 32
  • 45

1 Answers1

1

You might want to use a widget library like ToscaWidget2 which is meant to actually manage widgets with resources.

Otherwise you might want to use a static files framework like fanstatic which provides support for resources inclusion: http://www.fanstatic.org/en/1.0a5/quickstart.html#including-resources-with-fanstatic

If you want to roll your own custom solution you should register the resources somewhere whenever the widget is rendered (like in request) and then add them to the head tag when template is rendered. This is actually what tw2.core.resources does: https://github.com/toscawidgets/tw2.core/blob/develop/tw2/core/resources.py

amol
  • 1,771
  • 1
  • 11
  • 15
  • Thanks for the answer. `tw2.core.CSSLink` and `tw2.core.JSSource` look like good candidates, but I'm not sure how to incorporate them in my code above. As I explained, I'm editing existing code in a collaborative project. Changing or adding libraries is more difficult. – Yuval Sep 15 '14 at 11:59