Warning: Can't synchronize with repository "(default)" (Unsupported version control system "svn": No module named svn). Look in the Trac log for more information.

Ticket #2287 (closed enhancement: fixed)

Opened 6 years ago

Last modified 5 years ago

[PATCH] No simple way to make TurboGears 2 produce HTML

Reported by: chrisz Owned by:
Priority: high Milestone: 2.1a2
Component: TurboGears Version: 2.0rc1
Severity: normal Keywords: html patch
Cc:

Description (last modified by chrisz) (diff)

In TG 1.0, switching between HTML and XHTML output was the matter of only one config setting, but in TG 2.0 this has become very difficult. By default TG 2.0 produces XHTML (while TG 1.0 produced HTML by default) and there is no clean and simple way to use HTML in TG 2.0.

Note that I'm not against using XHTML as the default, but there are many good reasons to produce HTML instead of XHTML, so people should at least be given the  choice.

There are two problems:

  1. Changing the output method of the default render function (using Genshi) is not as straightforward as it should be (as discussed  here).
  2. Even if you change the default Genshi renderer, the ressource injection of ToscaWidgets will still use XHTML for CSS links, because it uses the string.Template rendering engine with a hardcoded XHTML template (as discussed  here).

My current solution is to add the following code to config/environment.py:

# Make Genshi render HTML (instead of XHTML) by default:

_load_environment = load_environment

def load_environment(*args):

    _load_environment(*args)

    render_genshi = base_config.render_functions.genshi

    def render_genshi_html(*args, **kwargs):
        return render_genshi(method='html', *args, **kwargs)

    base_config.render_functions.genshi = render_genshi_html

# Monkey-patch ToscaWidget so that it creates a valid HMTL link tag
# instead of a XHTML tag when injecting resources:

from tw.api import CSSLink

CSSLink.template = CSSLink.template.replace('/>', '>')

This solves the problem, but it is really ugly and complicated. Something so basic should have a much simpler solution. I think this is an annoying step backward in TG2 compared with TG1.

Attachments

tg2-genshi-html.patch Download (571 bytes) - added by stefanor 6 years ago.
Patch: Configurable output type

Change History

comment:1 Changed 6 years ago by mramm

  • Milestone changed from 2.0 to 2.1

comment:2 Changed 6 years ago by mramm

  • Milestone changed from 2.1 to 2.1a1

comment:3 Changed 6 years ago by mramm

  • Priority changed from normal to high

Changed 6 years ago by stefanor

Patch: Configurable output type

comment:4 Changed 6 years ago by stefanor

  • Keywords patch added
  • Summary changed from No simple way to make TurboGears 2 produce HTML to [PATCH] No simple way to make TurboGears 2 produce HTML

Added patch and modified summary accordingly

comment:5 Changed 6 years ago by stefanor

Of course my patch doesn't fix the ToscaWidgets? bug, but that's hardcoded HTML so there's not much that can be done

comment:6 follow-up: ↓ 8 Changed 6 years ago by chrisz

  • Description modified (diff)

Ok, I commited a  similar patch now.

However, there are still two open problems:

First, the resource injection issue as mentioned above. To fix this, we need to work on  TW ticket 40.

Second, the doctype is not adapted when you change the method from xhtml to html, i.e. you need to set the correct doctype in all your templates, which is not only inconvenient, but also bad if you want to view the templates directly. To fix this, we need to add a custom Genshi renderer since passing a doctype is not supported by Pylons (see  Pylons ticket 613).

comment:7 follow-up: ↓ 9 Changed 5 years ago by Twey

Why can't the Genshi renderer (and other renderers, for that matter) take a dictionary of options as in Buffet? Is there some serious defect in this configuration model? Using it, it would be possible to pass whatever options to Genshi one desired. It's even easy to tie into the INI file. Why was the templating API crippled in this way?

comment:8 in reply to: ↑ 6 Changed 5 years ago by jorge.vargas

Replying to chrisz:

Ok, I commited a  similar patch now.

However, there are still two open problems:

First, the resource injection issue as mentioned above. To fix this, we need to work on  TW ticket 40.

Second, the doctype is not adapted when you change the method from xhtml to html, i.e. you need to set the correct doctype in all your templates, which is not only inconvenient, but also bad if you want to view the templates directly. To fix this, we need to add a custom Genshi renderer since passing a doctype is not supported by Pylons (see  Pylons ticket 613).

Given Ben's input on the pylons ticket I think the correct solution will be for TG to build a render genshi function (or set of functions) that will take all the parameters like it was said in the pylons ticket. In fact I'm willing to simply skip the pylons.templating.render_genshi function and simply use our own.

comment:9 in reply to: ↑ 7 Changed 5 years ago by jorge.vargas

Replying to Twey:

Why can't the Genshi renderer (and other renderers, for that matter) take a dictionary of options as in Buffet? Is there some serious defect in this configuration model? Using it, it would be possible to pass whatever options to Genshi one desired. It's even easy to tie into the INI file. Why was the templating API crippled in this way?

The main reason why buffet was removed is because template APIs aren't really that flexible. TG1.x used to need a special class to coerce each templating engine into using it. Specialized renderers prove to be a saner design. I think the current implementation by chrisz seems to be best. As I said in my previous comment the Genshi API can be made as powerful as we want without needing to call down on the pylons implementation.

comment:10 Changed 5 years ago by percious

  • Status changed from new to closed
  • Resolution set to fixed

I'm closing this ticket as it seems like the code sufficiently handles the challenge. Reopen a new ticket if you want more than the ability to specify a method. That should be a separate feature request.

Note: See TracTickets for help on using tickets.