Took a quick look at djangoproject.com with this change. I noticed we're 
using the label to construct an input placeholder [0]. I think adapting 
that for this change isn't so easy to do in a cross-browser way via CSS [1] 
but we could add capfirst in the code.

The question of a deprecation seems to be whether it's better to ask every 
Django project opt into the new behavior in the next two releases via some 
temporary setting or if we force all projects to adapt their CSS (and 
possibly code, as the example above shows) for Django 1.10. I'm not too 
happy with either path.

I'm not sure about the validation messages. If we stop capitalizing the 
label, the message "%(field_label)s must be unique for" won't start with a 
capital anymore. On the other hand, capitalizing field_label is awkward if 
a custom message that doesn't put field_label at the start of the sentence 
is used.

[0] 
https://github.com/django/djangoproject.com/blob/7fd780c061e4244982ca5bdd914fd004c6fe90af/members/forms.py#L25
[1] http://stackoverflow.com/a/2610741/5112

On Sunday, January 31, 2016 at 4:30:09 PM UTC-5, Sergei Maertens wrote:
>
> I've done the initial work for a patch, assuming a 'hard' change without 
> deprecation path, the branch is here: 
> https://github.com/sergei-maertens/django/commit/2f3c1d8dd56522dc69448ec20aac28d4ddc70ac4
>  
> <https://www.google.com/url?q=https%3A%2F%2Fgithub.com%2Fsergei-maertens%2Fdjango%2Fcommit%2F2f3c1d8dd56522dc69448ec20aac28d4ddc70ac4&sa=D&sntz=1&usg=AFQjCNF1RxmN7pPTemwhThfU-Su1TWDDZA>.
>  
> Tests should be passing.
>
> I've also taken a quick glance at django-admin-tools to check if they do 
> anything special with decapitalizing/capitalizing things, but all seems to 
> be well. Django injects the form css in the block extrastyle within 
> change_form.html. For Grappelli/django-xadmin that block is present, but 
> Grappelli overrides change_form.html, so that would probably need updating. 
> I haven't looked at any other admin-theme packages, but the change would be 
> trivial for them as well - providing a proper documentation notion.
>
> The only things so far I'm not really sure of are:
>
>    - Is deprecation required or not (input needed from other core devs I 
>    presume)
>    - what with the validation error messages: as it stands, field labels 
>    are capitalized at the moment, and they're not in a <label> tag. Examples 
>    can be found 
>    in: django.db.models.base.Model.(date_error_message|unique_error_message)
>
> In the tests I also noticed that there are cases where the label itself is 
> not wrapped in a <label> tag 
> (django.tests.forms_tests.tests.test_forms.FormsTestCase.test_templates_with_forms).
>
> On Friday, November 20, 2015 at 8:31:55 PM UTC+1, Tim Graham wrote:
>>
>> Looks easy enough. I was going to write, "Seems to me that there's more 
>> complexity in a deprecation path that requires a temporary opt-in setting 
>> rather than simply making the backwards incompatible change. Unless I 
>> missed something, adding CSS like that shouldn't cause problems for any 
>> apps maintaining compatibility with older versions of Django." but then I 
>> thought of a different case where it could be trickier to upgrade: 
>> developers who are specifying label='lower string' in some places to 
>> workaround the current behavior (but still want uppercased labels 
>> everywhere else). I guess the solution would be to use the text-transform 
>> rule you mentioned and another CSS rule targeting all labels IDs that you 
>> want to remain lowercased.
>>
>> I'd like other opinions about whether or not a deprecation seems helpful 
>> for this. Personally, I'd rather just fix my CSS when upgrading rather than 
>> fix my CSS *and* add a setting for a few Django versions to silence the 
>> deprecation. I guess some people might like a few Django versions to update 
>> their CSS though (also we promised to try to provide fairly seamless 
>> upgrades from one LTS to the next).
>>
>> On Friday, November 20, 2015 at 11:38:53 AM UTC-5, Sergei Maertens wrote:
>>>
>>> In 
>>> https://github.com/django/django/blob/master/django/contrib/admin/static/admin/css/forms.css#L31
>>>  
>>> <https://www.google.com/url?q=https%3A%2F%2Fgithub.com%2Fdjango%2Fdjango%2Fblob%2Fmaster%2Fdjango%2Fcontrib%2Fadmin%2Fstatic%2Fadmin%2Fcss%2Fforms.css%23L31&sa=D&sntz=1&usg=AFQjCNHYsYTv4mQblNJ7FiR_9EjUyq28oA>,
>>>  
>>> after
>>> label {
>>>    font-weight: normal;
>>>    color:#666;
>>>    font-size:13px;
>>> }
>>>
>>> you would add
>>> label::first-letter {
>>>    text-transform: capitalize;
>>> }
>>>
>>> (see https://css-tricks.com/almanac/selectors/f/first-letter/)
>>>
>>> text-transform: capitalize on the label itself would capitalize all 
>>> words, which is not wanted. The ::first-letter pseudo-selector is supported 
>>> on all browsers, for IE 8 and lower you need a sigle colon instead of a 
>>> double colon.
>>>
>>>
>>> On Thursday, November 19, 2015 at 11:23:48 PM UTC+1, Tim Graham wrote:
>>>>
>>>> I'd like to see the admin's CSS updated under the assumption that this 
>>>> change moves forward to better understand the extent of changes that would 
>>>> be required from Django users to maintain the current behavior.
>>>>
>>>> On Thursday, November 19, 2015 at 4:52:57 PM UTC-5, Sergei Maertens 
>>>> wrote:
>>>>>
>>>>> Yes, I've thought about a setting as well briefly but quickly 
>>>>> discarded it because it would be 'yet another setting'. But this one 
>>>>> would 
>>>>> ofcourse be temporarily, and if that's been applied successfully in the 
>>>>> past, then that's probably the best way to tackle this.
>>>>>
>>>>> I'd be happy to write the patch for this myself if no objections turn 
>>>>> up.
>>>>>
>>>>> On Thursday, November 19, 2015 at 10:49:49 PM UTC+1, Tim Graham wrote:
>>>>>>
>>>>>> The best solution I can think of at the moment would be a setting 
>>>>>> allowing users to opt-in to the new behavior which would then silence 
>>>>>> the 
>>>>>> warning. That leaves you with a defunct setting once the deprecation 
>>>>>> period 
>>>>>> completes. That's basically how SessionAuthenticationMiddleware 
>>>>>> worked when we decided to require it.
>>>>>>
>>>>>> On Thursday, November 19, 2015 at 4:13:40 PM UTC-5, Sergei Maertens 
>>>>>> wrote:
>>>>>>>
>>>>>>> Good catch.
>>>>>>>
>>>>>>> I'm not sure, haven't there been similar cases in the past? First 
>>>>>>> thing I can think of is using naive datetimes when timezone-support is 
>>>>>>> enabled, and then you get a warning for each naive datetime you use, 
>>>>>>> but 
>>>>>>> that's of course different then a DeprecationWarning.
>>>>>>>
>>>>>>> It's probably not best practice, but maybe it could be tracked with 
>>>>>>> a module-level flag/constant, to check if the warning has been emited 
>>>>>>> or 
>>>>>>> not, ensuring that it gets only emited once during the lifetime of a 
>>>>>>> thread?
>>>>>>>
>>>>>>> On Thursday, November 19, 2015 at 7:27:18 PM UTC+1, Tim Graham wrote:
>>>>>>>>
>>>>>>>> How would a developer acknowledge/silence that deprecation warning? 
>>>>>>>> It seems to me that if it's emitted for every form field in a project 
>>>>>>>> that's not really going to be helpful.
>>>>>>>>
>>>>>>>> On Wednesday, November 11, 2015 at 11:47:46 AM UTC-5, Sergei 
>>>>>>>> Maertens wrote:
>>>>>>>>>
>>>>>>>>> I think I would start with locally creating a wrapper capfirst 
>>>>>>>>> that is only called in the referenced line and 
>>>>>>>>> https://github.com/django/django/blob/master/django/db/models/fields/__init__.py#L2069
>>>>>>>>>  
>>>>>>>>> (missed that one in the previous post) and possible other ocurrences. 
>>>>>>>>> Emit 
>>>>>>>>> a PendingDeprecationWarning, something along the lines of
>>>>>>>>>
>>>>>>>>> def deprecated_capfirst(value):
>>>>>>>>>     warnings.warn(
>>>>>>>>>         "form field labels generated from model field 
>>>>>>>>> 'verbose_name' will no longer automatically be capitalized",
>>>>>>>>>         PendingDeprecationWarning, stacklevel=2
>>>>>>>>>     )
>>>>>>>>>     return capfirst(value)
>>>>>>>>>
>>>>>>>>> and replace the capfirst with deprecated_capfirst ofcourse. At the 
>>>>>>>>> same time, in the admin the CSS for labels can be added to 
>>>>>>>>> text-transform 
>>>>>>>>> them to capitalize.
>>>>>>>>>
>>>>>>>>> In the next Django version this becomes loud, and in the next+1 
>>>>>>>>> version it is effectively removed.
>>>>>>>>>
>>>>>>>>> As soon as the PendingDeprecation is added, the entry should be 
>>>>>>>>> added to the docs with example CSS to make your own templates/styling 
>>>>>>>>> capitalize the labels - and/or mention the `capfirst` template filter.
>>>>>>>>>
>>>>>>>>> Thoughts?
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On Wednesday, November 11, 2015 at 5:32:57 PM UTC+1, Tim Graham 
>>>>>>>>> wrote:
>>>>>>>>>>
>>>>>>>>>> How do you envision putting this through a deprecation cycle?
>>>>>>>>>>
>>>>>>>>>> On Wednesday, November 11, 2015 at 10:59:46 AM UTC-5, Sergei 
>>>>>>>>>> Maertens wrote:
>>>>>>>>>>>
>>>>>>>>>>> This is a proposal to change how Django generates form field 
>>>>>>>>>>> labels from model fields. Currently, `capfirst` is called on 
>>>>>>>>>>> `field.verbose_name` (see 
>>>>>>>>>>> https://github.com/django/django/blob/master/django/db/models/fields/__init__.py#L872
>>>>>>>>>>>  
>>>>>>>>>>> <https://www.google.com/url?q=https%3A%2F%2Fgithub.com%2Fdjango%2Fdjango%2Fblob%2Fmaster%2Fdjango%2Fdb%2Fmodels%2Ffields%2F__init__.py%23L872&sa=D&sntz=1&usg=AFQjCNGUcFeQthwsqiwrA57fw50I20lHtw>).
>>>>>>>>>>>  
>>>>>>>>>>> This behaviour has been around since pretty much forever and makes 
>>>>>>>>>>> sense.
>>>>>>>>>>>
>>>>>>>>>>> However, this affects what you put down in your translations - 
>>>>>>>>>>> if a lowercased verbose name is what you want (and you translate it 
>>>>>>>>>>> as 
>>>>>>>>>>> such), Django will make your form labels uppercase and there's no 
>>>>>>>>>>> clean way 
>>>>>>>>>>> around that.
>>>>>>>>>>>
>>>>>>>>>>> There is a very specific use case for this proposal. The 
>>>>>>>>>>> house-style of a design states that all form labels should be 
>>>>>>>>>>> lowercase - 
>>>>>>>>>>> but names of the brand should be capitalized. Example: 'you agree 
>>>>>>>>>>> to the 
>>>>>>>>>>> Brand terms'. This is not easily feasible: css text-transform will 
>>>>>>>>>>> also 
>>>>>>>>>>> lowercase the brand name, and Django uppercases the first letter. 
>>>>>>>>>>> Another 
>>>>>>>>>>> possible use case could be if you insist on putting the labels to 
>>>>>>>>>>> the right 
>>>>>>>>>>> of the form input, but I will agree that looks silly.
>>>>>>>>>>>
>>>>>>>>>>> So the proposal is to get rid of the capfirst call, and in the 
>>>>>>>>>>> admin this could be mitigated for backwards compatibility by 
>>>>>>>>>>> modifying the 
>>>>>>>>>>> css to include:
>>>>>>>>>>> label {
>>>>>>>>>>>     text-transform: capitalize;
>>>>>>>>>>> }
>>>>>>>>>>>
>>>>>>>>>>> This is ofcourse a fairly big backwards-incompatible change 
>>>>>>>>>>> towards front-end/non-vendor code, as people now have to explicitly 
>>>>>>>>>>> make 
>>>>>>>>>>> sure that labels are capitalized in their own templates. So this 
>>>>>>>>>>> should 
>>>>>>>>>>> probably go through the usual deprecation mechanics (silent, 
>>>>>>>>>>> warning, 
>>>>>>>>>>> remove), if it happens at all.
>>>>>>>>>>>
>>>>>>>>>>> What are current workarounds for this problem?
>>>>>>>>>>>
>>>>>>>>>>>    - explicitly specifying the label value in the ModelForm 
>>>>>>>>>>>    definition: this violates the DRY principle, you already defined 
>>>>>>>>>>> the 
>>>>>>>>>>>    verbose_name on the model field
>>>>>>>>>>>    - creating a form mixin that will lowercase the first letter 
>>>>>>>>>>>    of the label for all fields
>>>>>>>>>>>       - you still have to check if the first word if it's the 
>>>>>>>>>>>       Brand string, because then it should stay capitalized
>>>>>>>>>>>       - you now have to include this mixin in every single 
>>>>>>>>>>>       form, and can no longer rely on implicitly generated form 
>>>>>>>>>>> classes in 
>>>>>>>>>>>       generic CBV
>>>>>>>>>>>    - create a templatefilter that decapitalizes the label, and 
>>>>>>>>>>>    re-capitalizes 'brand' occurrences to 'Brand' (currently 
>>>>>>>>>>> implemented)
>>>>>>>>>>>       - you now have to not forget this filter everywhere you 
>>>>>>>>>>>       render forms
>>>>>>>>>>>       - performance hit if this is based on regular expressions 
>>>>>>>>>>>       (which in this case it is because subbrand should not become 
>>>>>>>>>>> subBrand)
>>>>>>>>>>>    
>>>>>>>>>>> All in all, I'm of the opinion that the flexibility you gain by 
>>>>>>>>>>> NOT manipulating the label in Django outweighs the backwards 
>>>>>>>>>>> incompatible 
>>>>>>>>>>> change. I'm also strongly of the opinion that capitalizing labels 
>>>>>>>>>>> is 
>>>>>>>>>>> something that should be done entirely in CSS - whether the label 
>>>>>>>>>>> is 
>>>>>>>>>>> capitalized, lower case or upper case shouldn't matter for Django's 
>>>>>>>>>>> internals.
>>>>>>>>>>>
>>>>>>>>>>> Reasons to not do this:
>>>>>>>>>>>
>>>>>>>>>>>    - cater to common convention, not clients (quoted from 
>>>>>>>>>>>    #django-dev on irc): in my opinion this works 95% of the time, 
>>>>>>>>>>> but your 
>>>>>>>>>>>    forced into violating some of Django's principles if you divert 
>>>>>>>>>>> from this, 
>>>>>>>>>>>    most notably DRY
>>>>>>>>>>>    - maintain backwards compatibility
>>>>>>>>>>>
>>>>>>>>>>> Reasons to do this:
>>>>>>>>>>>
>>>>>>>>>>>    - gain flexibility about the display of form labels
>>>>>>>>>>>    - keep the codebase sane
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Bonus: vaguely related ticket: 
>>>>>>>>>>> https://code.djangoproject.com/ticket/5518
>>>>>>>>>>>
>>>>>>>>>>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/6b13ca05-2eda-4d1f-b2bb-413998e78416%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to