diff --git a/README.md b/README.md index 217008b..9baffa3 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,11 @@ ## What does it do This package extends the Contao backend with the [Yoast SEO](https://github.com/Yoast/wordpress-seo/tree/trunk/packages/yoastseo#yoastseojs) plugin. -For this, an input field named keyword gets created under the edit view of the Page structure. -And then on each text content field you get a display of the Yoast SEO results. +Every tinymce gets the Yoast SEO Results appended. +For the keyword (Keyphrase), an input field named `keyword` gets created under the edit view of the Page structure, this gets integrated in all articles under that Page structure. + +This Plugin also works with the [MetaModels](https://github.com/MetaModels/core) bundle and adds the SEO Results to every tinymce that is created with this bundle. +Here, you can create an extra filed named `keyword` or `keyword_translated` so that the SEO Results include the keyword search. ## Example ![Preview of the Contao admin panel](doc/preview.png) \ No newline at end of file diff --git a/composer.json b/composer.json index f164eec..d5841d3 100644 --- a/composer.json +++ b/composer.json @@ -18,8 +18,8 @@ } ], "support": { - "issues": "https://github.com/imi/yoast-seo-for-contao/issues", - "source": "https://github.com/imi/yoast-seo-for-contao" + "issues": "https://github.com/iMi-digital/yoast-seo-for-contao/issues", + "source": "https://github.com/iMi-digital/yoast-seo-for-contao" }, "require": { "php": "^8.1", diff --git a/contao/config/config.php b/contao/config/config.php new file mode 100644 index 0000000..9f0c344 --- /dev/null +++ b/contao/config/config.php @@ -0,0 +1,3 @@ +'; \ No newline at end of file diff --git a/public/assets/index.js b/public/assets/index.js deleted file mode 100644 index 0cea7fa..0000000 --- a/public/assets/index.js +++ /dev/null @@ -1 +0,0 @@ -import"./main.js";import"./app.js";(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const e of document.querySelectorAll('link[rel="modulepreload"]'))i(e);new MutationObserver(e=>{for(const r of e)if(r.type==="childList")for(const o of r.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&i(o)}).observe(document,{childList:!0,subtree:!0});function s(e){const r={};return e.integrity&&(r.integrity=e.integrity),e.referrerPolicy&&(r.referrerPolicy=e.referrerPolicy),e.crossOrigin==="use-credentials"?r.credentials="include":e.crossOrigin==="anonymous"?r.credentials="omit":r.credentials="same-origin",r}function i(e){if(e.ep)return;e.ep=!0;const r=s(e);fetch(e.href,r)}})(); diff --git a/public/assets/main.js b/public/assets/main.js index 1a4fda7..fe02ab2 100644 --- a/public/assets/main.js +++ b/public/assets/main.js @@ -1 +1 @@ -import{A as a,_ as c}from"./app.js";const r=new a(new Worker(new URL(""+new URL("webworker-767f3803.js",import.meta.url).href,self.location),{type:"module"}));console.debug("YoastSeo loaded");typeof tinymce!="undefined"&&tinymce.on("SetupEditor",function(l){const e=l.editor,n=document.getElementById("pal_text_legend");n.innerHTML+='
',s(e),e.on("keyup",function(t){s(e)})});function s(l){r.initialize({locale:"de_DE",contentAnalysisActive:!0,keywordAnalysisActive:!0,logLevel:"ERROR"}).then(()=>{const e=new c(l.getContent(),{keyword:window.yoastKeyword,locale:"de_DE"});return r.analyze(e)}).then(e=>{const n=e,t=document.getElementById("resultsList");t.innerHTML="";let o=document.createElement("h2");o.innerHTML="Readability (Yoast)",o.style.paddingTop="5px",t.appendChild(o);for(const i of n.result.readability.results)i.text&&d(t,i);o=document.createElement("h2"),o.innerHTML="SEO (Yoast)",o.style.paddingTop="5px",t.appendChild(o);for(const i of n.result.seo[""].results)i.text&&i._identifier!=="titleWidth"&&i._identifier!=="metaDescriptionLength"&&d(t,i)}).catch(e=>{console.error("An error occured while analyzing the text:"),console.error(e)})}function d(l,e){const n=document.createElement("li");let t;e.score===9?t="green":e.score>=6?t="gold":e.score>=3?t="orange":t="red",n.innerHTML=" "+e.text,l.appendChild(n)} +import{A as c,_ as s}from"./app.js";if(typeof tinymce!="undefined"){const o=["ctrl_keyword","ctrl_keyword_translated"].find(t=>document.getElementById(t)!=null);if(o){const t=document.getElementById(o);window.yoastKeyword=t.value,t.addEventListener("keyup",function(){window.yoastKeyword=this.value})}tinymce.on("SetupEditor",function(t){const e=t.editor,d=new c(new Worker(new URL(""+new URL("webworker-767f3803.js",import.meta.url).href,self.location),{type:"module"}));e.on("init",function(){const n=document.createElement("ul");n.style.padding="10px 0",n.classList.add("widget"),e.getContainer().insertAdjacentElement("afterend",n),l(d,e,n),e.on("keyup",function(){l(d,e,n)})})})}function l(r,o,t){r.initialize({locale:"de_DE",contentAnalysisActive:!0,keywordAnalysisActive:!0,logLevel:"ERROR"}).then(()=>{const e=new s(o.getContent(),{keyword:window.yoastKeyword,locale:"de_DE"});return r.analyze(e)}).then(e=>{const d=e;t.innerHTML="";let n=document.createElement("h2");n.innerHTML="Readability (Yoast)",n.style.paddingTop="5px",t.appendChild(n);for(const i of d.result.readability.results)i.text&&a(t,i);n=document.createElement("h2"),n.innerHTML="SEO (Yoast)",n.style.paddingTop="5px",t.appendChild(n);for(const i of d.result.seo[""].results)i.text&&i._identifier!=="titleWidth"&&i._identifier!=="metaDescriptionLength"&&!(window.yoastKeyword==""&&i._identifier==="keyphraseLength")&&a(t,i)}).catch(e=>{console.error("An error occured while analyzing the text:"),console.error(e)})}function a(r,o){const t=document.createElement("li");let e;o.score===9?e="green":o.score>=6?e="gold":o.score>=3?e="orange":e="red",t.innerHTML=" "+o.text,r.appendChild(t)} diff --git a/src/ImiYoastSeoForContao.php b/src/ImiYoastSeoForContao.php index aba996a..4fbd17d 100644 --- a/src/ImiYoastSeoForContao.php +++ b/src/ImiYoastSeoForContao.php @@ -35,7 +35,6 @@ public function loadDataKeywordAttribute($varValue, \DataContainer $dc) } $GLOBALS['TL_MOOTOOLS'][] = ''; - $GLOBALS['TL_MOOTOOLS'][] = ''; return $varValue; } diff --git a/src/main.js b/src/main.js index 0077860..2278f82 100644 --- a/src/main.js +++ b/src/main.js @@ -1,36 +1,44 @@ import {AnalysisWorkerWrapper, createWorker, Paper} from "yoastseo"; -// `url` needs to be the full URL to the script for the browser to know where to load the worker script from. -// This should be the script created by the previous code-snippet. - -const worker = new AnalysisWorkerWrapper(new Worker( - new URL('./webworker', import.meta.url), - {type: 'module'} -)); - -console.debug('YoastSeo loaded'); - if (typeof tinymce !== "undefined") { + const keyword_fields = ["ctrl_keyword" , "ctrl_keyword_translated"]; + const field = keyword_fields.find((field) => document.getElementById(field) != null); + if (field) { + const keyword_field = document.getElementById(field); + window.yoastKeyword = keyword_field.value; + keyword_field.addEventListener("keyup", function () { + window.yoastKeyword = this.value; + }); + } + tinymce.on('SetupEditor', function (event) { const editor = event.editor; - const text_field_set = document.getElementById("pal_text_legend"); - text_field_set.innerHTML += "
"; + const worker = new AnalysisWorkerWrapper(new Worker( + new URL('./webworker', import.meta.url), + {type: 'module'} + )); + + editor.on('init', function() { + const results_list = document.createElement("ul"); + results_list.style.padding = "10px 0"; + results_list.classList.add("widget"); + editor.getContainer().insertAdjacentElement('afterend', results_list); - yoastSEO(editor); - editor.on("keyup", function (event2) { - yoastSEO(editor); + yoastSEO(worker, editor, results_list); + editor.on("keyup", function () { + yoastSEO(worker, editor, results_list); + }); }); }); } -function yoastSEO(editor) { +function yoastSEO(worker, editor, results_list) { worker.initialize({ locale: "de_DE", contentAnalysisActive: true, keywordAnalysisActive: true, logLevel: "ERROR", }).then(() => { - // The worker has been configured, we can now analyze a Paper. const paper = new Paper(editor.getContent(), { keyword: window.yoastKeyword, locale: "de_DE" @@ -39,17 +47,16 @@ function yoastSEO(editor) { return worker.analyze(paper); }).then((results) => { const data = results; - const olElement = document.getElementById('resultsList'); - olElement.innerHTML = ""; + results_list.innerHTML = ""; // Iterate over readability results let h2 = document.createElement('h2'); h2.innerHTML = "Readability (Yoast)"; h2.style.paddingTop = "5px"; - olElement.appendChild(h2); + results_list.appendChild(h2); for (const result of data.result.readability.results) { if (result.text) { // Only add if there's text to show - resultElement(olElement, result); + resultElement(results_list, result); } } @@ -57,10 +64,10 @@ function yoastSEO(editor) { h2 = document.createElement('h2'); h2.innerHTML = "SEO (Yoast)"; h2.style.paddingTop = "5px"; - olElement.appendChild(h2); + results_list.appendChild(h2); for (const result of data.result.seo[""].results) { - if (result.text && result._identifier !== "titleWidth" && result._identifier !== "metaDescriptionLength") { - resultElement(olElement, result); + if (result.text && result._identifier !== "titleWidth" && result._identifier !== "metaDescriptionLength" && !(window.yoastKeyword == "" && result._identifier === "keyphraseLength")) { + resultElement(results_list, result); } } @@ -70,7 +77,7 @@ function yoastSEO(editor) { }); } -function resultElement(olElement, result) { +function resultElement(results_list, result) { const li = document.createElement('li'); let color; @@ -85,5 +92,5 @@ function resultElement(olElement, result) { } li.innerHTML = " " + result.text; - olElement.appendChild(li); + results_list.appendChild(li); } \ No newline at end of file