db.define_table("event", Field("id_meet", "reference meet", label=T("Meet")), Field("id_session", "reference session", label=T("Session")), Field("id_event", "reference event_index", label=T("Event")), #Field("day", "integer", notnull=True, label=T("Day")), Field("ord", "integer", notnull=True, label=T("Order")), Field("swim_num", "string", notnull=True, label=T("Number")), elapsed_time_field("lcm_gt",label=T("LCM >")), elapsed_time_field("lcm_le",label=T("LCM ≤")), elapsed_time_field("scm_gt",label=T("SCM >")), elapsed_time_field("scm_le",label=T("SCM ≤")), elapsed_time_field("scy_gt",label=T("SCY >")), elapsed_time_field("scy_le",label=T("SCY ≤")), Field("nt_ok", "boolean", label=T("Allow NT")), format=event_list, migrate=current.settings.migrate)
<label class="control-label col-sm-5" for="event_join_lcm_gt" id="event_join_lcm_gt__label">LCM >: </label>
<label class="control-label col-sm-5" for="event_join_lcm_le" id="event_join_lcm_le__label">LCM &le;: </label>
It's even worse than I imagined.Leaving off the T() operation, I find that my field labeled "LCM >" is actually sanitized at some point into:
<label class="control-label col-sm-5" for="event_join_lcm_gt" id="event_join_lcm_gt__label">LCM >: </label>
Yes, something in the process has recognized the character ">" and changed it to ">" But the field "LCM ≤" was sanitized into:
<label class="control-label col-sm-5" for="event_join_lcm_le" id="event_join_lcm_le__label">LCM &le;: </label>
In this case, not only was the ≤ not recognized by the sanitizer, it actually DE-SANITZED it by removing the ampersand and sanitizing it separately.
elapsed_time_field("lcm_gt",label=CAT(T("LCM"),XML(" >"))),
elapsed_time_field("lcm_le",label=CAT(T("LCM"),XML(" ≤"))),
elapsed_time_field("scm_gt",label=CAT(T("SCM"),XML(" >"))),
elapsed_time_field("scm_le",label=CAT(T("SCM"),XML(" ≤"))),
elapsed_time_field("scy_gt",label=CAT(T("SCY"),XML(" >"))),
elapsed_time_field("scy_le",label=CAT(T("SCY"),XML(" ≤"))),
elapsed_time_field("lcm_gt",label=XML(T("LCM %s",(">",)))),
elapsed_time_field("lcm_le",label=XML(T("LCM %s",("≤",)))),
elapsed_time_field("scm_gt",label=XML(T("SCM %s",(">",)))),
elapsed_time_field("scm_le",label=XML(T("SCM %s",("≤",)))),
elapsed_time_field("scy_gt",label=XML(T("SCY %s",(">",)))),
elapsed_time_field("scy_le",label=XML(T("SCY %s",("≤",)))),
As far as my table comment, I meant that when I used the SQL table and its Fields to create an SQLTABLE, the labels "just worked" and produced a column header with the desired symbol instead of printing "≤" in the column heading. So SQLTABLE behavior differed from SQLFORM in this manner.
I have found a workaround, finally, which lets me have symbols in both forms and tables:
elapsed_time_field("lcm_gt",label=CAT(T("LCM"),XML(" >"))),
elapsed_time_field("lcm_le",label=CAT(T("LCM"),XML(" ≤"))),
elapsed_time_field("scm_gt",label=CAT(T("SCM"),XML(" >"))),
elapsed_time_field("scm_le",label=CAT(T("SCM"),XML(" ≤"))),
elapsed_time_field("scy_gt",label=CAT(T("SCY"),XML(" >"))),
elapsed_time_field("scy_le",label=CAT(T("SCY"),XML(" ≤"))),
label=XML(T("LCM ≤"))
which is your original label simply wrapped in XML().I first tried the obvious, letting T() handle the substitution but again, that doesn't work. The &xx; character escapes get printed literally in the form label instead of creating the symbol I intended. So I got around the problem with CAT(). Still, an awful amount of work and hassle to reverse-engineer and make a work around for something that just should have worked.
I'm not sure why &xx; is "sanitized" to begin with. It seems like an extreme form of sanitizing, to eliminate any and all special characters from form labels.