-
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "За мен",
|
||||
"description": "Кратко описание за вашия сайт или за себе си."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"plugin-data": {
|
||||
"description": "Vis en lille beskrivelse af dit websted eller om dig selv.",
|
||||
"name": "About"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Über",
|
||||
"description": "Kurzer Text über die Website oder zum Betreiber des Blogs oder der Website."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Über",
|
||||
"description": "Kurzer Text über die Website oder zum Betreiber des Blogs oder der Website."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "About",
|
||||
"description": "Show a small description of your site or about yourself."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Acerca de",
|
||||
"description": "Breve descripción de ti mismo o sobre tu sitio."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "درباره",
|
||||
"description": "نمایش توضیح کوتاهی از شما و یا وبسایتتان."
|
||||
}
|
||||
}
|
||||
Executable
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "À Propos",
|
||||
"description": "Afficher une courte description sur votre site ou sur vous-même."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Informazioni",
|
||||
"description": "Visualizza una breve descrizione sul tuo sito o su te stesso."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "About",
|
||||
"description": "サイトやあなたについての簡単な説明を表示します。"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Over",
|
||||
"description": "Een korte beschrijving over de site of over uzelf."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "О блоге",
|
||||
"description": "Небольшое описание о вашем сайте или о себе."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Hakkında",
|
||||
"description": "Senin veya siten hakkında kısa bilgiler"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Про блог",
|
||||
"description": "Невеликий опис вашого сайту або про Вас."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"author": "Bludit",
|
||||
"email": "",
|
||||
"website": "https://plugins.bludit.com",
|
||||
"version": "3.22.0",
|
||||
"releaseDate": "2026-05-10",
|
||||
"license": "MIT",
|
||||
"compatible": "3.22",
|
||||
"notes": ""
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
class pluginAbout extends Plugin
|
||||
{
|
||||
|
||||
public function init()
|
||||
{
|
||||
$this->dbFields = array(
|
||||
'label' => 'About',
|
||||
'text' => ''
|
||||
);
|
||||
}
|
||||
|
||||
public function form()
|
||||
{
|
||||
global $L;
|
||||
|
||||
$html = '<div class="alert alert-primary" role="alert">';
|
||||
$html .= $this->description();
|
||||
$html .= '</div>';
|
||||
|
||||
$html .= '<div>';
|
||||
$html .= '<label>' . $L->get('Label') . '</label>';
|
||||
$html .= '<input name="label" type="text" dir="auto" value="' . $this->getValue('label') . '">';
|
||||
$html .= '<span class="tip">' . $L->get('This title is almost always used in the sidebar of the site') . '</span>';
|
||||
$html .= '</div>';
|
||||
|
||||
$html .= '<div>';
|
||||
$html .= '<label>' . $L->get('About') . '</label>';
|
||||
$html .= '<textarea name="text" id="jstext">' . $this->getValue('text') . '</textarea>';
|
||||
$html .= '</div>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
public function siteSidebar()
|
||||
{
|
||||
$html = '<div class="plugin plugin-about">';
|
||||
$html .= '<h2 class="plugin-label">' . $this->getValue('label') . '</h2>';
|
||||
$html .= '<div class="plugin-content">';
|
||||
$html .= html_entity_decode(nl2br($this->getValue('text')));
|
||||
$html .= '</div>';
|
||||
$html .= '</div>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Theme Popeye",
|
||||
"description": "Das Plugin erlaubt verschiedene Einstellungen für das Theme Popeye."
|
||||
},
|
||||
"enable-or-disable-dark-mode": "Dunkelmodus aktivieren oder deaktivieren.",
|
||||
"enable-or-disable-google-fonts": "Google Fonts aktivieren oder deaktivieren.",
|
||||
"relative": "Relativ",
|
||||
"absolute": "Absolut",
|
||||
"change-the-date-format-for-the-main-page": "Einstellung des Datumsformats auf der Haupt- oder Blogseite.",
|
||||
"show-tags": "Schlagwörter zeigen",
|
||||
"show-tags-in-the-main-page-for-each-article": "Zeigt auf der Haupt- oder Blogseite die Schlagwörter der Beiträge."
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Theme Popeye",
|
||||
"description": "Das Plugin erlaubt verschiedene Einstellungen für das Theme Popeye."
|
||||
},
|
||||
"enable-or-disable-dark-mode": "Dunkelmodus aktivieren oder deaktivieren.",
|
||||
"enable-or-disable-google-fonts": "Google Fonts aktivieren oder deaktivieren.",
|
||||
"relative": "Relativ",
|
||||
"absolute": "Absolut",
|
||||
"change-the-date-format-for-the-main-page": "Einstellung des Datumsformats auf der Haupt- oder Blogseite.",
|
||||
"show-tags": "Schlagwörter zeigen",
|
||||
"show-tags-in-the-main-page-for-each-article": "Zeigt auf der Haupt- oder Blogseite die Schlagwörter der Beiträge."
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Theme Popeye",
|
||||
"description": "Das Plugin erlaubt verschiedene Einstellungen für das Theme Popeye."
|
||||
},
|
||||
"enable-or-disable-dark-mode": "Dunkelmodus aktivieren oder deaktivieren.",
|
||||
"enable-or-disable-google-fonts": "Google Fonts aktivieren oder deaktivieren.",
|
||||
"relative": "Relativ",
|
||||
"absolute": "Absolut",
|
||||
"change-the-date-format-for-the-main-page": "Einstellung des Datumsformats auf der Haupt- oder Blogseite.",
|
||||
"show-tags": "Schlagwörter zeigen",
|
||||
"show-tags-in-the-main-page-for-each-article": "Zeigt auf der Haupt- oder Blogseite die Schlagwörter der Beiträge."
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"plugin-data": {
|
||||
"name": "Alternative Theme",
|
||||
"description": "This plugin provides configuration for the Alternative theme."
|
||||
},
|
||||
"enable-or-disable-dark-mode": "Enable or disable dark mode.",
|
||||
"enable-or-disable-google-fonts": "Enable or disable Google fonts.",
|
||||
"relative": "Relative",
|
||||
"absolute": "Absolute",
|
||||
"change-the-date-format-for-the-main-page": "Change the date format for the main page.",
|
||||
"show-tags": "Show tags",
|
||||
"show-tags-in-the-main-page-for-each-article": "Show tags on the main page for each article."
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Popeye Theme",
|
||||
"description": "Popeyeテーマの設定を行うプラグインです。"
|
||||
},
|
||||
"enable-or-disable-dark-mode": "ダークモードを有効または無効にします。",
|
||||
"enable-or-disable-google-fonts": "Google Fontsの利用を有効または無効にします。",
|
||||
"relative": "相対的",
|
||||
"absolute": "絶対的",
|
||||
"change-the-date-format-for-the-main-page": "メインページの日付表示形式を変更します。",
|
||||
"show-tags": "タグの表示",
|
||||
"show-tags-in-the-main-page-for-each-article": "メインページの各記事にタグを表示します。"
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Popeye Thema",
|
||||
"description": "Met deze plugin kan het thema Popeye geconfigureerd worden."
|
||||
},
|
||||
"enable-or-disable-dark-mode": "Donkere modus in-/uitschakelen.",
|
||||
"enable-or-disable-google-fonts": "Lettertypes van Google in-/uitschakelen.",
|
||||
"relative": "Relatief",
|
||||
"absolute": "Absoluut",
|
||||
"change-the-date-format-for-the-main-page": "Het datumformaat voor de hoofdpagina aanpassen.",
|
||||
"show-tags": "Tags tonen",
|
||||
"show-tags-in-the-main-page-for-each-article": "Op de hoofdpagina voor ieder artikel de tags tonen."
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"plugin-data": {
|
||||
"name": "Настройки темы Alternative",
|
||||
"description": "Этот плагин содержит настройки для темы Alternative."
|
||||
},
|
||||
"enable-or-disable-dark-mode": "Включить или выключить тёмный режим.",
|
||||
"enable-or-disable-google-fonts": "Включить или выключить шрифты от Google (Google fonts).",
|
||||
"relative": "Относительный",
|
||||
"absolute": "Абсолютный",
|
||||
"change-the-date-format-for-the-main-page": "Изменить формат даты для главной страницы.",
|
||||
"show-tags": "Отображать теги",
|
||||
"show-tags-in-the-main-page-for-each-article": "Показывать теги на главной странице для каждой записи."
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"author": "Bludit",
|
||||
"email": "",
|
||||
"website": "https://plugins.bludit.com",
|
||||
"version": "3.22.0",
|
||||
"releaseDate": "2026-05-10",
|
||||
"license": "MIT",
|
||||
"compatible": "3.22",
|
||||
"notes": "",
|
||||
"type": "theme"
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
class alternative extends Plugin
|
||||
{
|
||||
|
||||
public function init()
|
||||
{
|
||||
$this->dbFields = array(
|
||||
'googleFonts' => false,
|
||||
'showPostInformation' => false,
|
||||
'dateFormat' => 'relative'
|
||||
);
|
||||
}
|
||||
|
||||
public function form()
|
||||
{
|
||||
global $L;
|
||||
|
||||
$html = '';
|
||||
|
||||
$html .= '<div class="mb-3">';
|
||||
$html .= '<label class="form-label" for="googleFonts">' . $L->get('Google Fonts') . '</label>';
|
||||
$html .= '<select class="form-select" id="googleFonts" name="googleFonts">';
|
||||
$html .= '<option value="false" ' . ($this->getValue('googleFonts') === false ? 'selected' : '') . '>' . $L->get('Disabled') . '</option>';
|
||||
$html .= '<option value="true" ' . ($this->getValue('googleFonts') === true ? 'selected' : '') . '>' . $L->get('Enabled') . '</option>';
|
||||
$html .= '</select>';
|
||||
$html .= '<div class="form-text">' . $L->get('Enable or disable Google fonts.') . '</div>';
|
||||
$html .= '</div>';
|
||||
|
||||
$html .= '<div class="mb-3">';
|
||||
$html .= '<label class="form-label" for="showPostInformation">' . $L->get('Show Post Information') . '</label>';
|
||||
$html .= '<select class="form-select" id="showPostInformation" name="showPostInformation">';
|
||||
$html .= '<option value="false" ' . ($this->getValue('showPostInformation') === false ? 'selected' : '') . '>' . $L->get('Disabled') . '</option>';
|
||||
$html .= '<option value="true" ' . ($this->getValue('showPostInformation') === true ? 'selected' : '') . '>' . $L->get('Enabled') . '</option>';
|
||||
$html .= '</select>';
|
||||
$html .= '</div>';
|
||||
|
||||
$html .= '<div class="mb-3">';
|
||||
$html .= '<label class="form-label" for="dateFormat">' . $L->get('Date format') . '</label>';
|
||||
$html .= '<select class="form-select" id="dateFormat" name="dateFormat">';
|
||||
$html .= '<option value="noshow" ' . ($this->getValue('dateFormat') == 'noshow' ? 'selected' : '') . '>' . $L->get('No show') . '</option>';
|
||||
$html .= '<option value="relative" ' . ($this->getValue('dateFormat') == 'relative' ? 'selected' : '') . '>' . $L->get('Relative') . '</option>';
|
||||
$html .= '<option value="absolute" ' . ($this->getValue('dateFormat') == 'absolute' ? 'selected' : '') . '>' . $L->get('Absolute') . '</option>';
|
||||
$html .= '</select>';
|
||||
$html .= '<div class="form-text">' . $L->get('Change the date format for the main page.') . '</div>';
|
||||
$html .= '</div>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
public function showPostInformation()
|
||||
{
|
||||
return $this->getValue('showPostInformation');
|
||||
}
|
||||
|
||||
public function googleFonts()
|
||||
{
|
||||
return $this->getValue('googleFonts');
|
||||
}
|
||||
|
||||
public function dateFormat()
|
||||
{
|
||||
return $this->getValue('dateFormat');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"amount-of-pages": "Antal af sider",
|
||||
"api-token": "API-token",
|
||||
"plugin-data": {
|
||||
"description": "Grænseflade til interaktion med Bludit ved hjælp af HTTP-protokol. <br> Læs mere om denne udvidelse i <a href=\"https://docs.bludit.com/en/api/introduction\">API-introduktion</a>.",
|
||||
"name": "API"
|
||||
},
|
||||
"this-is-the-maximum-of-pages-to-return-when-you-call-to": "Dette er det maksimale antal sider, der skal returneres, når du lavet et kald til / api / sider",
|
||||
"this-token-is-for-read-only-and-is-regenerated-every-time-you-install-the-plugin": "Denne token er kun læsbar og regenereres hver gang du installerer udvidelsen."
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "API",
|
||||
"description": "Schnittstelle, für den Datenaustausch mit Bludit über das HTTP-Protokoll. Informationen zur Verwendung des Plugins unter <a href=\"https://docs.bludit.com/en/api/introduction\">API Introduction</a>."
|
||||
},
|
||||
"api-token": "API-Token",
|
||||
"amount-of-pages": "Anzahl Seiten",
|
||||
"this-is-the-maximum-of-pages-to-return-when-you-call-to": "Maximum der Seiten bei einem Aufruf /api/pages.",
|
||||
"this-token-is-for-read-only-and-is-regenerated-every-time-you-install-the-plugin": "Der Token kann für Leserechte verwendet werden. Er wird bei bei einer Neuinstallation des Plugins erneuert."
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "API",
|
||||
"description": "Schnittstelle, für den Datenaustausch mit Bludit über das HTTP-Protokoll. Informationen zur Verwendung des Plugins unter <a href=\"https://docs.bludit.com/en/api/introduction\">API Introduction</a>."
|
||||
},
|
||||
"api-token": "API-Token",
|
||||
"amount-of-pages": "Anzahl Seiten",
|
||||
"this-is-the-maximum-of-pages-to-return-when-you-call-to": "Maximum der Seiten bei einem Aufruf /api/pages.",
|
||||
"this-token-is-for-read-only-and-is-regenerated-every-time-you-install-the-plugin": "Der Token kann für Leserechte verwendet werden. Er wird bei bei einer Neuinstallation des Plugins erneuert."
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "API",
|
||||
"description": "Interface to interact with Bludit using HTTP protocol. <br> Read more about this plugin on <a href=\"https://docs.bludit.com/en/api/introduction\">API Introduction</a>."
|
||||
},
|
||||
"api-token": "API Token",
|
||||
"amount-of-pages": "Amount of pages",
|
||||
"this-is-the-maximum-of-pages-to-return-when-you-call-to": "This is the maximum of pages to return when you call to /api/pages",
|
||||
"this-token-is-for-read-only-and-is-regenerated-every-time-you-install-the-plugin": "This token is for read only and is regenerated every time you install the plugin"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "API",
|
||||
"description": "Interfaz para interactuar con Bludit mediante el protocolo HTTP. <br>Leer más sobre este plugin en <a href=\"https://docs.bludit.com/en/api/introduction\">API introducción</a>."
|
||||
},
|
||||
"api-token": "API Token",
|
||||
"amount-of-pages": "Cantidad de paginas",
|
||||
"this-is-the-maximum-of-pages-to-return-when-you-call-to": "Este es el máximo de páginas a devolver cuando llame a /api/pages.",
|
||||
"this-token-is-for-read-only-and-is-regenerated-every-time-you-install-the-plugin": "Este token es para sólo lectura y se regenera cada vez que se instala el plugin."
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "API",
|
||||
"description": "رابطی برای ارتباط با بلودیت با استفاده از پروتکل HTTP.<br>اطلاعات بیشتر را درمورد این پلاگین از <a href=\"https://docs.bludit.com/en/api/introduction\">API Introduction</a> مطالعه کنید."
|
||||
},
|
||||
"api-token": "رمز توکن API",
|
||||
"amount-of-pages": "تعداد صفحات",
|
||||
"this-is-the-maximum-of-pages-to-return-when-you-call-to": "این حداکثر صفحاتی بازگشتی است هنگامی که /api/pages را بازخوانی میکنید",
|
||||
"this-token-is-for-read-only-and-is-regenerated-every-time-you-install-the-plugin": "این توکن تنها خواندی است و هر زمانی که پلاگین را نصب می کنید بازسازی می شود"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "API",
|
||||
"description": "Interface pour interagir avec Bludit en utilisant le protocole HTTP. <br>En savoir plus sur ce plugin, en lisant <a href=\"https://docs.bludit.com/en/api/introduction\">l’introduction sur l’API</a>."
|
||||
},
|
||||
"api-token": "Jeton de l’API",
|
||||
"amount-of-pages": "Nombre de pages",
|
||||
"this-is-the-maximum-of-pages-to-return-when-you-call-to": "C’est le nombre maximal de pages à renvoyer lorsque vous appelez l’api par pages.",
|
||||
"this-token-is-for-read-only-and-is-regenerated-every-time-you-install-the-plugin": "Ce jeton est en lecture seule et est régénéré à chaque fois que vous installez le plugin."
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "API",
|
||||
"description": "Interfaccia per interagire con Bludit utilizzando il protocollo HTTP. <br> Leggi di più su questo plugin su <a href=\"https://docs.bludit.com/en/api/introduction\">API Introduction</a>."
|
||||
},
|
||||
"api-token": "Token API",
|
||||
"amount-of-pages": "Quantità di pagine",
|
||||
"this-is-the-maximum-of-pages-to-return-when-you-call-to": "Questo è il numero di pagine di ritorno quando effetui una chiamata /api/pages",
|
||||
"this-token-is-for-read-only-and-is-regenerated-every-time-you-install-the-plugin": "Questo token è di sola lettura e viene rigenerato ogni volta che installi il plugin"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "API",
|
||||
"description": "HTTPを使用してBluditとやり取りするインターフェース。<br> このプラグインについては <a href=\"https:\/\/docs.bludit.com\/en\/api\/introduction\">API Introduction<\/a> を参照してください。"
|
||||
},
|
||||
"api-token": "APIトークン",
|
||||
"amount-of-pages": "ページ数",
|
||||
"this-is-the-maximum-of-pages-to-return-when-you-call-to": "これは \/api\/pages 呼び出し時に返される最大ページ数です",
|
||||
"this-token-is-for-read-only-and-is-regenerated-every-time-you-install-the-plugin": "このトークンは読み取り専用トークンで、プラグインをインストールするたびに再生成されます"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "API",
|
||||
"description": "Interface om met Bludit te communiceren via het HTTP-protocol. <br>Lees meer over deze plugin op <a href=\"https://docs.bludit.com/en/api/introduction\">API Introduction</a>."
|
||||
},
|
||||
"api-token": "API-token",
|
||||
"amount-of-pages": "Aantal pagina's",
|
||||
"this-is-the-maximum-of-pages-to-return-when-you-call-to": "Het maximum aantal door te sturen pagina's via een call naar /api/pages",
|
||||
"this-token-is-for-read-only-and-is-regenerated-every-time-you-install-the-plugin": "Dit token is niet aan te passen en wordt automatisch ververst wanneer de plugin opnieuw wordt geïnstalleerd"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "API",
|
||||
"description": "Интерфейс для взаимодействия с Bludit по HTTP-протоколу.<br>Узнайте больше про этот плагин в разделе <a href=\"https://docs.bludit.com/en/api/introduction\">Введение в API для Bludit</a> (раздел на английском)."
|
||||
},
|
||||
"api-token": "API Tокен",
|
||||
"amount-of-pages": "Количество страниц",
|
||||
"this-is-the-maximum-of-pages-to-return-when-you-call-to": "Максимальное количество возвращаемых страниц при обращении к <code>/api/pages</code>",
|
||||
"this-token-is-for-read-only-and-is-regenerated-every-time-you-install-the-plugin": "Данный токен используется только для чтения, токен обновляется при каждой переустановке плагина."
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "API",
|
||||
"description": "HTTP protokolünü kullanarak Bludit ile etkileşimde bulunmak için arabirim. <br> Bu eklenti hakkında daha fazla bilgi için <a href=\"https://docs.bludit.com/en/api/introduction\">API Tanıtımı (ingilizce)</a>."
|
||||
},
|
||||
"api-token": "API Token",
|
||||
"amount-of-pages": "Sayfa miktarı",
|
||||
"this-is-the-maximum-of-pages-to-return-when-you-call-to": "Bu /api/pages sayfasını çağırdığınızda gösterilecek maksimum sayfa sayısıdır.",
|
||||
"this-token-is-for-read-only-and-is-regenerated-every-time-you-install-the-plugin": "Bu token salt okunur amaçlıdır ve eklentiyi her yüklediğinizde yeniden oluşturulur."
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"author": "Bludit",
|
||||
"email": "",
|
||||
"website": "https://plugins.bludit.com",
|
||||
"version": "3.22.0",
|
||||
"releaseDate": "2026-05-10",
|
||||
"license": "MIT",
|
||||
"compatible": "3.22",
|
||||
"notes": ""
|
||||
}
|
||||
@@ -0,0 +1,911 @@
|
||||
<?php
|
||||
|
||||
class pluginAPI extends Plugin
|
||||
{
|
||||
|
||||
private $method;
|
||||
|
||||
// HTTP status applied to the final response. Inner handlers may override it
|
||||
// by calling setStatus() before returning their result. The body still carries
|
||||
// the legacy status:'0'|'1' field for backwards compatibility.
|
||||
private $httpCode = 200;
|
||||
private $httpMessage = 'OK';
|
||||
|
||||
private function setStatus($code)
|
||||
{
|
||||
$messages = array(
|
||||
200 => 'OK',
|
||||
201 => 'Created',
|
||||
400 => 'Bad Request',
|
||||
401 => 'Unauthorized',
|
||||
403 => 'Forbidden',
|
||||
404 => 'Not Found',
|
||||
409 => 'Conflict',
|
||||
500 => 'Internal Server Error'
|
||||
);
|
||||
$this->httpCode = $code;
|
||||
$this->httpMessage = isset($messages[$code]) ? $messages[$code] : 'Error';
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
// Generate the API Token (32 bytes = 64 hex chars = 256 bits of entropy)
|
||||
$token = bin2hex( random_bytes(32) );
|
||||
|
||||
$this->dbFields = array(
|
||||
'token' => $token, // API Token
|
||||
'numberOfItems' => 15 // Amount of items to return
|
||||
);
|
||||
}
|
||||
|
||||
public function getToken()
|
||||
{
|
||||
return $this->getValue('token');
|
||||
}
|
||||
|
||||
public function form()
|
||||
{
|
||||
global $L;
|
||||
|
||||
$html = '<div class="alert alert-primary" role="alert">';
|
||||
$html .= $this->description();
|
||||
$html .= '</div>';
|
||||
|
||||
$html .= '<div>';
|
||||
$html .= '<label>' . $L->get('URL') . '</label>';
|
||||
$html .= '<p class="text-muted">' . DOMAIN_BASE . 'api/{endpoint}</p>';
|
||||
$html .= '</div>';
|
||||
|
||||
$html .= '<div>';
|
||||
$html .= '<label>' . $L->get('API Token') . '</label>';
|
||||
$html .= '<input name="token" type="text" dir="auto" value="' . $this->getValue('token') . '">';
|
||||
$html .= '<span class="tip">' . $L->get('This token is for read only and is regenerated every time you install the plugin') . '</span>';
|
||||
$html .= '</div>';
|
||||
|
||||
$html .= '<div>';
|
||||
$html .= '<label>' . $L->get('Amount of pages') . '</label>';
|
||||
$html .= '<input id="jsnumberOfItems" name="numberOfItems" type="text" dir="auto" value="' . $this->getValue('numberOfItems') . '">';
|
||||
$html .= '<span class="tip">' . $L->get('This is the maximum of pages to return when you call to') . '</span>';
|
||||
$html .= '</div>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
|
||||
// API HOOKS
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
public function beforeAll()
|
||||
{
|
||||
global $url;
|
||||
global $pages;
|
||||
global $users;
|
||||
|
||||
// CHECK URL
|
||||
// ------------------------------------------------------------
|
||||
$URI = $this->webhook('api', $returnsAfterURI = true, $fixed = false);
|
||||
if ($URI === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// METHOD
|
||||
// ------------------------------------------------------------
|
||||
$method = $this->getMethod();
|
||||
|
||||
// METHOD INPUTS
|
||||
// ------------------------------------------------------------
|
||||
$inputs = $this->getMethodInputs();
|
||||
if (empty($inputs)) {
|
||||
$this->response(400, 'Bad Request', array('message' => 'Missing method inputs.'));
|
||||
}
|
||||
|
||||
// ENDPOINT PARAMETERS
|
||||
// ------------------------------------------------------------
|
||||
$parameters = $this->getEndpointParameters($URI);
|
||||
if (empty($parameters)) {
|
||||
$this->response(400, 'Bad Request', array('message' => 'Missing endpoint parameters.'));
|
||||
}
|
||||
|
||||
// API TOKEN
|
||||
// ------------------------------------------------------------
|
||||
// Token from the plugin, the user can change it on the settings of the plugin
|
||||
$tokenAPI = $this->getValue('token');
|
||||
|
||||
// Check empty token
|
||||
if (empty($inputs['token'])) {
|
||||
$this->response(400, 'Bad Request', array('message' => 'Missing API token.'));
|
||||
}
|
||||
|
||||
// Check if the token is valid
|
||||
if ($inputs['token'] !== $tokenAPI) {
|
||||
$this->response(401, 'Unauthorized', array('message' => 'Invalid API token.'));
|
||||
}
|
||||
|
||||
// AUTHENTICATION TOKEN
|
||||
// ------------------------------------------------------------
|
||||
$writePermissions = false;
|
||||
if (!empty($inputs['authentication'])) {
|
||||
|
||||
// Get the user with the authentication token, FALSE if it doesn't exist
|
||||
$username = $users->getByAuthToken($inputs['authentication']);
|
||||
if ($username !== false) {
|
||||
try {
|
||||
$user = new User($username);
|
||||
if (($user->role() == 'admin') && ($user->enabled())) {
|
||||
// Loggin the user to create the session
|
||||
$login = new Login();
|
||||
$login->setLogin($username, 'admin');
|
||||
// Enable write permissions
|
||||
$writePermissions = true;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
// Continue without permissions
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clean inputs
|
||||
// ------------------------------------------------------------
|
||||
unset($inputs['token']);
|
||||
unset($inputs['authentication']);
|
||||
|
||||
// ENDPOINTS
|
||||
// ------------------------------------------------------------
|
||||
|
||||
// (GET) /api/pages
|
||||
if (($method === 'GET') && ($parameters[0] === 'pages') && empty($parameters[1])) {
|
||||
$data = $this->getPages($inputs);
|
||||
}
|
||||
// (GET) /api/pages/<key>
|
||||
elseif (($method === 'GET') && ($parameters[0] === 'pages') && !empty($parameters[1])) {
|
||||
$pageKey = $parameters[1];
|
||||
if (isset($parameters[2])) {
|
||||
$pageKey = $parameters[1] . '/' . $parameters[2];
|
||||
}
|
||||
$data = $this->getPage($pageKey);
|
||||
}
|
||||
// (PUT) /api/pages/<key>
|
||||
elseif (($method === 'PUT') && ($parameters[0] === 'pages') && !empty($parameters[1]) && $writePermissions) {
|
||||
$pageKey = $parameters[1];
|
||||
$data = $this->editPage($pageKey, $inputs);
|
||||
}
|
||||
// (DELETE) /api/pages/<key>
|
||||
elseif (($method === 'DELETE') && ($parameters[0] === 'pages') && !empty($parameters[1]) && $writePermissions) {
|
||||
$pageKey = $parameters[1];
|
||||
$data = $this->deletePage($pageKey);
|
||||
}
|
||||
// (POST) /api/pages
|
||||
elseif (($method === 'POST') && ($parameters[0] === 'pages') && empty($parameters[1]) && $writePermissions) {
|
||||
$data = $this->createPage($inputs);
|
||||
}
|
||||
// (GET) /api/settings
|
||||
elseif (($method === 'GET') && ($parameters[0] === 'settings') && empty($parameters[1]) && $writePermissions) {
|
||||
$data = $this->getSettings();
|
||||
}
|
||||
// (PUT) /api/settings
|
||||
elseif (($method === 'PUT') && ($parameters[0] === 'settings') && empty($parameters[1]) && $writePermissions) {
|
||||
$data = $this->editSettings($inputs);
|
||||
}
|
||||
// (POST) /api/images
|
||||
elseif (($method === 'POST') && ($parameters[0] === 'images') && $writePermissions) {
|
||||
$data = $this->uploadImage($inputs);
|
||||
}
|
||||
// (GET) /api/tags
|
||||
elseif (($method === 'GET') && ($parameters[0] === 'tags') && empty($parameters[1])) {
|
||||
$data = $this->getTags();
|
||||
}
|
||||
// (GET) /api/tags/<key>
|
||||
elseif (($method === 'GET') && ($parameters[0] === 'tags') && !empty($parameters[1])) {
|
||||
$tagKey = $parameters[1];
|
||||
$data = $this->getTag($tagKey);
|
||||
}
|
||||
// (GET) /api/categories
|
||||
elseif (($method === 'GET') && ($parameters[0] === 'categories') && empty($parameters[1])) {
|
||||
$data = $this->getCategories();
|
||||
}
|
||||
// (GET) /api/categories/<key>
|
||||
elseif (($method === 'GET') && ($parameters[0] === 'categories') && !empty($parameters[1])) {
|
||||
$categoryKey = $parameters[1];
|
||||
$data = $this->getCategory($categoryKey);
|
||||
}
|
||||
// (GET) /api/users
|
||||
elseif (($method === 'GET') && ($parameters[0] === 'users') && empty($parameters[1])) {
|
||||
$data = $this->getUsers();
|
||||
}
|
||||
// (GET) /api/users/<username>
|
||||
elseif (($method === 'GET') && ($parameters[0] === 'users') && !empty($parameters[1])) {
|
||||
$username = $parameters[1];
|
||||
$data = $this->getUser($username);
|
||||
}
|
||||
// (GET) /api/files/<page-key>
|
||||
elseif (($method === 'GET') && ($parameters[0] === 'files') && !empty($parameters[1])) {
|
||||
$pageKey = $parameters[1];
|
||||
if (!$this->isValidPageKey($pageKey)) {
|
||||
$this->response(400, 'Bad Request', array('message' => 'Invalid page key.'));
|
||||
}
|
||||
$data = $this->getFiles($pageKey);
|
||||
}
|
||||
// (POST) /api/files/<page-key>
|
||||
elseif (($method === 'POST') && ($parameters[0] === 'files') && !empty($parameters[1]) && $writePermissions) {
|
||||
$pageKey = $parameters[1];
|
||||
if (!$this->isValidPageKey($pageKey)) {
|
||||
$this->response(400, 'Bad Request', array('message' => 'Invalid page key.'));
|
||||
}
|
||||
$data = $this->uploadFile($pageKey);
|
||||
} else {
|
||||
$this->response(401, 'Unauthorized', array('message' => 'Access denied or invalid endpoint.'));
|
||||
}
|
||||
|
||||
$this->response($this->httpCode, $this->httpMessage, $data);
|
||||
}
|
||||
|
||||
// PRIVATE METHODS
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Validate page key to prevent path traversal (CWE-22)
|
||||
private function isValidPageKey($pageKey)
|
||||
{
|
||||
if (strpos($pageKey, '..') !== false) {
|
||||
return false;
|
||||
}
|
||||
if (strpos($pageKey, "\0") !== false) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private function getMethod()
|
||||
{
|
||||
// METHODS
|
||||
// ------------------------------------------------------------
|
||||
// GET
|
||||
// POST
|
||||
// PUT
|
||||
// DELETE
|
||||
|
||||
$this->method = $_SERVER['REQUEST_METHOD'];
|
||||
return $this->method;
|
||||
}
|
||||
|
||||
private function getMethodInputs()
|
||||
{
|
||||
switch ($this->method) {
|
||||
case "POST":
|
||||
$inputs = $_POST;
|
||||
break;
|
||||
case "GET":
|
||||
case "DELETE":
|
||||
$inputs = $_GET;
|
||||
break;
|
||||
case "PUT":
|
||||
$inputs = '';
|
||||
break;
|
||||
default:
|
||||
$inputs = json_encode(array());
|
||||
break;
|
||||
}
|
||||
|
||||
// Try to get raw/json data
|
||||
if (empty($inputs)) {
|
||||
$inputs = file_get_contents('php://input');
|
||||
}
|
||||
|
||||
return $this->cleanInputs($inputs);
|
||||
}
|
||||
|
||||
// Returns an array with key=>value with the inputs
|
||||
// If the content is JSON is parsed to array
|
||||
//
|
||||
// Note: DB-bound values are sanitized by core (Pages::add/edit, Site::set);
|
||||
// sanitizing again here would double-encode form/query values like
|
||||
// "Cats & Dogs" into "Cats &amp; Dogs".
|
||||
private function cleanInputs($inputs)
|
||||
{
|
||||
if (is_array($inputs)) {
|
||||
return $inputs;
|
||||
}
|
||||
if (is_string($inputs)) {
|
||||
$decoded = json_decode($inputs, true);
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
return array();
|
||||
}
|
||||
return is_array($decoded) ? $decoded : array();
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
private function getEndpointParameters($URI)
|
||||
{
|
||||
// ENDPOINT Parameters
|
||||
// ------------------------------------------------------------
|
||||
// /api/pages | GET | returns all pages
|
||||
// /api/pages/{key} | GET | returns the page with the {key}
|
||||
// /api/pages | POST | create a new page
|
||||
|
||||
$URI = ltrim($URI, '/');
|
||||
$parameters = explode('/', $URI);
|
||||
|
||||
// Sanitize parameters
|
||||
foreach ($parameters as $key => $value) {
|
||||
$parameters[$key] = Sanitize::html($value);
|
||||
}
|
||||
|
||||
return $parameters;
|
||||
}
|
||||
|
||||
private function response($code = 200, $message = 'OK', $data = array())
|
||||
{
|
||||
header('HTTP/1.1 ' . $code . ' ' . $message);
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
header('Content-Type: application/json');
|
||||
$json = json_encode($data);
|
||||
exit($json);
|
||||
}
|
||||
|
||||
private function getTags()
|
||||
{
|
||||
global $tags;
|
||||
$tmp = array(
|
||||
'status' => '0',
|
||||
'message' => 'List of tags.',
|
||||
'data' => array()
|
||||
);
|
||||
foreach ($tags->keys() as $key) {
|
||||
$tag = $tags->getMap($key);
|
||||
array_push($tmp['data'], $tag);
|
||||
}
|
||||
return $tmp;
|
||||
}
|
||||
|
||||
// Returns the tag information and the pages releated to the tag
|
||||
// The array with the pages has the complete information of each page
|
||||
private function getTag($key)
|
||||
{
|
||||
try {
|
||||
$tag = new Tag($key);
|
||||
} catch (Exception $e) {
|
||||
$this->setStatus(404);
|
||||
return array(
|
||||
'status' => '1',
|
||||
'message' => 'Tag not found by the key: ' . $key
|
||||
);
|
||||
}
|
||||
|
||||
$list = array();
|
||||
foreach ($tag->pages() as $pageKey) {
|
||||
try {
|
||||
$page = new Page($pageKey);
|
||||
array_push($list, $page->json($returnsArray = true));
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
}
|
||||
|
||||
$data = $tag->json($returnsArray = true);
|
||||
$data['pages'] = $list;
|
||||
|
||||
return array(
|
||||
'status' => '0',
|
||||
'message' => 'Information about the tag and pages related.',
|
||||
'data' => $data
|
||||
);
|
||||
}
|
||||
|
||||
private function getPages($args)
|
||||
{
|
||||
global $pages;
|
||||
|
||||
// Parameters and the default values
|
||||
$published = (isset($args['published']) ? $args['published'] == 'true' : true);
|
||||
$static = (isset($args['static']) ? $args['static'] == 'true' : false);
|
||||
$draft = (isset($args['draft']) ? $args['draft'] == 'true' : false);
|
||||
$sticky = (isset($args['sticky']) ? $args['sticky'] == 'true' : false);
|
||||
$scheduled = (isset($args['scheduled']) ? $args['scheduled'] == 'true' : false);
|
||||
$untagged = (isset($args['untagged']) ? $args['untagged'] == 'true' : false);
|
||||
|
||||
$numberOfItems = (isset($args['numberOfItems']) ? (int)$args['numberOfItems'] : (int)$this->getValue('numberOfItems'));
|
||||
$pageNumber = (isset($args['pageNumber']) ? (int)$args['pageNumber'] : 1);
|
||||
|
||||
// Clamp to safe values. -1 is the documented "return all" sentinel for
|
||||
// numberOfItems; anything else <=0 falls back to the plugin default and
|
||||
// then to a hard fallback so getList() can never receive 0.
|
||||
if ($pageNumber < 1) {
|
||||
$pageNumber = 1;
|
||||
}
|
||||
if ($numberOfItems === 0) {
|
||||
$numberOfItems = (int)$this->getValue('numberOfItems');
|
||||
}
|
||||
if ($numberOfItems === 0 || $numberOfItems < -1) {
|
||||
$numberOfItems = 15;
|
||||
}
|
||||
|
||||
$list = $pages->getList($pageNumber, $numberOfItems, $published, $static, $sticky, $draft, $scheduled);
|
||||
// getList() returns false when pageNumber is past the end; treat as empty.
|
||||
if ($list === false) {
|
||||
$list = array();
|
||||
}
|
||||
|
||||
// total reflects the count of pages matching the type filters; the
|
||||
// untagged filter is applied to the page slice below, so it is not
|
||||
// reflected in this total.
|
||||
$total = $pages->countByType($published, $static, $sticky, $draft, $scheduled);
|
||||
$hasMore = ($numberOfItems > 0) && (($pageNumber * $numberOfItems) < $total);
|
||||
|
||||
$tmp = array(
|
||||
'status' => '0',
|
||||
'message' => 'List of pages',
|
||||
'numberOfItems' => $numberOfItems,
|
||||
'meta' => array(
|
||||
'total' => $total,
|
||||
'pageNumber' => $pageNumber,
|
||||
'pageSize' => $numberOfItems,
|
||||
'hasMore' => $hasMore
|
||||
),
|
||||
'data' => array()
|
||||
);
|
||||
|
||||
foreach ($list as $pageKey) {
|
||||
try {
|
||||
// Create the page object from the page key
|
||||
$page = new Page($pageKey);
|
||||
if ($untagged) {
|
||||
if (empty($page->tags())) {
|
||||
// Push the page to the data array for the response
|
||||
array_push($tmp['data'], $page->json($returnsArray = true));
|
||||
}
|
||||
} else {
|
||||
array_push($tmp['data'], $page->json($returnsArray = true));
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
// Continue
|
||||
}
|
||||
}
|
||||
|
||||
return $tmp;
|
||||
}
|
||||
|
||||
private function getPage($key)
|
||||
{
|
||||
try {
|
||||
$page = new Page($key);
|
||||
return array(
|
||||
'status' => '0',
|
||||
'message' => 'Page filtered by key: ' . $key,
|
||||
'data' => $page->json($returnsArray = true)
|
||||
);
|
||||
} catch (Exception $e) {
|
||||
$this->setStatus(404);
|
||||
return array(
|
||||
'status' => '1',
|
||||
'message' => 'Page not found.'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function createPage($args)
|
||||
{
|
||||
// This function is defined on functions.php
|
||||
$key = createPage($args);
|
||||
if ($key === false) {
|
||||
$this->setStatus(400);
|
||||
return array(
|
||||
'status' => '1',
|
||||
'message' => 'Error trying to create the new page.'
|
||||
);
|
||||
}
|
||||
|
||||
$this->setStatus(201);
|
||||
try {
|
||||
$page = new Page($key);
|
||||
return array(
|
||||
'status' => '0',
|
||||
'message' => 'Page created.',
|
||||
'data' => $page->json($returnsArray = true)
|
||||
);
|
||||
} catch (Exception $e) {
|
||||
// The page was created but failed to load. Fall back to the legacy
|
||||
// minimal payload so the caller still gets the key.
|
||||
return array(
|
||||
'status' => '0',
|
||||
'message' => 'Page created.',
|
||||
'data' => array('key' => $key)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function editPage($key, $args)
|
||||
{
|
||||
global $pages;
|
||||
|
||||
if (!$pages->exists($key)) {
|
||||
$this->setStatus(404);
|
||||
return array(
|
||||
'status' => '1',
|
||||
'message' => 'Page not found.'
|
||||
);
|
||||
}
|
||||
|
||||
$args['key'] = $key;
|
||||
$newKey = editPage($args);
|
||||
|
||||
if ($newKey === false) {
|
||||
$this->setStatus(400);
|
||||
return array(
|
||||
'status' => '1',
|
||||
'message' => 'Error trying to edit the page.'
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
$page = new Page($newKey);
|
||||
return array(
|
||||
'status' => '0',
|
||||
'message' => 'Page edited.',
|
||||
'data' => $page->json($returnsArray = true)
|
||||
);
|
||||
} catch (Exception $e) {
|
||||
// The page was edited but failed to load. Fall back to the legacy
|
||||
// minimal payload so the caller still gets the key.
|
||||
return array(
|
||||
'status' => '0',
|
||||
'message' => 'Page edited.',
|
||||
'data' => array('key' => $newKey)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function deletePage($key)
|
||||
{
|
||||
global $pages;
|
||||
|
||||
if (!$pages->exists($key)) {
|
||||
$this->setStatus(404);
|
||||
return array(
|
||||
'status' => '1',
|
||||
'message' => 'Page not found.'
|
||||
);
|
||||
}
|
||||
|
||||
if (deletePage($key)) {
|
||||
return array(
|
||||
'status' => '0',
|
||||
'message' => 'Page deleted.'
|
||||
);
|
||||
}
|
||||
|
||||
$this->setStatus(500);
|
||||
return array(
|
||||
'status' => '1',
|
||||
'message' => 'Error trying to delete the page.'
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
| Upload an image and generate the thumbnails
|
||||
| Returns the image and thumbnail URL
|
||||
|
|
||||
| @inputs array
|
||||
| @inputs['uuid'] string Page UUID
|
||||
| @_FILE array https://www.php.net/manual/en/reserved.variables.files.php
|
||||
|
|
||||
| @return array
|
||||
*/
|
||||
private function uploadImage($inputs)
|
||||
{
|
||||
// Set upload directory
|
||||
if (isset($inputs['uuid']) && IMAGE_RESTRICT) {
|
||||
if (!$this->isValidPageKey($inputs['uuid'])) {
|
||||
$this->setStatus(400);
|
||||
return array('status' => '1', 'message' => 'Invalid UUID.');
|
||||
}
|
||||
$imageDirectory = PATH_UPLOADS_PAGES . $inputs['uuid'] . DS;
|
||||
$thumbnailDirectory = $imageDirectory . 'thumbnails' . DS;
|
||||
$imageEndpoint = DOMAIN_UPLOADS_PAGES . $inputs['uuid'] . '/';
|
||||
$thumbnailEndpoint = $imageEndpoint . 'thumbnails' . '/';
|
||||
if (!Filesystem::directoryExists($thumbnailDirectory)) {
|
||||
Filesystem::mkdir($thumbnailDirectory, true);
|
||||
}
|
||||
} else {
|
||||
$imageDirectory = PATH_UPLOADS;
|
||||
$thumbnailDirectory = PATH_UPLOADS_THUMBNAILS;
|
||||
$imageEndpoint = DOMAIN_UPLOADS;
|
||||
$thumbnailEndpoint = DOMAIN_UPLOADS_THUMBNAILS;
|
||||
}
|
||||
|
||||
if (!isset($_FILES['image'])) {
|
||||
$this->setStatus(400);
|
||||
return array(
|
||||
'status' => '1',
|
||||
'message' => 'No image sent.'
|
||||
);
|
||||
}
|
||||
|
||||
if ($_FILES['image']['error'] != 0) {
|
||||
$this->setStatus(400);
|
||||
return array(
|
||||
'status' => '1',
|
||||
'message' => 'Error uploading the image, maximum load file size allowed: ' . ini_get('upload_max_filesize')
|
||||
);
|
||||
}
|
||||
|
||||
// Move from PHP tmp file to Bludit tmp directory
|
||||
Filesystem::mv($_FILES['image']['tmp_name'], PATH_TMP . $_FILES['image']['name']);
|
||||
|
||||
// Transform image and create thumbnails
|
||||
$image = transformImage(PATH_TMP . $_FILES['image']['name'], $imageDirectory, $thumbnailDirectory);
|
||||
if ($image) {
|
||||
$filename = Filesystem::filename($image);
|
||||
return array(
|
||||
'status' => '0',
|
||||
'message' => 'Image uploaded.',
|
||||
'image' => $imageEndpoint . $filename,
|
||||
'thumbnail' => $thumbnailEndpoint . $filename
|
||||
);
|
||||
}
|
||||
|
||||
$this->setStatus(400);
|
||||
return array(
|
||||
'status' => '1',
|
||||
'message' => 'Image extension not allowed.'
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
| Get the settings
|
||||
|
|
||||
| @args array
|
||||
|
|
||||
| @return array
|
||||
*/
|
||||
private function getSettings()
|
||||
{
|
||||
global $site;
|
||||
return array(
|
||||
'status' => '0',
|
||||
'message' => 'Settings.',
|
||||
'data' => $site->get()
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
| Edit the settings
|
||||
| You can edit any field defined in the class site.class.php variable $dbFields
|
||||
|
|
||||
| @args array
|
||||
|
|
||||
| @return array
|
||||
*/
|
||||
private function editSettings($args)
|
||||
{
|
||||
if (editSettings($args)) {
|
||||
return array(
|
||||
'status' => '0',
|
||||
'message' => 'Settings edited.'
|
||||
);
|
||||
}
|
||||
$this->setStatus(400);
|
||||
return array(
|
||||
'status' => '1',
|
||||
'message' => 'Error trying to edit the settings.'
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
| Returns the categories in the system
|
||||
| Included the category name, key, description and the list of pages
|
||||
| The list of pages are the page's key
|
||||
|
|
||||
| @return array
|
||||
*/
|
||||
private function getCategories()
|
||||
{
|
||||
global $categories;
|
||||
$tmp = array(
|
||||
'status' => '0',
|
||||
'message' => 'List of categories.',
|
||||
'data' => array()
|
||||
);
|
||||
foreach ($categories->keys() as $key) {
|
||||
$category = $categories->getMap($key);
|
||||
array_push($tmp['data'], $category);
|
||||
}
|
||||
return $tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
| Returns information about the category and pages related
|
||||
| The pages are expanded which mean the title, content and more fields are returned in the query
|
||||
| This can degrade the performance
|
||||
|
|
||||
| @key string Category key
|
||||
|
|
||||
| @return array
|
||||
*/
|
||||
private function getCategory($key)
|
||||
{
|
||||
try {
|
||||
$category = new Category($key);
|
||||
} catch (Exception $e) {
|
||||
$this->setStatus(404);
|
||||
return array(
|
||||
'status' => '1',
|
||||
'message' => 'Category not found by the key: ' . $key
|
||||
);
|
||||
}
|
||||
|
||||
$list = array();
|
||||
foreach ($category->pages() as $pageKey) {
|
||||
try {
|
||||
$page = new Page($pageKey);
|
||||
array_push($list, $page->json($returnsArray = true));
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
}
|
||||
|
||||
$data = $category->json($returnsArray = true);
|
||||
$data['pages'] = $list;
|
||||
|
||||
return array(
|
||||
'status' => '0',
|
||||
'message' => 'Information about the category and pages related.',
|
||||
'data' => $data
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
| Returns the user profile
|
||||
|
|
||||
| @username string Username
|
||||
|
|
||||
| @return array
|
||||
*/
|
||||
private function getUser($username)
|
||||
{
|
||||
try {
|
||||
$user = new User($username);
|
||||
} catch (Exception $e) {
|
||||
$this->setStatus(404);
|
||||
return array(
|
||||
'status' => '1',
|
||||
'message' => 'User not found by username: ' . $username
|
||||
);
|
||||
}
|
||||
|
||||
$data = $user->json($returnsArray = true);
|
||||
return array(
|
||||
'status' => '0',
|
||||
'message' => 'User profile.',
|
||||
'data' => $data
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
| Returns all the users
|
||||
|
|
||||
| @return array
|
||||
*/
|
||||
private function getUsers()
|
||||
{
|
||||
global $users;
|
||||
$data = array();
|
||||
foreach ($users->db as $username => $profile) {
|
||||
try {
|
||||
$user = new User($username);
|
||||
$data[$username] = $user->json($returnsArray = true);
|
||||
} catch (Exception $e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return array(
|
||||
'status' => '0',
|
||||
'message' => 'Users profiles.',
|
||||
'data' => $data
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
| Returns all files uploaded for a specific page, includes any type of file.
|
||||
|
|
||||
| @return array
|
||||
*/
|
||||
private function getFiles($pageKey)
|
||||
{
|
||||
$chunk = false;
|
||||
$sortByDate = true;
|
||||
$path = PATH_UPLOADS_PAGES . $pageKey . DS;
|
||||
$listFiles = Filesystem::listFiles($path, '*', '*', $sortByDate, $chunk);
|
||||
|
||||
$files = array();
|
||||
foreach ($listFiles as $file) {
|
||||
$info = array('thumbnail' => '');
|
||||
$info['file'] = $file;
|
||||
$info['filename'] = basename($file);
|
||||
$info['mime'] = Filesystem::mimeType($file);
|
||||
$info['size'] = Filesystem::getSize($file);
|
||||
|
||||
// Check if thumbnail exists for the file
|
||||
$thumbnail = $path . 'thumbnails' . DS . $info['filename'];
|
||||
if (Filesystem::fileExists($thumbnail)) {
|
||||
$info['thumbnail'] = $thumbnail;
|
||||
}
|
||||
|
||||
array_push($files, $info);
|
||||
}
|
||||
|
||||
return array(
|
||||
'status' => '0',
|
||||
'message' => 'Files for the page key: ' . $pageKey,
|
||||
'data' => $files
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
| Upload a file to a particular page
|
||||
| Returns the file URL
|
||||
|
|
||||
| @inputs array
|
||||
| @inputs['uuid'] string Page UUID
|
||||
| @_FILE array https://www.php.net/manual/en/reserved.variables.files.php
|
||||
|
|
||||
| @return array
|
||||
*/
|
||||
private function uploadFile($pageKey)
|
||||
{
|
||||
if (!isset($_FILES['file'])) {
|
||||
$this->setStatus(400);
|
||||
return array(
|
||||
'status' => '1',
|
||||
'message' => 'File not sent.'
|
||||
);
|
||||
}
|
||||
|
||||
if ($_FILES['file']['error'] != 0) {
|
||||
$this->setStatus(400);
|
||||
return array(
|
||||
'status' => '1',
|
||||
'message' => 'Error uploading the file.'
|
||||
);
|
||||
}
|
||||
|
||||
$filename = $_FILES['file']['name'];
|
||||
|
||||
// Block dotfiles
|
||||
if (strpos($filename, '.') === 0) {
|
||||
$this->setStatus(400);
|
||||
return array('status' => '1', 'message' => 'File type not allowed.');
|
||||
}
|
||||
|
||||
// Check file extension
|
||||
$fileExtension = Filesystem::extension($filename);
|
||||
$fileExtension = Text::lowercase($fileExtension);
|
||||
if (!in_array($fileExtension, $GLOBALS['ALLOWED_FILE_EXTENSIONS'])) {
|
||||
$this->setStatus(400);
|
||||
return array('status' => '1', 'message' => 'File type not allowed.');
|
||||
}
|
||||
|
||||
// Sanitize filename to prevent issues with special characters
|
||||
$filenameWithoutExt = Filesystem::filename($filename);
|
||||
$filenameWithoutExt = Text::removeSpecialCharacters($filenameWithoutExt, '-');
|
||||
$filenameWithoutExt = Text::removeQuotes($filenameWithoutExt);
|
||||
$filenameWithoutExt = Text::removeSpaces($filenameWithoutExt, '-');
|
||||
$filename = $filenameWithoutExt . '.' . $fileExtension;
|
||||
|
||||
$absoluteURL = DOMAIN_UPLOADS_PAGES . $pageKey . '/' . $filename;
|
||||
$absolutePath = PATH_UPLOADS_PAGES . $pageKey . DS . $filename;
|
||||
if (Filesystem::mv($_FILES['file']['tmp_name'], $absolutePath)) {
|
||||
return array(
|
||||
'status' => '0',
|
||||
'message' => 'File uploaded.',
|
||||
'filename' => $filename,
|
||||
'absolutePath' => $absolutePath,
|
||||
'absoluteURL' => $absoluteURL
|
||||
);
|
||||
}
|
||||
|
||||
$this->setStatus(500);
|
||||
return array(
|
||||
'status' => '1',
|
||||
'message' => 'Error moving the file to the final path.'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"plugin-data": {
|
||||
"description": "Brug af canonical URLs kan hjælpe med at informere søgemaskiner om hvilke URLs der har identisk indhold.",
|
||||
"name": "Canonical"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Canonical",
|
||||
"description": "Kennzeichnung von Seiten mit kanonischen Links, um Dublicate Content bei der Erfassung durch Suchmaschinen zu verhindern."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Canonical",
|
||||
"description": "Kennzeichnung von Seiten mit kanonischen Links, um Dublicate Content bei der Erfassung durch Suchmaschinen zu verhindern."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Canonical",
|
||||
"description": "Using canonical URLs can help to inform search engines which URLs have identical content."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Canonical",
|
||||
"description": "El uso de URL canónicas ayuda a los motores de búsqueda qué URLs tienen contenido idéntico."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "لینک استاندارد",
|
||||
"description": "با استفاده از آدرسهای وب استاندارد میتوانید به اطلاع موتورهای جستجو برسانید که کدامیک از آدرس وب ها داری محتوای یکسانی هستند."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "URL Canonique",
|
||||
"description": "L'utilisation d'URL canoniques permet d'indiquer aux moteurs de recherche quelles URL ont un contenu identique."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Canonical",
|
||||
"description": "L'utilizzo degli URLS canonici può aiutare i motori di ricerca quali URL hanno un contenuto identico."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Canonical",
|
||||
"description": "カノニカル(正規化)URLを使用すると、検索エンジンに、どのURLのコンテンツが同一コンテンツであるかを通知できます。"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Canonieke URLs",
|
||||
"description": "Het gebruik van canonieke URLs kan helpen bij het informeren van zoekmachines over welke URLs dezelfde inhoud hebben."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Canonical",
|
||||
"description": "Плагин для использоания канонических URL-адресов. Использование канонических URL-адресов может помочь сообщить поисковым системам, какие URL-адреса имеют идентичный контент."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Канонические URL-адреса",
|
||||
"description": "Использование канонических URL-адресов может помочь поисковым системам грамотно идентифицировать URL-адреса страниц с дублирующимся содержанием."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"author": "Bludit",
|
||||
"email": "",
|
||||
"website": "https://plugins.bludit.com",
|
||||
"version": "3.22.0",
|
||||
"releaseDate": "2026-05-10",
|
||||
"license": "MIT",
|
||||
"compatible": "3.22",
|
||||
"notes": ""
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
class pluginCanonical extends Plugin {
|
||||
|
||||
public function siteHead()
|
||||
{
|
||||
global $url;
|
||||
global $page;
|
||||
global $WHERE_AM_I;
|
||||
|
||||
$html = '';
|
||||
$canonical = '';
|
||||
|
||||
switch ($WHERE_AM_I) {
|
||||
case 'home':
|
||||
// Handle pagination on homepage
|
||||
$pageNumber = $url->pageNumber();
|
||||
if ($pageNumber > 1) {
|
||||
$canonical = DOMAIN_BASE . 'page/' . $pageNumber . '/';
|
||||
} else {
|
||||
$canonical = DOMAIN_BASE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'page':
|
||||
$canonical = $page->permalink($absolute = true);
|
||||
break;
|
||||
|
||||
case 'category':
|
||||
// Category pages
|
||||
$categoryKey = $url->slug();
|
||||
$canonical = DOMAIN_CATEGORIES . $categoryKey . '/';
|
||||
$pageNumber = $url->pageNumber();
|
||||
if ($pageNumber > 1) {
|
||||
$canonical .= 'page/' . $pageNumber . '/';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'tag':
|
||||
// Tag pages
|
||||
$tagKey = $url->slug();
|
||||
$canonical = DOMAIN_TAGS . $tagKey . '/';
|
||||
$pageNumber = $url->pageNumber();
|
||||
if ($pageNumber > 1) {
|
||||
$canonical .= 'page/' . $pageNumber . '/';
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// For any other page type, use current URI
|
||||
$canonical = DOMAIN_BASE . ltrim($url->uri(), '/');
|
||||
break;
|
||||
}
|
||||
|
||||
if (!empty($canonical)) {
|
||||
$html .= '<link rel="canonical" href="' . htmlspecialchars($canonical, ENT_QUOTES, 'UTF-8') . '">' . PHP_EOL;
|
||||
|
||||
// Add prev/next for paginated content (helps search engines)
|
||||
$pageNumber = $url->pageNumber();
|
||||
if ($pageNumber > 1) {
|
||||
// Previous page
|
||||
if ($pageNumber === 2) {
|
||||
$prevUrl = preg_replace('/page\/\d+\/?$/', '', $canonical);
|
||||
} else {
|
||||
$prevUrl = preg_replace('/page\/\d+\/?$/', 'page/' . ($pageNumber - 1) . '/', $canonical);
|
||||
}
|
||||
$html .= '<link rel="prev" href="' . htmlspecialchars($prevUrl, ENT_QUOTES, 'UTF-8') . '">' . PHP_EOL;
|
||||
}
|
||||
|
||||
// Next page (only if more content exists)
|
||||
// This requires checking if there's a next page of content
|
||||
global $content;
|
||||
global $site;
|
||||
if (isset($content) && is_array($content) && count($content) >= $site->itemsPerPage()) {
|
||||
$nextUrl = preg_replace('/page\/\d+\/?$/', '', $canonical);
|
||||
if ($pageNumber < 1) {
|
||||
$nextUrl .= 'page/2/';
|
||||
} else {
|
||||
$nextUrl = preg_replace('/page\/\d+\/?$/', 'page/' . ($pageNumber + 1) . '/', $canonical);
|
||||
}
|
||||
$html .= '<link rel="next" href="' . htmlspecialchars($nextUrl, ENT_QUOTES, 'UTF-8') . '">' . PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"hide-categories-without-content": "Skjul kategorier uden indhold",
|
||||
"plugin-data": {
|
||||
"description": "Viser alle kategorier på sidepanelet.",
|
||||
"name": "Categories"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Kategorien",
|
||||
"description": "Zeigt alle Kategorien in der Seitenleiste (bei Themes mit einer Seitenleiste)."
|
||||
},
|
||||
"hide-categories-without-content": "Kategorien ohne Inhalte ausblenden"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Kategorien",
|
||||
"description": "Zeigt alle Kategorien in der Seitenleiste (bei Themes mit einer Seitenleiste)."
|
||||
},
|
||||
"hide-categories-without-content": "Kategorien ohne Inhalte ausblenden"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Categories",
|
||||
"description": "Shows all categories on the sidebar."
|
||||
},
|
||||
"hide-categories-without-content": "Hide Categories without content"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Categorías",
|
||||
"description": "Muestra todas las categorías en la barra lateral."
|
||||
},
|
||||
"hide-categories-without-content": "Ocultar categorías sin contenido"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "مجموعه ها",
|
||||
"description": "نمایش تمام مجموعه ها در نوارکناری."
|
||||
},
|
||||
"hide-categories-without-content": "پنهان کردن مجموعه های خالی از محتوا"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Catégories",
|
||||
"description": "Affiche toutes les catégories sur la barre latérale."
|
||||
},
|
||||
"hide-categories-without-content": "Masquer les catégories sans contenu."
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Categorie",
|
||||
"description": "Visualizza tutte le categorie nella barra laterale."
|
||||
},
|
||||
"hide-categories-without-content": "Nascondi categorie senza contenuto"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Categories",
|
||||
"description": "サイドバーにすべてのカテゴリを表示します。"
|
||||
},
|
||||
"hide-categories-without-content": "コンテンツのないカテゴリを非表示にする"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Categorieën",
|
||||
"description": "Toont alle categorieën in de zijbalk."
|
||||
},
|
||||
"hide-categories-without-content": "Categorieën zonder inhoud verbergen"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Категории",
|
||||
"description": "Показывает все категории на боковой панели."
|
||||
},
|
||||
"hide-categories-without-content": "Скрывать пустые категории"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Kategoriler",
|
||||
"description": "Tüm kategorileri kenar çubuğunda göster."
|
||||
},
|
||||
"hide-categories-without-content": "İçeriksiz kategorileri gizle"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Категорії",
|
||||
"description": "Показує всі категорії на бічній панелі."
|
||||
},
|
||||
"hide-categories-without-content": "Сховати категорії без вмісту"
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"author": "Bludit",
|
||||
"email": "",
|
||||
"website": "https://plugins.bludit.com",
|
||||
"version": "3.22.0",
|
||||
"releaseDate": "2026-05-10",
|
||||
"license": "MIT",
|
||||
"compatible": "3.22",
|
||||
"notes": ""
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
class pluginCategories extends Plugin
|
||||
{
|
||||
|
||||
public function init()
|
||||
{
|
||||
// Fields and default values for the database of this plugin
|
||||
$this->dbFields = array(
|
||||
'label' => 'Categories',
|
||||
'hideCero' => true
|
||||
);
|
||||
}
|
||||
|
||||
// Method called on the settings of the plugin on the admin area
|
||||
public function form()
|
||||
{
|
||||
global $L;
|
||||
|
||||
$html = '<div class="alert alert-primary" role="alert">';
|
||||
$html .= $this->description();
|
||||
$html .= '</div>';
|
||||
|
||||
$html .= '<div>';
|
||||
$html .= '<label>' . $L->get('Label') . '</label>';
|
||||
$html .= '<input name="label" type="text" dir="auto" value="' . $this->getValue('label') . '">';
|
||||
$html .= '<span class="tip">' . $L->get('This title is almost always used in the sidebar of the site') . '</span>';
|
||||
$html .= '</div>';
|
||||
|
||||
$html .= '<div>';
|
||||
$html .= '<label>' . $L->get('Hide Categories without content') . '</label>';
|
||||
$html .= '<select name="hideCero">';
|
||||
$html .= '<option value="true" ' . ($this->getValue('hideCero') === true ? 'selected' : '') . '>' . $L->get('Enabled') . '</option>';
|
||||
$html .= '<option value="false" ' . ($this->getValue('hideCero') === false ? 'selected' : '') . '>' . $L->get('Disabled') . '</option>';
|
||||
$html .= '</select>';
|
||||
$html .= '</div>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
// Method called on the sidebar of the website
|
||||
public function siteSidebar()
|
||||
{
|
||||
global $L;
|
||||
global $categories;
|
||||
|
||||
// HTML for sidebar
|
||||
$html = '<div class="plugin plugin-categories">';
|
||||
$html .= '<h2 class="plugin-label">' . $this->getValue('label') . '</h2>';
|
||||
$html .= '<div class="plugin-content">';
|
||||
$html .= '<ul>';
|
||||
|
||||
// By default, the database of categories is alphanumeric sorted
|
||||
foreach ($categories->db as $key => $fields) {
|
||||
$count = count($fields['list']);
|
||||
if (!$this->getValue('hideCero') || $count > 0) {
|
||||
$html .= '<li>';
|
||||
$html .= '<a href="' . DOMAIN_CATEGORIES . $key . '">';
|
||||
$html .= $fields['name'];
|
||||
$html .= ' (' . count($fields['list']) . ')';
|
||||
$html .= '</a>';
|
||||
$html .= '</li>';
|
||||
}
|
||||
}
|
||||
|
||||
$html .= '</ul>';
|
||||
$html .= '</div>';
|
||||
$html .= '</div>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"plugin-data": {
|
||||
"description": "Definer kode for de brugerdefinerede felter, og fortolk indholdet af siderne.",
|
||||
"name": "Custom fields parser"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Custom fields parser",
|
||||
"description": "Define code for the custom fields and parse the content of the pages."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "تحلیلگر کادر سفارشی",
|
||||
"description": "برای کادرهای سفارشی کد تعریف کرده و محتوای صفحات را تحلیل کنید."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Analyseur de champs personnalisés",
|
||||
"description": "Définissez le code des champs personnalisés et analysez le contenu des pages."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"plugin-data": {
|
||||
"name": "Парсер пользовательских полей",
|
||||
"description": "Ищет код пользовательских полей и отпределяет содержимое страниц в соответствии с найденным кодом."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"author": "Bludit",
|
||||
"email": "",
|
||||
"website": "https://plugins.bludit.com",
|
||||
"version": "3.22.0",
|
||||
"releaseDate": "2026-05-10",
|
||||
"license": "MIT",
|
||||
"compatible": "3.22",
|
||||
"notes": ""
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
class pluginCustomFieldsParser extends Plugin {
|
||||
|
||||
public function init()
|
||||
{
|
||||
$this->dbFields = array(
|
||||
'label'=>'Custom fields parser',
|
||||
'jsondb'=>json_encode(array())
|
||||
);
|
||||
}
|
||||
|
||||
public function form()
|
||||
{
|
||||
global $L;
|
||||
global $site;
|
||||
|
||||
$html = '<div class="alert alert-primary" role="alert">';
|
||||
$html .= $this->description();
|
||||
$html .= '</div>';
|
||||
|
||||
$jsondb = $this->getValue('jsondb', false);
|
||||
$database = json_decode($jsondb, true);
|
||||
|
||||
$customFields = $site->customFields();
|
||||
|
||||
foreach ($customFields as $field=>$options) {
|
||||
if ($options['type']=="string") {
|
||||
$html .= '<div>';
|
||||
$html .= '<label>'.$options['label'].'</label>';
|
||||
$html .= '<textarea name="'.$field.'">'.(isset($database[$field])?$database[$field]:'').'</textarea>';
|
||||
$html .= '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
public function post()
|
||||
{
|
||||
$this->db['jsondb'] = Sanitize::html(json_encode($_POST));
|
||||
return $this->save();
|
||||
}
|
||||
|
||||
public function parse($page)
|
||||
{
|
||||
$jsondb = $this->getValue('jsondb', false);
|
||||
$database = json_decode($jsondb, true);
|
||||
$parsedCode = array();
|
||||
|
||||
// Ensure $database is a valid array before iterating
|
||||
if (is_array($database)) {
|
||||
foreach ($database as $field=>$code) {
|
||||
$value = $page->custom($field);
|
||||
$parsedCode['{{ '.$field.' }}'] = str_replace('{{ value }}', $value, $code);
|
||||
}
|
||||
}
|
||||
|
||||
$content = $page->contentRaw();
|
||||
if (!empty($parsedCode)) {
|
||||
$content = str_replace(array_keys($parsedCode), array_values($parsedCode), $content);
|
||||
}
|
||||
|
||||
// Parse Markdown
|
||||
if (MARKDOWN_PARSER) {
|
||||
$parsedown = new Parsedown();
|
||||
$content = $parsedown->text($content);
|
||||
}
|
||||
|
||||
// Parse img src relative to absolute (with domain)
|
||||
if (IMAGE_RELATIVE_TO_ABSOLUTE) {
|
||||
$domain = IMAGE_RESTRICT ? DOMAIN_UPLOADS_PAGES . $page->uuid() . '/' : DOMAIN_UPLOADS;
|
||||
$content = Text::imgRel2Abs($content, $domain);
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
public function beforeSiteLoad()
|
||||
{
|
||||
if ($GLOBALS['WHERE_AM_I']=='page') {
|
||||
$GLOBALS['page']->setField('content', $this->parse($GLOBALS['page']));
|
||||
} else {
|
||||
foreach ($GLOBALS['content'] as $key=>$page) {
|
||||
$GLOBALS['content'][$key]->setField('content', $this->parse($GLOBALS['content'][$key]));
|
||||
}
|
||||
if (!empty($GLOBALS['content'])) {
|
||||
$GLOBALS['page'] = $GLOBALS['content'][0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"disqus-shortname": "Disqus kortnavn",
|
||||
"enable-disqus-on-pages": "Disqus på sider",
|
||||
"enable-disqus-on-static-pages": "Disqus på statiske sider",
|
||||
"enable-disqus-on-sticky-pages": "Disqus på fastgjorde sider",
|
||||
"get-the-shortname-from-the-disqus-general-settings": "Hent det korte navn fra Disqus generelle indstillinger",
|
||||
"plugin-data": {
|
||||
"description": "Disqus er en kommentar hostingstjeneste til websteder.<br>Det er nødvendigt at være registreret på <a href=\"https://disqus.com\">Disqus</a> for at bruge denne service.",
|
||||
"name": "Disqus"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Disqus",
|
||||
"description": "Disqus ist eine Kommentar-Plattform für Websites. Um das Plugin verwenden zu können, muss ein Konto bei <a href=\"https://disqus.com\">Disqus</a> eingerichtet werden."
|
||||
},
|
||||
"disqus-shortname": "Disqus-Kurzname (Shortname)",
|
||||
"enable-disqus-on-pages": "Disqus auf Seiten",
|
||||
"enable-disqus-on-static-pages": "Disqus auf statischen Seiten",
|
||||
"enable-disqus-on-sticky-pages": "Disqus bei fixierten Inhalten",
|
||||
"get-the-shortname-from-the-disqus-general-settings": "Der Kurzname wird bei Disqus unter \"Settings\" > \"General\" angezeigt."
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Disqus",
|
||||
"description": "Disqus ist eine Kommentar-Plattform für Websites. Um das Plugin verwenden zu können, muss ein Konto bei <a href=\"https://disqus.com\">Disqus</a> eingerichtet werden."
|
||||
},
|
||||
"disqus-shortname": "Disqus-Kurzname (Shortname)",
|
||||
"enable-disqus-on-pages": "Disqus auf Seiten",
|
||||
"enable-disqus-on-static-pages": "Disqus auf statischen Seiten",
|
||||
"enable-disqus-on-sticky-pages": "Disqus bei fixierten Inhalten",
|
||||
"get-the-shortname-from-the-disqus-general-settings": "Der Kurzname wird bei Disqus unter \"Settings\" > \"General\" angezeigt."
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Disqus",
|
||||
"description": "Disqus is a comment hosting service for web sites.<br>It's necessary to be registered on <a href=\"https://disqus.com\">Disqus</a> to use this service."
|
||||
},
|
||||
"disqus-shortname": "Disqus shortname",
|
||||
"enable-disqus-on-pages": "Disqus on pages",
|
||||
"enable-disqus-on-static-pages": "Disqus on static pages",
|
||||
"enable-disqus-on-sticky-pages": "Disqus on sticky pages",
|
||||
"get-the-shortname-from-the-disqus-general-settings": "Get the shortname from the Disqus general settings"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Disqus",
|
||||
"description": "Disqus es un servicio de comentarios online.<br>Es necesario registrarse en <a href=\"https://disqus.com\">Disqus</a> antes de utilizar este plugin."
|
||||
},
|
||||
"disqus-shortname": "Disqus shortname",
|
||||
"enable-disqus-on-pages": "Disqus en página",
|
||||
"enable-disqus-on-static-pages": "Disqus en página estaticas",
|
||||
"enable-disqus-on-sticky-pages": "Disqus en página sticky",
|
||||
"get-the-shortname-from-the-disqus-general-settings": "Puede obtener el shortname en la página de configuración de Disqus."
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "دیسکاس",
|
||||
"description": "دیسکاس یک سرویس اینترنتی ارسال دیدگاه برای وبسایت ها میباشد.<br>برای استفاده از این سرویس لازم است که در <a href=\"https://disqus.com\">Disqus</a> ثبت نام کنید."
|
||||
},
|
||||
"disqus-shortname": "نام کوتاه دیسکاس",
|
||||
"enable-disqus-on-pages": "دیسکاس در صفحات",
|
||||
"enable-disqus-on-static-pages": "دیسکاس در صفحات استاتیک",
|
||||
"enable-disqus-on-sticky-pages": "دیسکاس در صفحات چسبنده",
|
||||
"get-the-shortname-from-the-disqus-general-settings": "دریافت نام کوتاه از تنظیمات عمومی دیسکاس"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Disqus système de commentaire",
|
||||
"description": "Disqus est un service Web de discussion et de commentaires d'articles centralisé avec authentification unique. Il est nécessaire de s’inscrire sur Disqus.com avant d’utiliser ce plugin."
|
||||
},
|
||||
"disqus-shortname": "Votre ID Disqus",
|
||||
"enable-disqus-on-pages": "Disqus sur les pages",
|
||||
"enable-disqus-on-static-pages": "Disqus sur les pages statiques",
|
||||
"enable-disqus-on-sticky-pages": "Disqus sur les pages épinglées",
|
||||
"get-the-shortname-from-the-disqus-general-settings": "Obtenez votre ID à partir des paramètres généraux de Disqus."
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Disqus",
|
||||
"description": "Disqus è un servizio di hosting per i commenti sui siti web.<br>E' neccesario essere resitrati su <a href=\"https://disqus.com\">Disqus</a> per utilizzare questo servizio."
|
||||
},
|
||||
"disqus-shortname": "Nome Breve Disqus ",
|
||||
"enable-disqus-on-pages": "Disqus sulle pagine",
|
||||
"enable-disqus-on-static-pages": "Disqus sulle pagine statiche",
|
||||
"enable-disqus-on-sticky-pages": "Disqus sulle pagine sticky",
|
||||
"get-the-shortname-from-the-disqus-general-settings": "Acquisisci il nome utente da utilizzare dalle impostazioni generali di Disqus"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Disqus",
|
||||
"description": "DisqusはWebサイト向けのコメントホスティングサービスです。このサービスを利用するには、<a href=\"https:\/\/disqus.com\">Disqus<\/a>に登録する必要があります。"
|
||||
},
|
||||
"disqus-shortname": "Disqusショートネーム",
|
||||
"enable-disqus-on-pages": "ページにDisqusを使用",
|
||||
"enable-disqus-on-static-pages": "固定ページにDisqusを使用",
|
||||
"enable-disqus-on-sticky-pages": "先頭固定ページにDisqusを使用",
|
||||
"get-the-shortname-from-the-disqus-general-settings": "Disqus一般設定からショートネームを取得します"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Disqus",
|
||||
"description": "Disqus is hosting service om reacties in websites te implementeren.<br>Registratie op Disqus.com is nodig voordat deze plugin gebruikt kan gebruiken."
|
||||
},
|
||||
"disqus-shortname": "Disqus shortname",
|
||||
"enable-disqus-on-pages": "Disqus op pagina's tonen",
|
||||
"enable-disqus-on-static-pages": "Disqus on statische pagina's tonen",
|
||||
"enable-disqus-on-sticky-pages": "Disqus on vastgezette pagina's tonen",
|
||||
"get-the-shortname-from-the-disqus-general-settings": "De shortname is te verkrijgen via de algemene instellingen van Disqus"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "System komentarzy - Disqus",
|
||||
"description": "System komentarzy Disqus przechowuje komentarze dla serwisów internetowych. Korzystanie z tej wtyczki wymaga rejestracji w serwisie disqus.com."
|
||||
},
|
||||
"disqus-shortname": "Nazwa użytkownika Disqus",
|
||||
"enable-disqus-on-pages": "Disqus on pages",
|
||||
"enable-disqus-on-static-pages": "Disqus on static pages",
|
||||
"enable-disqus-on-sticky-pages": "Disqus on sticky pages",
|
||||
"get-the-shortname-from-the-disqus-general-settings": "Get the shortname from the Disqus general settings"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Комментарии Disqus",
|
||||
"description": "Disqus это сервис комментариев для сайтов и блогов. Необходимо зарегистрироваться на Disqus.com перед тем как использовать плагина."
|
||||
},
|
||||
"disqus-shortname": "Краткое имя Disqus",
|
||||
"enable-disqus-on-pages": "Disqus для страниц",
|
||||
"enable-disqus-on-static-pages": "Disqus для статических страниц",
|
||||
"enable-disqus-on-sticky-pages": "Disqus для прикреплённых страниц",
|
||||
"get-the-shortname-from-the-disqus-general-settings": "Получить краткое имя со страницы общих настроек Disqus"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Disqus Yorum Sistemi",
|
||||
"description": "Disqus siteler için yorum barındırması yapan bir firmadır. Eklentiyi kullanmadan önce Disqus.com adresine kayıt olmanız gerekmektedir."
|
||||
},
|
||||
"disqus-shortname": "Disqus shortname",
|
||||
"enable-disqus-on-pages": "Disqus on pages",
|
||||
"enable-disqus-on-static-pages": "Disqus on static pages",
|
||||
"enable-disqus-on-sticky-pages": "Disqus on sticky pages",
|
||||
"get-the-shortname-from-the-disqus-general-settings": "Get the shortname from the Disqus general settings"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "Система коментарів Disqus",
|
||||
"description": "Disqus надає послуги хостингу коментарів для веб-сайтів. Необхідно зареєструватися на Disqus.com перед використанням цього плагіна."
|
||||
},
|
||||
"disqus-shortname": "Коротке ім'я в Disqus",
|
||||
"enable-disqus-on-pages": "Disqus on pages",
|
||||
"enable-disqus-on-static-pages": "Disqus on static pages",
|
||||
"enable-disqus-on-sticky-pages": "Disqus on sticky pages",
|
||||
"get-the-shortname-from-the-disqus-general-settings": "Get the shortname from the Disqus general settings"
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"author": "Bludit",
|
||||
"email": "",
|
||||
"website": "https://plugins.bludit.com",
|
||||
"version": "3.22.0",
|
||||
"releaseDate": "2026-05-10",
|
||||
"license": "MIT",
|
||||
"compatible": "3.22",
|
||||
"notes": ""
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
class pluginDisqus extends Plugin
|
||||
{
|
||||
|
||||
public function init()
|
||||
{
|
||||
$this->dbFields = array(
|
||||
'shortname' => '',
|
||||
'enablePages' => true,
|
||||
'enableStatic' => true,
|
||||
'enableSticky' => true
|
||||
);
|
||||
}
|
||||
|
||||
public function form()
|
||||
{
|
||||
global $L;
|
||||
|
||||
$html = '<div class="alert alert-primary" role="alert">';
|
||||
$html .= $this->description();
|
||||
$html .= '</div>';
|
||||
|
||||
$html .= '<div>';
|
||||
$html .= '<label>' . $L->get('disqus-shortname') . '</label>';
|
||||
$html .= '<input name="shortname" id="jsshortname" type="text" dir="auto" value="' . $this->getValue('shortname') . '">';
|
||||
$html .= '<span class="tip">' . $L->get('Get the shortname from the Disqus general settings') . '</span>';
|
||||
$html .= '</div>';
|
||||
|
||||
$html .= '<div>';
|
||||
$html .= '<label>' . $L->get('enable-disqus-on-pages') . '</label>';
|
||||
$html .= '<select name="enablePages">';
|
||||
$html .= '<option value="true" ' . ($this->getValue('enablePages') === true ? 'selected' : '') . '>' . $L->get('enabled') . '</option>';
|
||||
$html .= '<option value="false" ' . ($this->getValue('enablePages') === false ? 'selected' : '') . '>' . $L->get('disabled') . '</option>';
|
||||
$html .= '</select>';
|
||||
$html .= '</div>';
|
||||
|
||||
$html .= '<div>';
|
||||
$html .= '<label>' . $L->get('enable-disqus-on-static-pages') . '</label>';
|
||||
$html .= '<select name="enableStatic">';
|
||||
$html .= '<option value="true" ' . ($this->getValue('enableStatic') === true ? 'selected' : '') . '>' . $L->get('enabled') . '</option>';
|
||||
$html .= '<option value="false" ' . ($this->getValue('enableStatic') === false ? 'selected' : '') . '>' . $L->get('disabled') . '</option>';
|
||||
$html .= '</select>';
|
||||
$html .= '</div>';
|
||||
|
||||
$html .= '<div>';
|
||||
$html .= '<label>' . $L->get('enable-disqus-on-sticky-pages') . '</label>';
|
||||
$html .= '<select name="enableSticky">';
|
||||
$html .= '<option value="true" ' . ($this->getValue('enableSticky') === true ? 'selected' : '') . '>' . $L->get('enabled') . '</option>';
|
||||
$html .= '<option value="false" ' . ($this->getValue('enableSticky') === false ? 'selected' : '') . '>' . $L->get('disabled') . '</option>';
|
||||
$html .= '</select>';
|
||||
$html .= '</div>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
public function pageEnd()
|
||||
{
|
||||
global $url;
|
||||
global $WHERE_AM_I;
|
||||
|
||||
// Do not show disqus on page not found
|
||||
if ($url->notFound()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($WHERE_AM_I === 'page') {
|
||||
global $page;
|
||||
if ($page->published() && $this->getValue('enablePages')) {
|
||||
return $this->javascript();
|
||||
}
|
||||
if ($page->isStatic() && $this->getValue('enableStatic')) {
|
||||
return $this->javascript();
|
||||
}
|
||||
if ($page->sticky() && $this->getValue('enableSticky')) {
|
||||
return $this->javascript();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function javascript()
|
||||
{
|
||||
global $page;
|
||||
$pageURL = $page->permalink();
|
||||
$pageID = $page->uuid();
|
||||
$shortname = $this->getValue('shortname');
|
||||
|
||||
$code = <<<EOF
|
||||
<!-- Disqus plugin -->
|
||||
<div id="disqus_thread"></div>
|
||||
<script>
|
||||
|
||||
var disqus_config = function () {
|
||||
this.page.url = '$pageURL';
|
||||
this.page.identifier = '$pageID';
|
||||
};
|
||||
|
||||
(function() { // DON'T EDIT BELOW THIS LINE
|
||||
var d = document, s = d.createElement('script');
|
||||
s.src = 'https://$shortname.disqus.com/embed.js';
|
||||
s.setAttribute('data-timestamp', +new Date());
|
||||
(d.head || d.body).appendChild(s);
|
||||
})();
|
||||
</script>
|
||||
<noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
|
||||
<!-- /Disqus plugin -->
|
||||
EOF;
|
||||
return $code;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
.editor-toolbar { background: #f1f1f1; border-radius: 0 !important; font-size: 1.5em;}
|
||||
.editor-toolbar::before { margin-bottom: 2px !important }
|
||||
.editor-toolbar::after { margin-top: 2px !important }
|
||||
.CodeMirror, .CodeMirror-scroll { flex:1; border-radius: 0 !important; }
|
||||
.editor-toolbar .fa { color: #555;}
|
||||
+903
@@ -0,0 +1,903 @@
|
||||
/**
|
||||
* easymde v2.18.0
|
||||
* Copyright Jeroen Akkerman
|
||||
* @link https://github.com/ionaru/easy-markdown-editor
|
||||
* @license MIT
|
||||
*/
|
||||
.CodeMirror {
|
||||
font-family: monospace;
|
||||
height: 300px;
|
||||
color: #000;
|
||||
direction: ltr
|
||||
}
|
||||
|
||||
.CodeMirror-lines {
|
||||
padding: 4px 0
|
||||
}
|
||||
|
||||
.CodeMirror pre.CodeMirror-line,
|
||||
.CodeMirror pre.CodeMirror-line-like {
|
||||
padding: 0 4px
|
||||
}
|
||||
|
||||
.CodeMirror-gutter-filler,
|
||||
.CodeMirror-scrollbar-filler {
|
||||
background-color: #fff
|
||||
}
|
||||
|
||||
.CodeMirror-gutters {
|
||||
border-right: 1px solid #ddd;
|
||||
background-color: #f7f7f7;
|
||||
white-space: nowrap
|
||||
}
|
||||
|
||||
.CodeMirror-linenumber {
|
||||
padding: 0 3px 0 5px;
|
||||
min-width: 20px;
|
||||
text-align: right;
|
||||
color: #999;
|
||||
white-space: nowrap
|
||||
}
|
||||
|
||||
.CodeMirror-guttermarker {
|
||||
color: #000
|
||||
}
|
||||
|
||||
.CodeMirror-guttermarker-subtle {
|
||||
color: #999
|
||||
}
|
||||
|
||||
.CodeMirror-cursor {
|
||||
border-left: 1px solid #000;
|
||||
border-right: none;
|
||||
width: 0
|
||||
}
|
||||
|
||||
.CodeMirror div.CodeMirror-secondarycursor {
|
||||
border-left: 1px solid silver
|
||||
}
|
||||
|
||||
.cm-fat-cursor .CodeMirror-cursor {
|
||||
width: auto;
|
||||
border: 0 !important;
|
||||
background: #7e7
|
||||
}
|
||||
|
||||
.cm-fat-cursor div.CodeMirror-cursors {
|
||||
z-index: 1
|
||||
}
|
||||
|
||||
.cm-fat-cursor .CodeMirror-line::selection,
|
||||
.cm-fat-cursor .CodeMirror-line>span::selection,
|
||||
.cm-fat-cursor .CodeMirror-line>span>span::selection {
|
||||
background: 0 0
|
||||
}
|
||||
|
||||
.cm-fat-cursor .CodeMirror-line::-moz-selection,
|
||||
.cm-fat-cursor .CodeMirror-line>span::-moz-selection,
|
||||
.cm-fat-cursor .CodeMirror-line>span>span::-moz-selection {
|
||||
background: 0 0
|
||||
}
|
||||
|
||||
.cm-fat-cursor {
|
||||
caret-color: transparent
|
||||
}
|
||||
|
||||
@-moz-keyframes blink {
|
||||
50% {
|
||||
background-color: transparent
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes blink {
|
||||
50% {
|
||||
background-color: transparent
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes blink {
|
||||
50% {
|
||||
background-color: transparent
|
||||
}
|
||||
}
|
||||
|
||||
.cm-tab {
|
||||
display: inline-block;
|
||||
text-decoration: inherit
|
||||
}
|
||||
|
||||
.CodeMirror-rulers {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: -50px;
|
||||
bottom: 0;
|
||||
overflow: hidden
|
||||
}
|
||||
|
||||
.CodeMirror-ruler {
|
||||
border-left: 1px solid #ccc;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
position: absolute
|
||||
}
|
||||
|
||||
.cm-s-default .cm-header {
|
||||
color: #00f
|
||||
}
|
||||
|
||||
.cm-s-default .cm-quote {
|
||||
color: #090
|
||||
}
|
||||
|
||||
.cm-negative {
|
||||
color: #d44
|
||||
}
|
||||
|
||||
.cm-positive {
|
||||
color: #292
|
||||
}
|
||||
|
||||
.cm-header,
|
||||
.cm-strong {
|
||||
font-weight: 700
|
||||
}
|
||||
|
||||
.cm-em {
|
||||
font-style: italic
|
||||
}
|
||||
|
||||
.cm-link {
|
||||
text-decoration: underline
|
||||
}
|
||||
|
||||
.cm-strikethrough {
|
||||
text-decoration: line-through
|
||||
}
|
||||
|
||||
.cm-s-default .cm-keyword {
|
||||
color: #708
|
||||
}
|
||||
|
||||
.cm-s-default .cm-atom {
|
||||
color: #219
|
||||
}
|
||||
|
||||
.cm-s-default .cm-number {
|
||||
color: #164
|
||||
}
|
||||
|
||||
.cm-s-default .cm-def {
|
||||
color: #00f
|
||||
}
|
||||
|
||||
.cm-s-default .cm-variable-2 {
|
||||
color: #05a
|
||||
}
|
||||
|
||||
.cm-s-default .cm-type,
|
||||
.cm-s-default .cm-variable-3 {
|
||||
color: #085
|
||||
}
|
||||
|
||||
.cm-s-default .cm-comment {
|
||||
color: #a50
|
||||
}
|
||||
|
||||
.cm-s-default .cm-string {
|
||||
color: #a11
|
||||
}
|
||||
|
||||
.cm-s-default .cm-string-2 {
|
||||
color: #f50
|
||||
}
|
||||
|
||||
.cm-s-default .cm-meta {
|
||||
color: #555
|
||||
}
|
||||
|
||||
.cm-s-default .cm-qualifier {
|
||||
color: #555
|
||||
}
|
||||
|
||||
.cm-s-default .cm-builtin {
|
||||
color: #30a
|
||||
}
|
||||
|
||||
.cm-s-default .cm-bracket {
|
||||
color: #997
|
||||
}
|
||||
|
||||
.cm-s-default .cm-tag {
|
||||
color: #170
|
||||
}
|
||||
|
||||
.cm-s-default .cm-attribute {
|
||||
color: #00c
|
||||
}
|
||||
|
||||
.cm-s-default .cm-hr {
|
||||
color: #999
|
||||
}
|
||||
|
||||
.cm-s-default .cm-link {
|
||||
color: #00c
|
||||
}
|
||||
|
||||
.cm-s-default .cm-error {
|
||||
color: red
|
||||
}
|
||||
|
||||
.cm-invalidchar {
|
||||
color: red
|
||||
}
|
||||
|
||||
.CodeMirror-composing {
|
||||
border-bottom: 2px solid
|
||||
}
|
||||
|
||||
div.CodeMirror span.CodeMirror-matchingbracket {
|
||||
color: #0b0
|
||||
}
|
||||
|
||||
div.CodeMirror span.CodeMirror-nonmatchingbracket {
|
||||
color: #a22
|
||||
}
|
||||
|
||||
.CodeMirror-matchingtag {
|
||||
background: rgba(255, 150, 0, .3)
|
||||
}
|
||||
|
||||
.CodeMirror-activeline-background {
|
||||
background: #e8f2ff
|
||||
}
|
||||
|
||||
.CodeMirror {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: #fff
|
||||
}
|
||||
|
||||
.CodeMirror-scroll {
|
||||
overflow: scroll !important;
|
||||
margin-bottom: -50px;
|
||||
margin-right: -50px;
|
||||
padding-bottom: 50px;
|
||||
height: 100%;
|
||||
outline: 0;
|
||||
position: relative;
|
||||
z-index: 0
|
||||
}
|
||||
|
||||
.CodeMirror-sizer {
|
||||
position: relative;
|
||||
border-right: 50px solid transparent
|
||||
}
|
||||
|
||||
.CodeMirror-gutter-filler,
|
||||
.CodeMirror-hscrollbar,
|
||||
.CodeMirror-scrollbar-filler,
|
||||
.CodeMirror-vscrollbar {
|
||||
position: absolute;
|
||||
z-index: 6;
|
||||
display: none;
|
||||
outline: 0
|
||||
}
|
||||
|
||||
.CodeMirror-vscrollbar {
|
||||
right: 0;
|
||||
top: 0;
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll
|
||||
}
|
||||
|
||||
.CodeMirror-hscrollbar {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
overflow-y: hidden;
|
||||
overflow-x: scroll
|
||||
}
|
||||
|
||||
.CodeMirror-scrollbar-filler {
|
||||
right: 0;
|
||||
bottom: 0
|
||||
}
|
||||
|
||||
.CodeMirror-gutter-filler {
|
||||
left: 0;
|
||||
bottom: 0
|
||||
}
|
||||
|
||||
.CodeMirror-gutters {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
min-height: 100%;
|
||||
z-index: 3
|
||||
}
|
||||
|
||||
.CodeMirror-gutter {
|
||||
white-space: normal;
|
||||
height: 100%;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
margin-bottom: -50px
|
||||
}
|
||||
|
||||
.CodeMirror-gutter-wrapper {
|
||||
position: absolute;
|
||||
z-index: 4;
|
||||
background: 0 0 !important;
|
||||
border: none !important
|
||||
}
|
||||
|
||||
.CodeMirror-gutter-background {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
z-index: 4
|
||||
}
|
||||
|
||||
.CodeMirror-gutter-elt {
|
||||
position: absolute;
|
||||
cursor: default;
|
||||
z-index: 4
|
||||
}
|
||||
|
||||
.CodeMirror-gutter-wrapper ::selection {
|
||||
background-color: transparent
|
||||
}
|
||||
|
||||
.CodeMirror-gutter-wrapper ::-moz-selection {
|
||||
background-color: transparent
|
||||
}
|
||||
|
||||
.CodeMirror-lines {
|
||||
cursor: text;
|
||||
min-height: 1px
|
||||
}
|
||||
|
||||
.CodeMirror pre.CodeMirror-line,
|
||||
.CodeMirror pre.CodeMirror-line-like {
|
||||
-moz-border-radius: 0;
|
||||
-webkit-border-radius: 0;
|
||||
border-radius: 0;
|
||||
border-width: 0;
|
||||
background: 0 0;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
margin: 0;
|
||||
white-space: pre;
|
||||
word-wrap: normal;
|
||||
line-height: inherit;
|
||||
color: inherit;
|
||||
z-index: 2;
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
-webkit-font-variant-ligatures: contextual;
|
||||
font-variant-ligatures: contextual
|
||||
}
|
||||
|
||||
.CodeMirror-wrap pre.CodeMirror-line,
|
||||
.CodeMirror-wrap pre.CodeMirror-line-like {
|
||||
word-wrap: break-word;
|
||||
white-space: pre-wrap;
|
||||
word-break: normal
|
||||
}
|
||||
|
||||
.CodeMirror-linebackground {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
z-index: 0
|
||||
}
|
||||
|
||||
.CodeMirror-linewidget {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
padding: .1px
|
||||
}
|
||||
|
||||
.CodeMirror-rtl pre {
|
||||
direction: rtl
|
||||
}
|
||||
|
||||
.CodeMirror-code {
|
||||
outline: 0
|
||||
}
|
||||
|
||||
.CodeMirror-gutter,
|
||||
.CodeMirror-gutters,
|
||||
.CodeMirror-linenumber,
|
||||
.CodeMirror-scroll,
|
||||
.CodeMirror-sizer {
|
||||
-moz-box-sizing: content-box;
|
||||
box-sizing: content-box
|
||||
}
|
||||
|
||||
.CodeMirror-measure {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
visibility: hidden
|
||||
}
|
||||
|
||||
.CodeMirror-cursor {
|
||||
position: absolute;
|
||||
pointer-events: none
|
||||
}
|
||||
|
||||
.CodeMirror-measure pre {
|
||||
position: static
|
||||
}
|
||||
|
||||
div.CodeMirror-cursors {
|
||||
visibility: hidden;
|
||||
position: relative;
|
||||
z-index: 3
|
||||
}
|
||||
|
||||
div.CodeMirror-dragcursors {
|
||||
visibility: visible
|
||||
}
|
||||
|
||||
.CodeMirror-focused div.CodeMirror-cursors {
|
||||
visibility: visible
|
||||
}
|
||||
|
||||
.CodeMirror-selected {
|
||||
background: #d9d9d9
|
||||
}
|
||||
|
||||
.CodeMirror-focused .CodeMirror-selected {
|
||||
background: #d7d4f0
|
||||
}
|
||||
|
||||
.CodeMirror-crosshair {
|
||||
cursor: crosshair
|
||||
}
|
||||
|
||||
.CodeMirror-line::selection,
|
||||
.CodeMirror-line>span::selection,
|
||||
.CodeMirror-line>span>span::selection {
|
||||
background: #d7d4f0
|
||||
}
|
||||
|
||||
.CodeMirror-line::-moz-selection,
|
||||
.CodeMirror-line>span::-moz-selection,
|
||||
.CodeMirror-line>span>span::-moz-selection {
|
||||
background: #d7d4f0
|
||||
}
|
||||
|
||||
.cm-searching {
|
||||
background-color: #ffa;
|
||||
background-color: rgba(255, 255, 0, .4)
|
||||
}
|
||||
|
||||
.cm-force-border {
|
||||
padding-right: .1px
|
||||
}
|
||||
|
||||
@media print {
|
||||
.CodeMirror div.CodeMirror-cursors {
|
||||
visibility: hidden
|
||||
}
|
||||
}
|
||||
|
||||
.cm-tab-wrap-hack:after {
|
||||
content: ''
|
||||
}
|
||||
|
||||
span.CodeMirror-selectedtext {
|
||||
background: 0 0
|
||||
}
|
||||
|
||||
.EasyMDEContainer {
|
||||
display: block
|
||||
}
|
||||
|
||||
.CodeMirror-rtl pre {
|
||||
direction: rtl
|
||||
}
|
||||
|
||||
.EasyMDEContainer.sided--no-fullscreen {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap
|
||||
}
|
||||
|
||||
.EasyMDEContainer .CodeMirror {
|
||||
box-sizing: border-box;
|
||||
height: auto;
|
||||
border: 1px solid #ced4da;
|
||||
border-bottom-left-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
padding: 10px;
|
||||
font: inherit;
|
||||
z-index: 0;
|
||||
word-wrap: break-word
|
||||
}
|
||||
|
||||
.EasyMDEContainer .CodeMirror-scroll {
|
||||
cursor: text
|
||||
}
|
||||
|
||||
.EasyMDEContainer .CodeMirror-fullscreen {
|
||||
background: #fff;
|
||||
position: fixed !important;
|
||||
top: 50px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
height: auto;
|
||||
z-index: 8;
|
||||
border-right: none !important;
|
||||
border-bottom-right-radius: 0 !important
|
||||
}
|
||||
|
||||
.EasyMDEContainer .CodeMirror-sided {
|
||||
width: 50% !important
|
||||
}
|
||||
|
||||
.EasyMDEContainer.sided--no-fullscreen .CodeMirror-sided {
|
||||
border-right: none !important;
|
||||
border-bottom-right-radius: 0;
|
||||
position: relative;
|
||||
flex: 1 1 auto
|
||||
}
|
||||
|
||||
.EasyMDEContainer .CodeMirror-placeholder {
|
||||
opacity: .5
|
||||
}
|
||||
|
||||
.EasyMDEContainer .CodeMirror-focused .CodeMirror-selected {
|
||||
background: #d9d9d9
|
||||
}
|
||||
|
||||
.editor-toolbar {
|
||||
position: relative;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
-o-user-select: none;
|
||||
user-select: none;
|
||||
padding: 9px 10px;
|
||||
border-top: 1px solid #ced4da;
|
||||
border-left: 1px solid #ced4da;
|
||||
border-right: 1px solid #ced4da;
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px
|
||||
}
|
||||
|
||||
.editor-toolbar.fullscreen {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
box-sizing: border-box;
|
||||
background: #fff;
|
||||
border: 0;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
opacity: 1;
|
||||
z-index: 9
|
||||
}
|
||||
|
||||
.editor-toolbar.fullscreen::before {
|
||||
width: 20px;
|
||||
height: 50px;
|
||||
background: -moz-linear-gradient(left, #fff 0, rgba(255, 255, 255, 0) 100%);
|
||||
background: -webkit-gradient(linear, left top, right top, color-stop(0, #fff), color-stop(100%, rgba(255, 255, 255, 0)));
|
||||
background: -webkit-linear-gradient(left, #fff 0, rgba(255, 255, 255, 0) 100%);
|
||||
background: -o-linear-gradient(left, #fff 0, rgba(255, 255, 255, 0) 100%);
|
||||
background: -ms-linear-gradient(left, #fff 0, rgba(255, 255, 255, 0) 100%);
|
||||
background: linear-gradient(to right, #fff 0, rgba(255, 255, 255, 0) 100%);
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
margin: 0;
|
||||
padding: 0
|
||||
}
|
||||
|
||||
.editor-toolbar.fullscreen::after {
|
||||
width: 20px;
|
||||
height: 50px;
|
||||
background: -moz-linear-gradient(left, rgba(255, 255, 255, 0) 0, #fff 100%);
|
||||
background: -webkit-gradient(linear, left top, right top, color-stop(0, rgba(255, 255, 255, 0)), color-stop(100%, #fff));
|
||||
background: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0, #fff 100%);
|
||||
background: -o-linear-gradient(left, rgba(255, 255, 255, 0) 0, #fff 100%);
|
||||
background: -ms-linear-gradient(left, rgba(255, 255, 255, 0) 0, #fff 100%);
|
||||
background: linear-gradient(to right, rgba(255, 255, 255, 0) 0, #fff 100%);
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
margin: 0;
|
||||
padding: 0
|
||||
}
|
||||
|
||||
.EasyMDEContainer.sided--no-fullscreen .editor-toolbar {
|
||||
width: 100%
|
||||
}
|
||||
|
||||
.editor-toolbar .easymde-dropdown,
|
||||
.editor-toolbar button {
|
||||
background: 0 0;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
text-decoration: none !important;
|
||||
height: 30px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 3px;
|
||||
cursor: pointer
|
||||
}
|
||||
|
||||
.editor-toolbar button {
|
||||
font-weight: 700;
|
||||
min-width: 30px;
|
||||
padding: 0 6px;
|
||||
white-space: nowrap
|
||||
}
|
||||
|
||||
.editor-toolbar button.active,
|
||||
.editor-toolbar button:hover {
|
||||
background: #fcfcfc;
|
||||
border-color: #95a5a6
|
||||
}
|
||||
|
||||
.editor-toolbar i.separator {
|
||||
display: inline-block;
|
||||
width: 0;
|
||||
border-left: 1px solid #d9d9d9;
|
||||
border-right: 1px solid #fff;
|
||||
color: transparent;
|
||||
text-indent: -10px;
|
||||
margin: 0 6px
|
||||
}
|
||||
|
||||
.editor-toolbar button:after {
|
||||
font-family: Arial, "Helvetica Neue", Helvetica, sans-serif;
|
||||
font-size: 65%;
|
||||
vertical-align: text-bottom;
|
||||
position: relative;
|
||||
top: 2px
|
||||
}
|
||||
|
||||
.editor-toolbar button.heading-1:after {
|
||||
content: "1"
|
||||
}
|
||||
|
||||
.editor-toolbar button.heading-2:after {
|
||||
content: "2"
|
||||
}
|
||||
|
||||
.editor-toolbar button.heading-3:after {
|
||||
content: "3"
|
||||
}
|
||||
|
||||
.editor-toolbar button.heading-bigger:after {
|
||||
content: "▲"
|
||||
}
|
||||
|
||||
.editor-toolbar button.heading-smaller:after {
|
||||
content: "▼"
|
||||
}
|
||||
|
||||
.editor-toolbar.disabled-for-preview button:not(.no-disable) {
|
||||
opacity: .6;
|
||||
pointer-events: none
|
||||
}
|
||||
|
||||
@media only screen and (max-width:700px) {
|
||||
.editor-toolbar i.no-mobile {
|
||||
display: none
|
||||
}
|
||||
}
|
||||
|
||||
.editor-statusbar {
|
||||
padding: 8px 10px;
|
||||
font-size: 12px;
|
||||
color: #959694;
|
||||
text-align: right
|
||||
}
|
||||
|
||||
.EasyMDEContainer.sided--no-fullscreen .editor-statusbar {
|
||||
width: 100%
|
||||
}
|
||||
|
||||
.editor-statusbar span {
|
||||
display: inline-block;
|
||||
min-width: 4em;
|
||||
margin-left: 1em
|
||||
}
|
||||
|
||||
.editor-statusbar .lines:before {
|
||||
content: 'lines: '
|
||||
}
|
||||
|
||||
.editor-statusbar .words:before {
|
||||
content: 'words: '
|
||||
}
|
||||
|
||||
.editor-statusbar .characters:before {
|
||||
content: 'characters: '
|
||||
}
|
||||
|
||||
.editor-preview-full {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 7;
|
||||
overflow: auto;
|
||||
display: none;
|
||||
box-sizing: border-box
|
||||
}
|
||||
|
||||
.editor-preview-side {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
width: 50%;
|
||||
top: 50px;
|
||||
right: 0;
|
||||
z-index: 9;
|
||||
overflow: auto;
|
||||
display: none;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #ddd;
|
||||
word-wrap: break-word
|
||||
}
|
||||
|
||||
.editor-preview-active-side {
|
||||
display: block
|
||||
}
|
||||
|
||||
.EasyMDEContainer.sided--no-fullscreen .editor-preview-active-side {
|
||||
flex: 1 1 auto;
|
||||
height: auto;
|
||||
position: static
|
||||
}
|
||||
|
||||
.editor-preview-active {
|
||||
display: block
|
||||
}
|
||||
|
||||
.editor-preview {
|
||||
padding: 10px;
|
||||
background: #fafafa
|
||||
}
|
||||
|
||||
.editor-preview>p {
|
||||
margin-top: 0
|
||||
}
|
||||
|
||||
.editor-preview pre {
|
||||
background: #eee;
|
||||
margin-bottom: 10px
|
||||
}
|
||||
|
||||
.editor-preview table td,
|
||||
.editor-preview table th {
|
||||
border: 1px solid #ddd;
|
||||
padding: 5px
|
||||
}
|
||||
|
||||
.cm-s-easymde .cm-tag {
|
||||
color: #63a35c
|
||||
}
|
||||
|
||||
.cm-s-easymde .cm-attribute {
|
||||
color: #795da3
|
||||
}
|
||||
|
||||
.cm-s-easymde .cm-string {
|
||||
color: #183691
|
||||
}
|
||||
|
||||
.cm-s-easymde .cm-header-1 {
|
||||
font-size: calc(1.375rem + 1.5vw)
|
||||
}
|
||||
|
||||
.cm-s-easymde .cm-header-2 {
|
||||
font-size: calc(1.325rem + .9vw)
|
||||
}
|
||||
|
||||
.cm-s-easymde .cm-header-3 {
|
||||
font-size: calc(1.3rem + .6vw)
|
||||
}
|
||||
|
||||
.cm-s-easymde .cm-header-4 {
|
||||
font-size: calc(1.275rem + .3vw)
|
||||
}
|
||||
|
||||
.cm-s-easymde .cm-header-5 {
|
||||
font-size: 1.25rem
|
||||
}
|
||||
|
||||
.cm-s-easymde .cm-header-6 {
|
||||
font-size: 1rem
|
||||
}
|
||||
|
||||
.cm-s-easymde .cm-header-1,
|
||||
.cm-s-easymde .cm-header-2,
|
||||
.cm-s-easymde .cm-header-3,
|
||||
.cm-s-easymde .cm-header-4,
|
||||
.cm-s-easymde .cm-header-5,
|
||||
.cm-s-easymde .cm-header-6 {
|
||||
margin-bottom: .5rem;
|
||||
line-height: 1.2
|
||||
}
|
||||
|
||||
.cm-s-easymde .cm-comment {
|
||||
background: rgba(0, 0, 0, .05);
|
||||
border-radius: 2px
|
||||
}
|
||||
|
||||
.cm-s-easymde .cm-link {
|
||||
color: #7f8c8d
|
||||
}
|
||||
|
||||
.cm-s-easymde .cm-url {
|
||||
color: #aab2b3
|
||||
}
|
||||
|
||||
.cm-s-easymde .cm-quote {
|
||||
color: #7f8c8d;
|
||||
font-style: italic
|
||||
}
|
||||
|
||||
.editor-toolbar .easymde-dropdown {
|
||||
position: relative;
|
||||
background: linear-gradient(to bottom right, #fff 0, #fff 84%, #333 50%, #333 100%);
|
||||
border-radius: 0;
|
||||
border: 1px solid #fff
|
||||
}
|
||||
|
||||
.editor-toolbar .easymde-dropdown:hover {
|
||||
background: linear-gradient(to bottom right, #fff 0, #fff 84%, #333 50%, #333 100%)
|
||||
}
|
||||
|
||||
.easymde-dropdown-content {
|
||||
display: block;
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
background-color: #f9f9f9;
|
||||
box-shadow: 0 8px 16px 0 rgba(0, 0, 0, .2);
|
||||
padding: 8px;
|
||||
z-index: 2;
|
||||
top: 30px
|
||||
}
|
||||
|
||||
.easymde-dropdown:active .easymde-dropdown-content,
|
||||
.easymde-dropdown:focus .easymde-dropdown-content,
|
||||
.easymde-dropdown:focus-within .easymde-dropdown-content {
|
||||
visibility: visible
|
||||
}
|
||||
|
||||
.easymde-dropdown-content button {
|
||||
display: block
|
||||
}
|
||||
|
||||
span[data-img-src]::after {
|
||||
content: '';
|
||||
background-image: var(--bg-image);
|
||||
display: block;
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
background-size: contain;
|
||||
height: 0;
|
||||
padding-top: var(--height);
|
||||
width: var(--width);
|
||||
background-repeat: no-repeat
|
||||
}
|
||||
|
||||
.CodeMirror .cm-spell-error:not(.cm-url):not(.cm-comment):not(.cm-tag):not(.cm-word) {
|
||||
background: rgba(255, 0, 0, .15)
|
||||
}
|
||||
Vendored
+7
File diff suppressed because one or more lines are too long
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"autosave": "Gem automatisk",
|
||||
"content-here-supports-markdown-and-html-code": "Indholdet her understøtter både Markdown og HTML kode",
|
||||
"plugin-data": {
|
||||
"description": "Markdown editor, med let brugergrænseflade, til oprettelse af indhold i markdown format.",
|
||||
"name": "EasyMDE"
|
||||
},
|
||||
"spell-checker": "Stavekontrol",
|
||||
"tab-size": "Fanestørrelse",
|
||||
"toolbar": "Værktøjslinje"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "EasyMDE",
|
||||
"description": "Einfacher Editor auf der Grundlage der Auszeichnungssprache Markdown."
|
||||
},
|
||||
"toolbar": "Werkzeugleiste",
|
||||
"tab-size": "Abstände der Tabstopps",
|
||||
"autosave": "Automatische Speicherung",
|
||||
"spell-checker": "Rechtschreibprüfung",
|
||||
"content-here-supports-markdown-and-html-code": "Hier kann der Inhalt eingefügt werden. Der Editor unterstützt Markdown und HTML-Code."
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "EasyMDE",
|
||||
"description": "Einfacher Editor auf der Grundlage der Auszeichnungssprache Markdown."
|
||||
},
|
||||
"toolbar": "Werkzeugleiste",
|
||||
"tab-size": "Abstände der Tabstopps",
|
||||
"autosave": "Automatische Speicherung",
|
||||
"spell-checker": "Rechtschreibprüfung",
|
||||
"content-here-supports-markdown-and-html-code": "Hier kann der Inhalt eingefügt werden. Der Editor unterstützt Markdown und HTML-Code."
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "EasyMDE",
|
||||
"description": "Markdown editor, cleaned interface to create markup language."
|
||||
},
|
||||
"toolbar": "Toolbar",
|
||||
"tab-size": "Tab size",
|
||||
"autosave": "Autosave",
|
||||
"spell-checker": "Spell Checker",
|
||||
"content-here-supports-markdown-and-html-code": "Content here supports Markdown and HTML code"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"plugin-data": {
|
||||
"name": "EasyMDE",
|
||||
"description": "Editor Markdown, interfaz limpia para crear lenguaje de marcado."
|
||||
},
|
||||
"toolbar": "Barra de herramientas",
|
||||
"tab-size": "Tamaño de la tabulación",
|
||||
"autosave": "Autoguardado",
|
||||
"content-here-supports-markdown-and-html-code": "Content here supports Markdown and HTML code",
|
||||
"spell-checker": "Corrector ortográfico"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"plugin-data":
|
||||
{
|
||||
"name": "EasyMDE",
|
||||
"description": "ویرایشگر Markdown، رابط ساده برای ایجاد زبان markup."
|
||||
},
|
||||
"toolbar": "نوار ابزار",
|
||||
"tab-size": "اندازه زبانه",
|
||||
"autosave": "ذخیره خودکار",
|
||||
"spell-checker": "غلط گیر",
|
||||
"content-here-supports-markdown-and-html-code": "محتوای اینجا از Markdown و کد HTML پشتیبانی می کند"
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user