Project homepage :

For a long time html-mode was the best option for web editing in Emacs. Although it works well for straight html, it can struggle when in template languages.

Packages like mumamo and mmm-mode make it possible to mix major modes together, but I haven't had much success with them.

web-mode is a mode made specifically for editing HTML with embedded templates. It supports the following languages:

And 15 more (at the time of writing).

It's one of the modes I use most, so it makes sense to learn some more about it.

Adding a file extension to web-mode

To make Emacs use web-mode for a specific file extension, add the following to .emacs.d/init.el (or another file where your configuration lives).

;; Make Emacs use web-mode for .phtml files.
(add-to-list 'auto-mode-alist '("\\.phtml\\'" . web-mode))

Navigation key bindings

C-c C-n
Jump between opening and closing tags. The cursor has to be on the tag (not the tag content) for this to work.
C-c C-e b
Jump to the beginning of the current element.
C-c C-e b
Jump to the end of the current element.

Region selection key bindings

C-c C-e s
Select the current element (opening through closing).
C-c C-m
Expand the current selection to the nearest element. I prefer to use expand region, but this is still quite useful.

Other useful key bindings

C-c C-e c
Clone the current element under the cursor. Useful when filling something like a table and wanting to replicate a column.
C-c C-f
Fold or unfold the current block.
Comment the current line or region. Automatically works with whatever template language is currently under the cursor.

Per-project indentation

Different projects may have different coding styles. Some require tabs, some require 4 spaces and some require 2 spaces.

Thankfully Emacs supports per-directory settings via dir-locals.el. The following code will set a project to use tabs instead of spaces, and to display tab width as 2 characters.

((web-mode . ((indent-tabs-mode . t)
	      (tab-width . 2))))

This example will use 4 spaces for indentation.

((web-mode . ((indent-tabs-mode . nil)
	      (web-mode-markup-indent-offset . 4))))


C-c C-s will insert a snippet at the current location. An example snippet looks a bit like this:

(setq web-mode-extra-snippets
      '(("php" . (("foreach" . "<?php foreach ( $items as $item ) : ?>\n(|)\n<?php endforeach; ?>")))))

Which inserts the following and places the cursor at the | character:

<?php foreach ( $items as $item ) : ?>
<?php endforeach ?>

I prefer to use emmet-mode for generating HTML quickly and yasnippet for other modes, so this isn't something I have much experience with.

This post is part of the "Exploring my Emacs packages" series.