diff --git a/package-lock.json b/package-lock.json
index e8cd4f6db..85489c970 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13,6 +13,8 @@
         "@codemirror/state": "^6.1.0",
         "@codemirror/theme-one-dark": "^6.0.0",
         "@codemirror/view": "^6.1.2",
+        "@ssddanbrown/codemirror-lang-smarty": "^1.0.0",
+        "@ssddanbrown/codemirror-lang-twig": "^1.0.0",
         "clipboard": "^2.0.11",
         "codemirror": "^6.0.1",
         "dropzone": "^5.9.3",
@@ -22,6 +24,7 @@
         "sortablejs": "^1.15.0"
       },
       "devDependencies": {
+        "@lezer/generator": "^1.2.2",
         "chokidar-cli": "^3.0",
         "esbuild": "^0.17.3",
         "livereload": "^0.9.3",
@@ -557,6 +560,19 @@
         "@lezer/lr": "^1.0.0"
       }
     },
+    "node_modules/@lezer/generator": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/@lezer/generator/-/generator-1.2.2.tgz",
+      "integrity": "sha512-O//eH9jTPM1GnbZruuD23xU68Pkuragonn1DEIom4Kt/eJN/QFt7Vzvp1YjV/XBmoUKC+2ySPgrA5fMF9FMM2g==",
+      "dev": true,
+      "dependencies": {
+        "@lezer/common": "^1.0.2",
+        "@lezer/lr": "^1.3.0"
+      },
+      "bin": {
+        "lezer-generator": "dist/lezer-generator.cjs"
+      }
+    },
     "node_modules/@lezer/highlight": {
       "version": "1.1.3",
       "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.1.3.tgz",
@@ -610,6 +626,21 @@
         "@lezer/lr": "^1.1.0"
       }
     },
+    "node_modules/@ssddanbrown/codemirror-lang-smarty": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@ssddanbrown/codemirror-lang-smarty/-/codemirror-lang-smarty-1.0.0.tgz",
+      "integrity": "sha512-F0ut1kmdbT3eORk3xVIKfQsGCZiQdh+6sLayBa0+FTex2gyIQlVQZRRA7bPSlchI3uZtWwNnqGNz5O/QLWRlFg=="
+    },
+    "node_modules/@ssddanbrown/codemirror-lang-twig": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@ssddanbrown/codemirror-lang-twig/-/codemirror-lang-twig-1.0.0.tgz",
+      "integrity": "sha512-7WIMIh8Ssc54TooGCY57WU2rKEqZZrcV2tZSVRPtd0gKYsrDEKCSLWpQjUWEx7bdgh3NKHUjq1O4ugIzI/+dwQ==",
+      "dependencies": {
+        "@codemirror/language": "^6.0.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0"
+      }
+    },
     "node_modules/ansi-regex": {
       "version": "4.1.1",
       "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
diff --git a/package.json b/package.json
index 24f451a9c..6b6dbbe46 100644
--- a/package.json
+++ b/package.json
@@ -15,6 +15,7 @@
     "permissions": "chown -R $USER:$USER bootstrap/cache storage public/uploads"
   },
   "devDependencies": {
+    "@lezer/generator": "^1.2.2",
     "chokidar-cli": "^3.0",
     "esbuild": "^0.17.3",
     "livereload": "^0.9.3",
@@ -31,6 +32,8 @@
     "@codemirror/state": "^6.1.0",
     "@codemirror/theme-one-dark": "^6.0.0",
     "@codemirror/view": "^6.1.2",
+    "@ssddanbrown/codemirror-lang-smarty": "^1.0.0",
+    "@ssddanbrown/codemirror-lang-twig": "^1.0.0",
     "clipboard": "^2.0.11",
     "codemirror": "^6.0.1",
     "dropzone": "^5.9.3",
diff --git a/resources/js/code/languages.js b/resources/js/code/languages.js
index 61aaeeefe..4a3591624 100644
--- a/resources/js/code/languages.js
+++ b/resources/js/code/languages.js
@@ -23,15 +23,16 @@ import {ruby} from '@codemirror/legacy-modes/mode/ruby';
 import {rust} from '@codemirror/legacy-modes/mode/rust';
 import {scheme} from '@codemirror/legacy-modes/mode/scheme';
 import {shell} from '@codemirror/legacy-modes/mode/shell';
+import {smarty} from "@ssddanbrown/codemirror-lang-smarty";
 import {standardSQL, pgSQL, msSQL, mySQL, sqlite, plSQL} from '@codemirror/legacy-modes/mode/sql';
 import {stex} from '@codemirror/legacy-modes/mode/stex';
+import {swift} from "@codemirror/legacy-modes/mode/swift";
 import {toml} from '@codemirror/legacy-modes/mode/toml';
-// import {twig, smarty} from '@codemirror/legacy-modes/mode/php'; // TODO
+import {twig} from "@ssddanbrown/codemirror-lang-twig";
 import {vb} from '@codemirror/legacy-modes/mode/vb';
 import {vbScript} from '@codemirror/legacy-modes/mode/vbscript';
 import {xml, html} from '@codemirror/legacy-modes/mode/xml';
 import {yaml} from '@codemirror/legacy-modes/mode/yaml';
-import {swift} from "@codemirror/legacy-modes/mode/swift";
 
 
 // Mapping of possible languages or formats from user input to their codemirror modes.
@@ -97,10 +98,12 @@ const modeMap = {
     scheme: () => StreamLanguage.define(scheme),
     shell: () => StreamLanguage.define(shell),
     sh: () => StreamLanguage.define(shell),
+    smarty: () => StreamLanguage.define(smarty),
     stext: () => StreamLanguage.define(stex),
     swift: () => StreamLanguage.define(swift),
     toml: () => StreamLanguage.define(toml),
     ts: () => StreamLanguage.define(typescript),
+    twig: () => twig(),
     typescript: () => StreamLanguage.define(typescript),
     sql: () => StreamLanguage.define(standardSQL),
     sqlite: () => StreamLanguage.define(sqlite),
diff --git a/resources/js/code/setups.js b/resources/js/code/setups.js
index 45cc9c317..e1a150856 100644
--- a/resources/js/code/setups.js
+++ b/resources/js/code/setups.js
@@ -6,6 +6,8 @@ import {defaultHighlightStyle, syntaxHighlighting, bracketMatching,
 import {defaultKeymap, history, historyKeymap} from "@codemirror/commands"
 import {EditorState} from "@codemirror/state"
 
+import {defaultLight} from "./themes";
+
 export function viewer() {
     return [
         lineNumbers(),
@@ -14,7 +16,7 @@ export function viewer() {
         history(),
         drawSelection(),
         dropCursor(),
-        syntaxHighlighting(defaultHighlightStyle, {fallback: true}),
+        syntaxHighlighting(defaultLight, {fallback: true}),
         bracketMatching(),
         rectangularSelection(),
         highlightActiveLine(),
diff --git a/resources/js/code/themes.js b/resources/js/code/themes.js
new file mode 100644
index 000000000..43feb2d53
--- /dev/null
+++ b/resources/js/code/themes.js
@@ -0,0 +1,46 @@
+import {tags} from "@lezer/highlight";
+import {HighlightStyle} from "@codemirror/language";
+
+export const defaultLight = HighlightStyle.define([
+    { tag: tags.meta,
+        color: "#388938" },
+    { tag: tags.link,
+        textDecoration: "underline" },
+    { tag: tags.heading,
+        textDecoration: "underline",
+        fontWeight: "bold" },
+    { tag: tags.emphasis,
+        fontStyle: "italic" },
+    { tag: tags.strong,
+        fontWeight: "bold" },
+    { tag: tags.strikethrough,
+        textDecoration: "line-through" },
+    { tag: tags.keyword,
+        color: "#708" },
+    { tag: [tags.atom, tags.bool, tags.url, tags.contentSeparator, tags.labelName],
+        color: "#219" },
+    { tag: [tags.literal, tags.inserted],
+        color: "#164" },
+    { tag: [tags.string, tags.deleted],
+        color: "#a11" },
+    { tag: [tags.regexp, tags.escape, tags.special(tags.string)],
+        color: "#e40" },
+    { tag: tags.definition(tags.variableName),
+        color: "#00f" },
+    { tag: tags.local(tags.variableName),
+        color: "#30a" },
+    { tag: [tags.typeName, tags.namespace],
+        color: "#085" },
+    { tag: tags.className,
+        color: "#167" },
+    { tag: [tags.special(tags.variableName), tags.macroName],
+        color: "#256" },
+    { tag: tags.definition(tags.propertyName),
+        color: "#00c" },
+    { tag: tags.compareOperator,
+        color: "#708" },
+    { tag: tags.comment,
+        color: "#940" },
+    { tag: tags.invalid,
+        color: "#f00" }
+]);
\ No newline at end of file
diff --git a/resources/js/code/views.js b/resources/js/code/views.js
index cada9a1d6..8202551b3 100644
--- a/resources/js/code/views.js
+++ b/resources/js/code/views.js
@@ -24,7 +24,7 @@ export function createView(config) {
 }
 
 /**
- * Ge the theme extension to use for editor view instance.
+ * Get the theme extension to use for editor view instance.
  * @returns {Extension}
  */
 function getTheme(viewParentEl) {