Skip to content

Instantly share code, notes, and snippets.

Last active Aug 3, 2021
What would you like to do?
Web-mode with liquid syntax for Shopify

Getting web-mode to play nice with Shopify liquid the “Trevor” way.

I could see myself wanting to do specific things on specific filetypes, regardless of what major mode it falls into. Web mode attempts to “catch-all” but there are still unique aspects of some templating engines that I want to control. I also don’t want to write the same conditional every time, so let’s make it a function with a callback.

(defun on-filetype(pattern func) "Checks the extension and fires a callback if it matches"
  (when (and (stringp buffer-file-name)
             (string-match pattern buffer-file-name))
  (funcall func)))

Use web-mode for html and liquid syntax. Tell web-mode that I don’t want to use their auto-pairing as it diverges from what I enjoy using (electric-pair)

(use-package web-mode
  :ensure t
  (setq web-mode-enable-auto-pairing nil)
  ("\\.html\\'" . web-mode)
  ("\\.liquid\\'" . web-mode))

Configure my automatic modes for other liquid files. Yes, Shopify lets you use liquid in CSS and even JS modes. It makes Shopify dynamic but confuses the heck out of linters/language-servers. I live with a lot of red squiggles.

Here I define when and how I want electric pair to auto-pair the {% keyword %} pattern in liquid files only.

(add-to-list 'auto-mode-alist '("\\.css.liquid\\'" . css-mode))
(add-to-list 'auto-mode-alist '("\\.scss.liquid\\'" . scss-mode))

(defvar liquid-electric-pairs '((?% . ?%)) "Electric pairs for liquid syntax.")
(defun liquid-add-electric-pairs ()
  (setq-local electric-pair-pairs (append electric-pair-pairs liquid-electric-pairs))
  (setq-local electric-pair-text-pairs electric-pair-pairs))

(add-hook 'web-mode-hook (lambda () (on-filetype "\\.liquid\\'" #'liquid-add-electric-pairs)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment