{"id":12022,"date":"2018-09-27T03:03:48","date_gmt":"2018-09-27T01:03:48","guid":{"rendered":"http:\/\/blog.wenzlaff.de\/?p=12022"},"modified":"2022-03-16T18:48:06","modified_gmt":"2022-03-16T17:48:06","slug":"es-muss-ja-nicht-immer-apache-velocity-sein-apache-freemarker-tuts-auch","status":"publish","type":"post","link":"http:\/\/blog.wenzlaff.de\/?p=12022","title":{"rendered":"Es muss ja nicht immer Apache Velocity sein, Apache FreeMarker geht auch!"},"content":{"rendered":"<p>Es gibt unterschiedliche Template Engine, wie zum Beispiel <a href=\"https:\/\/velocity.apache.org\/\" rel=\"noopener noreferrer\" target=\"_blank\">Apache Velocity<\/a> aber auch <a href=\"https:\/\/freemarker.apache.org\/\" rel=\"noopener noreferrer\" target=\"_blank\">Apache Freemarker<\/a>. <\/p>\n<p>Bei der Verwendung von Templates, kann man sich einfach auf die Pr\u00e4sentation der Daten konzentrieren. Das l\u00e4uft nach dem MVC (Model View Controller) Pattern. Die Templats k\u00f6nnen auch <a href=\"https:\/\/try.freemarker.apache.org\/\" rel=\"noopener noreferrer\" target=\"_blank\">\u00fcber diesen Online FreeMarker Template Tester<\/a> ohne Aufwand getestet werden.<\/p>\n<p>Heute mal ein kleines Beispiel, mit Freemarker. Wir wollen Verzeichnisse nach Mindmaps durchsuchen, und alle gefundenen Mindmaps in eine HTML-Seite ausgeben. <\/p>\n<p><a href=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2018\/09\/FreeMarker-Template-Language-700x429.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2018\/09\/FreeMarker-Template-Language-700x429.png\" alt=\"\" width=\"700\" height=\"429\" class=\"aligncenter size-full wp-image-12023\" srcset=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2018\/09\/FreeMarker-Template-Language-700x429.png 700w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2018\/09\/FreeMarker-Template-Language-700x429-300x184.png 300w\" sizes=\"auto, (max-width: 700px) 100vw, 700px\" \/><\/a><\/p>\n<p>Fangen wir mit einem JUnit Test an:<!--more--><\/p>\n<p>Hier die Testmethode:<\/p>\n<pre class=\"lang:java decode:true \" >\r\n@Test\r\n\t@DisplayName(\"Schreibt eine HTML Seite mit FreeMarker Generator\")\r\n\tpublic void generateHtmlSeite() {\r\n\r\n\t\tList&lt;String&gt; verzeichnise = new ArrayList&lt;String&gt;(Arrays.asList(MINDMAP_INPUT_VERZEICHNISSE));\r\n\r\n\t\tGenerator generator = new Generator();\r\n\t\tConfiguration cfg = generator.getKonfiguration(CONFIG_DIR);\r\n\r\n\t\tint anzahlMindmpas = generator.generate(ERGEBNIS_HTML, MINDMAP_TEMPLATE, verzeichnise, cfg);\r\n\r\n\t\tassertEquals(654, anzahlMindmpas, \"Die Anzahl der Mindmaps hat sich ver\u00e4ndert.\");\r\n}<\/pre>\n<p>Wir brauchen einmalig (Singelton) eine Configuration, hier die Methode:<\/p>\n<pre class=\"lang:java decode:true \" >\r\n\/**\r\n\t * Liefert die Konfiguration. Dies muss nur einmal (Singelton) aufgerufen\r\n\t * werden.\r\n\t * \r\n\t * @param configPath der Path zu der Konfiguration\r\n\t * @return die Konfiguration\r\n\t *\/\r\n\tpublic Configuration getKonfiguration(String configPath) {\r\n\t\t\/\/ einmalig die Konfiguration anlegen\r\n\t\tConfiguration cfg = new Configuration(Configuration.VERSION_2_3_28);\r\n\t\ttry {\r\n\t\t\tcfg.setDirectoryForTemplateLoading(new File(configPath));\r\n\t\t\tcfg.setDefaultEncoding(\"UTF-8\");\r\n\t\t\tcfg.setLocale(Locale.GERMANY);\r\n\t\t\tcfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);\r\n\t\t\tcfg.setLogTemplateExceptions(false);\r\n\t\t\tcfg.setWrapUncheckedExceptions(true);\r\n\t\t} catch (IOException e) {\r\n\t\t\tSystem.err.println(\"Fehler beim laden der Template Konfiguration. \" + configPath + \" \" + e.getMessage());\r\n\t\t}\r\n\t\treturn cfg;\r\n\t}\r\n<\/pre>\n<p>Und dann die Methode, die die eigentlich Arbeit macht, die auch mehrfach aufgerufen werden kann:<\/p>\n<pre class=\"lang:java decode:true \" >\r\nprivate void generateHtml(String ausgabeHtmlDateiName, String mindmapTemplate, List<Mindmap> inputMindmaps,\r\n\t\t\tConfiguration configuration) {\r\n\r\n\t\t\/\/ Datenmodell anlegen f\u00fcr die Nutzung im Template\r\n\t\tMap<String, Object> datenModell = new HashMap<String, Object>();\r\n\t\tdatenModell.put(\"user\", \"Thomas Wenzlaff\");\r\n\t\tdatenModell.put(\"mindmaps\", inputMindmaps);\r\n\t\tdatenModell.put(\"datum\", new Date());\r\n\r\n\t\ttry {\r\n\t\t\t\/\/ das Mindmap Template holen, es wird gecached\r\n\t\t\tTemplate template = configuration.getTemplate(mindmapTemplate);\r\n\r\n\t\t\t\/\/ Datenmodel mit dem Template zusammenf\u00fcgen und in der Konsole und\r\n\t\t\t\/\/ Ergebnis.html ausgeben\r\n\t\t\tWriter outputWriter = new OutputStreamWriter(System.out);\r\n\t\t\ttemplate.process(datenModell, outputWriter);\r\n\r\n\t\t\tWriter fileWriter = new FileWriter(new File(ausgabeHtmlDateiName));\r\n\t\t\ttry {\r\n\t\t\t\ttemplate.process(datenModell, fileWriter);\r\n\t\t\t} finally {\r\n\t\t\t\tfileWriter.close();\r\n\t\t\t}\r\n\t\t} catch (TemplateException | IOException e) {\r\n\t\t\tSystem.err.println(\"Fehler im Template. \" + mindmapTemplate + \" \" + e.getMessage());\r\n\t\t}\r\n\t}\r\n<\/pre>\n<p>Damit die obige Methode mehrfach aufgerufen werden kann, verwende ich diese Methode, die aber f\u00fcr die Funktionsweise der Template-Engine nicht n\u00f6tig ist:<\/p>\n<pre class=\"lang:java decode:true \" >\/**\r\n\t * Generiert f\u00fcr die Input Verzeichnise mit dem Freemarker Template eine Ausgabe\r\n\t * Datei im HTML Format.\r\n\t * \r\n\t * @param ausgabeHtmlDateiName der zu erzeugende HTML Dateiname\r\n\t * @param mindmapTemplate      der Name des Freemarker Template\r\n\t * @param inputVerzeichnise    alle Input Verzeichnisse wo Mindmaps gesucht\r\n\t *                             werden\r\n\t * @param configuration        Konfiguration\r\n\t * @return die Anzahl der bearbeiteten Mindmaps\r\n\t *\/\r\n\tpublic int generate(String ausgabeHtmlDateiName, String mindmapTemplate, List&lt;String&gt; inputVerzeichnise,\r\n\t\t\tConfiguration configuration) {\r\n\r\n\t\tcheckParameter(ausgabeHtmlDateiName, mindmapTemplate, inputVerzeichnise, configuration);\r\n\r\n\t\tList&lt;Mindmap&gt; mindmaps = new ArrayList&lt;&gt;();\r\n\r\n\t\tfor (String inputVerzeichnis : inputVerzeichnise) {\r\n\t\t\tmindmaps.addAll(getMindmaps(inputVerzeichnis));\r\n\t\t}\r\n\r\n\t\t\/\/ Sortieren der Mindmaps von A-Z\r\n\t\tCollections.sort(mindmaps);\r\n\r\n\t\tgenerateHtml(ausgabeHtmlDateiName, mindmapTemplate, mindmaps, configuration);\r\n\r\n\t\treturn mindmaps.size();\r\n\t}\r\n<\/pre>\n<p>Ein einfaches Mindmap BE brauchen wir auch noch:<\/p>\n<pre class=\"lang:java decode:true \" >package de.wenzlaff.mindmap.be;\r\n\r\nimport java.nio.file.Path;\r\nimport java.time.LocalDateTime;\r\nimport java.time.ZoneOffset;\r\nimport java.util.Objects;\r\n\r\n\/**\r\n * Eine Mindmap BE.\r\n * \r\n * @author Thomas Wenzlaff\r\n *\r\n *\/\r\npublic class Mindmap implements Comparable&lt;Mindmap&gt; {\r\n\r\n\tprivate Path path;\r\n\r\n\tpublic Path getPath() {\r\n\t\treturn path;\r\n\t}\r\n\r\n\tpublic void setPath(Path path) {\r\n\t\tthis.path = path;\r\n\t}\r\n\r\n\tpublic String getErstelldatum() {\r\n\t\treturn new Date(getPath().toFile().lastModified()).toGMTString();\r\n\t}\r\n\r\n\t\/**\r\n\t * LIefert den Namen der Mindmap Datei.\r\n\t * \r\n\t * @return der Name der Datei.\r\n\t *\/\r\n\tpublic String getName() {\r\n\t\treturn getPath().getFileName().toString();\r\n\t}\r\n\r\n\t\/**\r\n\t * Liefert die Gr\u00f6\u00dfe der Mindmap Datei in kB (1000).\r\n\t * \r\n\t * Im Template Aufruf z.B.: (${mindmap.size} kB)\r\n\t * \r\n\t * @return die Gr\u00f6\u00dfe der Datei in kB.\r\n\t *\/\r\n\tpublic String getSize() {\r\n\t\treturn \"\" + getPath().toFile().length() \/ 1000;\r\n\t}\r\n\r\n\t@Override\r\n\tpublic int hashCode() {\r\n\t\treturn Objects.hash(path);\r\n\t}\r\n\r\n\t@Override\r\n\tpublic boolean equals(Object obj) {\r\n\t\tif (this == obj)\r\n\t\t\treturn true;\r\n\t\tif (obj == null)\r\n\t\t\treturn false;\r\n\t\tif (getClass() != obj.getClass())\r\n\t\t\treturn false;\r\n\t\tMindmap other = (Mindmap) obj;\r\n\t\treturn Objects.equals(path, other.path);\r\n\t}\r\n\r\n\t\/**\r\n\t * Der Name der Mindmap ohne Prefix.\r\n\t *\/\r\n\t@Override\r\n\tpublic String toString() {\r\n\t\treturn getName().substring(0, getName().length() - 5);\r\n\t}\r\n\r\n\t\/**\r\n\t * Zum sortieren von A-Z nach Namen.\r\n\t *\/\r\n\t@Override\r\n\tpublic int compareTo(Mindmap mindmap) {\r\n\t\treturn getName().compareTo(mindmap.getName());\r\n\t}\r\n\r\n}\r\n<\/pre>\n<p>Nun brauchen wir noch ein <a href=\"https:\/\/freemarker.apache.org\/\" rel=\"noopener noreferrer\" target=\"_blank\">Apache Freemarker<\/a> Template:<\/p>\n<pre class=\"lang:java decode:true \" >\r\n<html>\r\n<head>\r\n  <title>Mindmaps von ${user}<\/title>\r\n<\/head>\r\n<body>\r\n<h1>Mindmaps von ${user}!<\/h1>   \r\n<BR>\r\n   \r\n<#list mindmaps as mindmap>\r\n${mindmap}, \r\n<\/#list>\r\n\r\n<BR>\r\n<h1>Anzahl Mindmaps ${mindmaps?size}<\/h1>\r\n\r\n\r\nGeneriert mit TWMindmapGernerator am ${datum?datetime} Uhr\r\n\r\n<\/body>\r\n<\/html>\r\n<\/pre>\n<p>Dies Template, kann man leicht \u00e4ndern, um Anpassungen an der Ausgabe zu erhalten.<\/p>\n<p>Dann brauchen wir eine pom.xml mit den Freemarker und JUnit Abh\u00e4ngigkeiten:<\/p>\n<pre class=\"lang:xhtml decode:true \" >&lt;project xmlns=\"http:\/\/maven.apache.org\/POM\/4.0.0\"\r\n\txmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"\r\n\txsi:schemaLocation=\"http:\/\/maven.apache.org\/POM\/4.0.0 http:\/\/maven.apache.org\/xsd\/maven-4.0.0.xsd\"&gt;\r\n\t&lt;modelVersion&gt;4.0.0&lt;\/modelVersion&gt;\r\n\t&lt;groupId&gt;de.wenzlaff.twmindmapgenerator&lt;\/groupId&gt;\r\n\t&lt;artifactId&gt;de.wenzlaff.twmindmapgenerator&lt;\/artifactId&gt;\r\n\t&lt;version&gt;0.0.1-SNAPSHOT&lt;\/version&gt;\r\n\r\n\r\n\t&lt;properties&gt;\r\n\t\t&lt;project.build.sourceEncoding&gt;UTF-8&lt;\/project.build.sourceEncoding&gt;\r\n\t\t&lt;maven.compiler.source&gt;1.8&lt;\/maven.compiler.source&gt;\r\n\t\t&lt;maven.compiler.target&gt;1.8&lt;\/maven.compiler.target&gt;\r\n\r\n\t\t&lt;project.reporting.outputEncoding&gt;UTF-8&lt;\/project.reporting.outputEncoding&gt;\r\n\t\t&lt;java.version&gt;1.8&lt;\/java.version&gt;\r\n\t\t&lt;junit.jupiter.version&gt;5.0.0-M2&lt;\/junit.jupiter.version&gt;\r\n\t\t&lt;junit.vintage.version&gt;4.12.0-M2&lt;\/junit.vintage.version&gt;\r\n\t\t&lt;junit.platform.version&gt;1.0.0-M2&lt;\/junit.platform.version&gt;\r\n\t&lt;\/properties&gt;\r\n\r\n\r\n\t&lt;build&gt;\r\n\t\t&lt;plugins&gt;\r\n\r\n\t\t\t&lt;plugin&gt;\r\n\t\t\t\t&lt;groupId&gt;org.apache.maven.plugins&lt;\/groupId&gt;\r\n\t\t\t\t&lt;artifactId&gt;maven-compiler-plugin&lt;\/artifactId&gt;\r\n\t\t\t\t&lt;version&gt;3.7.0&lt;\/version&gt;\r\n\t\t\t\t&lt;configuration&gt;\r\n\t\t\t\t\t&lt;source&gt;${maven.compiler.source}&lt;\/source&gt;\r\n\t\t\t\t\t&lt;target&gt;${maven.compiler.target}&lt;\/target&gt;\r\n\t\t\t\t\t&lt;encoding&gt;${project.build.sourceEncoding}&lt;\/encoding&gt;\r\n\t\t\t\t&lt;\/configuration&gt;\r\n\t\t\t&lt;\/plugin&gt;\r\n\t\t&lt;\/plugins&gt;\r\n\t&lt;\/build&gt;\r\n\t&lt;dependencies&gt;\r\n\t\t&lt;dependency&gt;\r\n\t\t\t&lt;groupId&gt;org.freemarker&lt;\/groupId&gt;\r\n\t\t\t&lt;artifactId&gt;freemarker&lt;\/artifactId&gt;\r\n\t\t\t&lt;version&gt;2.3.28&lt;\/version&gt;\r\n\t\t&lt;\/dependency&gt;\r\n\t\t&lt;dependency&gt;\r\n\t\t\t&lt;groupId&gt;org.junit.jupiter&lt;\/groupId&gt;\r\n\t\t\t&lt;artifactId&gt;junit-jupiter-engine&lt;\/artifactId&gt;\r\n\t\t\t&lt;version&gt;${junit.jupiter.version}&lt;\/version&gt;\r\n\t\t\t&lt;scope&gt;test&lt;\/scope&gt;\r\n\t\t&lt;\/dependency&gt;\r\n\t\t&lt;dependency&gt;\r\n\t\t\t&lt;groupId&gt;org.junit.vintage&lt;\/groupId&gt;\r\n\t\t\t&lt;artifactId&gt;junit-vintage-engine&lt;\/artifactId&gt;\r\n\t\t\t&lt;version&gt;${junit.vintage.version}&lt;\/version&gt;\r\n\t\t\t&lt;scope&gt;test&lt;\/scope&gt;\r\n\t\t&lt;\/dependency&gt;\r\n\t\t&lt;dependency&gt;\r\n\t\t\t&lt;groupId&gt;junit&lt;\/groupId&gt;\r\n\t\t\t&lt;artifactId&gt;junit&lt;\/artifactId&gt;\r\n\t\t\t&lt;version&gt;4.12&lt;\/version&gt;\r\n\t\t\t&lt;scope&gt;test&lt;\/scope&gt;\r\n\t\t&lt;\/dependency&gt;\r\n\t&lt;\/dependencies&gt;\r\n\r\n&lt;\/project&gt;<\/pre>\n<p>Das ist eigentlich alles f\u00fcr das generieren. Jetzt nur noch die Verzeichnisse einlesen und das Ergebnis ausgeben, durch das Starten des JUnit Tests:<\/p>\n<p><a href=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2018\/09\/Bildschirmfoto-2018-09-26-um-21.13.07.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2018\/09\/Bildschirmfoto-2018-09-26-um-21.13.07.png\" alt=\"\" width=\"564\" height=\"148\" class=\"aligncenter size-full wp-image-12028\" srcset=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2018\/09\/Bildschirmfoto-2018-09-26-um-21.13.07.png 564w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2018\/09\/Bildschirmfoto-2018-09-26-um-21.13.07-300x79.png 300w\" sizes=\"auto, (max-width: 564px) 100vw, 564px\" \/><\/a><\/p>\n<p>So &#8230;<br \/>\n<a href=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2018\/09\/Bildschirmfoto-2018-09-26-um-21.08.27.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2018\/09\/Bildschirmfoto-2018-09-26-um-21.08.27.png\" alt=\"\" width=\"1683\" height=\"914\" class=\"aligncenter size-full wp-image-12025\" srcset=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2018\/09\/Bildschirmfoto-2018-09-26-um-21.08.27.png 1683w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2018\/09\/Bildschirmfoto-2018-09-26-um-21.08.27-300x163.png 300w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2018\/09\/Bildschirmfoto-2018-09-26-um-21.08.27-768x417.png 768w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2018\/09\/Bildschirmfoto-2018-09-26-um-21.08.27-1024x556.png 1024w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/a><\/p>\n<p>Jetzt kann man durch eine kleine \u00c4nderung des Templates, z.B. eine Tabelle ausgeben:<\/p>\n<pre class=\"lang:default decode:true \" >&lt;table&gt; \r\n&lt;#list mindmaps as mindmap&gt;\r\n&lt;tr&gt;&lt;td&gt;${mindmap}&lt;\/td&gt; &lt;td&gt;(${mindmap.size} kB)&lt;\/td&gt; &lt;td&gt;${mindmap.erstelldatum}&lt;\/td&gt;&lt;\/tr&gt; \r\n&lt;\/#list&gt;\r\n&lt;\/table&gt;<\/pre>\n<p>Die dann so aussieht:<\/p>\n<p><a href=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2018\/09\/Bildschirmfoto-2018-09-26-um-21.51.11.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2018\/09\/Bildschirmfoto-2018-09-26-um-21.51.11.png\" alt=\"\" width=\"638\" height=\"578\" class=\"aligncenter size-full wp-image-12032\" srcset=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2018\/09\/Bildschirmfoto-2018-09-26-um-21.51.11.png 638w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2018\/09\/Bildschirmfoto-2018-09-26-um-21.51.11-300x272.png 300w\" sizes=\"auto, (max-width: 638px) 100vw, 638px\" \/><\/a><\/p>\n<p>Genauso k\u00f6nnte man leicht CSV oder auch sonstige Dateiformate ausgeben.<\/p>\n<p>Das ganze Projekt kann von <a href=\"http:\/\/blog.wenzlaff.de\/?p=12043\">GitLab<\/a> geladen werden mit <\/p>\n<p><strong>git clone https:\/\/gitlab.com\/IT-Berater\/twmindmapgenerator.git<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Es gibt unterschiedliche Template Engine, wie zum Beispiel Apache Velocity aber auch Apache Freemarker. Bei der Verwendung von Templates, kann man sich einfach auf die Pr\u00e4sentation der Daten konzentrieren. Das l\u00e4uft nach dem MVC (Model View Controller) Pattern. Die Templats k\u00f6nnen auch \u00fcber diesen Online FreeMarker Template Tester ohne Aufwand getestet werden. Heute mal ein &hellip; <\/p>\n<p class=\"link-more\"><a href=\"http:\/\/blog.wenzlaff.de\/?p=12022\" class=\"more-link\"><span class=\"screen-reader-text\">\u201eEs muss ja nicht immer Apache Velocity sein, Apache FreeMarker geht auch!\u201c <\/span>weiterlesen<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[220,5,1361,79,7],"tags":[500,3417,3416,1486,2178,394,3418,3415,526],"class_list":["post-12022","post","type-post","status-publish","format-standard","hentry","category-anleitung","category-java","category-java-8","category-programmierung","category-tools","tag-apache","tag-engine","tag-freemarker","tag-generator","tag-java","tag-template","tag-template-engine","tag-template-language","tag-velocity"],"_links":{"self":[{"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/posts\/12022","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=12022"}],"version-history":[{"count":0,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/posts\/12022\/revisions"}],"wp:attachment":[{"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=12022"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=12022"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=12022"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}