Fahri Firdausillah
Fahri Firdausillah

Reputation: 694

How to make VSCode format Django templates properly?

I love VSCode on-save auto-format, until it messed up with my template code.

It wrongly formats my django template syntax into one line code (sometimes really long line). So instead of having this code

{% for row in 'ABCDEFGH' %}
<tr>
  {% for col in '123456789012345' %}
    <td>
      {% with forloop.counter|stringformat:"s" as counter %}
        {% with row|add:counter as seat_num %}
          {% if seat_num not in oc_seats %}
            <input type="checkbox" value="{{ row }}{{ forloop.counter }}" name="seats">
          {% endif %}
          <br> {{ seat_num }} 
        {% endwith %}
      {% endwith %}
     </td>    
   {% endfor %}
</tr>
{% endfor %}

I end up have this code

{% for row in 'ABCDEFGH' %}
<tr>
  {% for col in '123456789012345' %}
  <td style="text-align: center; border: 1px solid #aaa;">
    {% with forloop.counter|stringformat:"s" as counter %} {% with row|add:counter as seat_num %} {% if seat_num not in oc_seats %}
    <input type="checkbox" value="{{ row }}{{ forloop.counter }}" name="seats"> {% endif %} {{ seat_num }} {% endwith %} {% endwith %}
  </td>
  {% endfor %}
</tr>
{% endfor %}

I tried to disable format on save by changing user settings into {"editor.formatOnSave": false} but still haven't gotten any luck.

Is there any configuration that I can use to make it work better?

PS: I'm using VSCode version 1.9 on Sierra MacOSx

Upvotes: 55

Views: 49251

Answers (12)

Vidyesh Churi
Vidyesh Churi

Reputation: 2579

As you will most likely be using vscode workspace settings, add extensions astral ruff and djlint then go to

settings.json

and add,

{
    "editor.defaultFormatter": "charliermarsh.ruff",
    "editor.formatOnSave": true,
    "[django-html]": {
        "editor.defaultFormatter": "monosans.djlint"
    }
}

Now this will corresctly format on every CMD+S or Ctrl+S

Upvotes: 0

Steve G.
Steve G.

Reputation: 688

I tried and now highly recommend the djlint extension to format Django HTML code. It is effective and quite configurable.

First, you need to manually install the Python package djlint in your current virtual environment (or globally).

Then you need to select Python interpreter where you installed the djlint extension in VSCode - Open the Command Palette, type Python: Select Interpreter, then select the Python environment where you installed djlint

Finally, install the actual djlint-vscode VSCode extension.

With your code, the output is:

{% for row in 'ABCDEFGH' %}
    <tr>
        {% for col in '123456789012345' %}
            <td style="text-align: center; border: 1px solid #aaa;">
                {% with forloop.counter|stringformat:"s" as counter %}
                    {% with row|add:counter as seat_num %}
                        {% if seat_num not in oc_seats %}
                            <input type="checkbox" value="{{ row }}{{ forloop.counter }}" name="seats">
                        {% endif %}
                        {{ seat_num }}
                    {% endwith %}
                {% endwith %}
            </td>
        {% endfor %}
    </tr>
{% endfor %}

Upvotes: 10

Arunas Bart
Arunas Bart

Reputation: 2678

For Prettier users, I want autoformat to work, thus:

Press ctrl/cmd+shift+p to open command bar and enter settings, then choose "Open User Settings (JSON)".

Append following to settings.json file:

  "[django-html]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "editor.formatOnType": true,
    "editor.formatOnSave": true,
    "editor.formatOnSaveMode": "file"
  }

This will not break any snippets defined for django html.

Still very convenient that all html snippets ant autocomplete also works in django templates, thus add

  "emmet.includeLanguages": { "django-html": "html" },

and you can choose any formatter like:

  • esbenp.prettier-vscode - does autoformat
  • dbaeumer.vscode-eslint - does not for me
  • batisteo.vscode-django - does not for me

Upvotes: -1

Joshysmart
Joshysmart

Reputation: 50

vscode eslint does not work on Django files. so to disable the prettier extension just add this to your settings.json

"[django-html]": {
    "editor.defaultFormatter": "dbaeumer.vscode-eslint"
  },

A similar solution would be

"[django-html]": {
    "editor.formatOnSave": false
  },

worked for me.

Upvotes: 1

Orvis Evans
Orvis Evans

Reputation: 169

Prettier in VSCode was the culprit in my situation. I got it to stop formatting with following in my settings.json.

"files.associations": {
   "**/*.html": "html",
   "**/templates/*/*.html": "django-html",
   "**/templates/*": "django-txt",
   "**/requirements{/**,*}.{txt,in}": "pip-requirements"
},    
"[django-html]": {
   "editor.defaultFormatter": "batisteo.vscode-django"
},

files.associations sets the language mode for the templates to django-html. [django-html] sets the settings for that language mode. As of writing this, the formatter in batisteo.vscode-django doesn't do anything for me (so it's the same as null in its place), but I left it there in case the django extension ever does.

Upvotes: 7

bhansa
bhansa

Reputation: 7504

You can disable the formatting option for some of the languages:

Go to Extensions and then "Extension settings" of Prettier and add django-html for this case as below.

disable language - prettier

Upvotes: 2

Phil
Phil

Reputation: 297

I used the beautify extension instead which worked right away while prettier was still putting on one line. Credit goes to kimanihuon on this stackoverflow page.

  1. Add the following to settings.json
"files.associations": {
   "**/*.html": "html",
   "**/templates/*/*.html": "django-html",
   "**/templates/*": "django-txt",
   "**/requirements{/**,*}.{txt,in}": "pip-requirements"
},

"emmet.includeLanguages": {
   "django-html": "html"
},
  1. Install beautify and then add following to settings.json
"beautify.language": {
   "html": [
       "htm",
       "html",
       "django-html"
   ]
},
  1. Restart VSCode just in case

Upvotes: 28

TUFAN POYRAZ
TUFAN POYRAZ

Reputation: 59

in VSCode's settings.json, add the following : emmet.includeLanguages": {"django-html": "html"}

Upvotes: -1

Espoir Murhabazi
Espoir Murhabazi

Reputation: 6376

Alexa has a good point in her answer. The file mode needs to be changed in "Django/HTML" to prevent VS CODE for formatting it.

How to change the file mode?

A quick solution is to use this extension called vscode-Django and adjust your setting like this as said in his documentation.

"files.associations": {
    "**/templates/*.html": "django-html",
    "**/templates/*": "django-txt"
}

With those setting any file located in the template folder will be considered as a Django template file and will not be affected by HTML autoformat.

PS: The extension is still in preview mode, hope it will get better with time.

Upvotes: 24

Alexa
Alexa

Reputation: 1157

Changing the language mode of the file to "Django/HTML" will also prevent VSCode from autoformatting it.

Upvotes: 16

Majid Max
Majid Max

Reputation: 517

you can disable the default html formatter, goto File > Preferences > User or Workspace Settings, in HTML settings you will find :

// Enable/disable default HTML formatter (requires restart)
  "html.format.enable": true,

I think VSCode uses js-beautify as default formatter, you can use beautify extension to override it settings with .jsbeautifyrc in project directory

Upvotes: 4

Tony
Tony

Reputation: 75

Had the same issue, found a post where the person disabled JS-CSS-HTML Formatter extension (https://stackoverflow.com/a/42100808/4812548) and it fixed the issue. Tested on mine and it seems to have worked too. Hope that helps

Upvotes: 3

Related Questions