Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[4.1][POC][RFC] Make tinyMCE a true WYSIWYG editor #35669

Closed
wants to merge 13 commits into from

Conversation

dgrammatiko
Copy link
Contributor

@dgrammatiko dgrammatiko commented Sep 25, 2021

Pull Request for Issue #35606 and partially a redo of #14456

Summary of Changes

Summary, testing instructions, etc will be updated later today or tomorrow (I need to finish the templates for the testing as the current templates are not supporting childs and the changes are available only for those)

This PR is a proposal for 4 changes:

  • Use the standard assets override mechanism of Joomla for the tinyMCE skins
  • Rework the tinyMCE templates to be in the assets folder of the templates using the new Mode (supporting child templates)
  • Introduce style_formats.json and formats.json to allow tinyMCE to use Bootstrap, Tailwind or whatever other CSS frameworks in the produced HTML
  • Templates that support the new mode (child templates) could provide an end point jeditor.php, a copy of their index.php that will return a css representative of the template's styles used

Use the standard assets override mechanism of Joomla for the tinyMCE skins

So, it seems that I'm trying to revert a very bad implementation of the skins that was introduced by... (drum roll) me back in 2015. Why is wrong? First because it expects the final user to decide on the looks of TinyMCE when that decision is not up to them but it's up to the TEMPLATE. The solution is almost a one line HTMLHelper::stylesheet() that will load the provided from tinyMCE skin or will be overrided if in the templates folder css/plg_editor_tinymce/skins/oxide/... exists. Simple, elegant, intuitive. Install a backend/frontend template, if it supports custom skin to match the tinyMCE with the rest of the template's design will be used, if not the default is there...

Rework the tinyMCE templates to be in the assets folder of the templates using the new Mode (supporting child templates)

When Brian reworked the templates part of tinyMCE he used the template's html folder for storing the files under a folder name tinymce. This is fine for the existing templates but will not play well with the templates implementing the new mode. The reason is simple the new mode calls for all static assets to be served from the folder /media/templates/... so that the actual templates folder will hold only PHP related files and thus could be locked and not being an entry point for the site (Joomla's entry points are: /index.php, '/installation/index.php', '/administrator/index.php', '/administrator/components/com_joomlaupdate/update.php', '/media', '/images' and the new one for api /api/index.php, meaning that anything else should be locked from direct access to a request). This introduces a minor change, legacy templates will have the tinyMCE templates in the /templates/templateName/html/tinymce while the ones supporting the new mode will have to get those files in /media/templates/site/templateName/html/tinymce. This would need to be documented when the docs for the child templates will be written.

Templates that support the new mode (child templates) could provide an end point jeditor.php, a copy of their index.php that will return a css representative of the template's styles used

This might be controversial but the editor.css that tinyMCE is using IMHO should be an exact copy of the front end template CSS. Since Joomla has a pretty nice way for doing this (?tmpl=something will load the something.php in the template, I build an actual PWA that composes the pages in the service worker just by abusing this https://github.com/dgrammatiko/sloth ) the proposal is to standardize an endpoint for the new mode templates. We don't break anything and we bring WYSIWYG in a opt in way.

sample implementation of jeditor.php
<?php
/**
 * @package     Joomla.Site
 * @subpackage  Templates.cassy
 *
 * @copyright   (C) 2021 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\CMS\Factory;
use Joomla\CMS\Uri\Uri;

/** @var Joomla\CMS\Document\HtmlDocument $this */

/**
 * This endpoint returns the CSS content for the template
 */
$wa   = $this->getWebAssetManager();
$mv   = $this->getMediaVersion();

$this->setMimeEncoding('text/css');
$this->setCharset('utf-8');

// Template assets path
$templatePath = 'media/templates/site/' . $this->template;

// Color Theme
$paramsColorName = $this->params->get('colorName', 'colors_standard');
$assetColorName  = 'theme.' . $paramsColorName;

// Use a font scheme if set in the template style options
$paramsFontScheme = $this->params->get('useFontScheme', false);
$fontStyles       = '';

$wa->registerAndUseStyle($assetColorName, $templatePath . '/css/global/' . $paramsColorName . '.css');

if ($paramsFontScheme) {
  if (stripos($paramsFontScheme, 'https://') === 0) {
    $this->getPreloadManager()->preconnect('https://fonts.googleapis.com/', []);
    $this->getPreloadManager()->preconnect('https://fonts.gstatic.com/', []);
    $wa->registerAndUseStyle('fontscheme.current', $paramsFontScheme, [], []);

    if (preg_match_all('/family=([^?:]*):/i', $paramsFontScheme, $matches) > 0) {
      $fontStyles = '--cassy-font-family-body: "' . str_replace('+', ' ', $matches[1][0]) . '", sans-serif;
  --cassy-font-family-headings: "' . str_replace('+', ' ', isset($matches[1][1]) ? $matches[1][1] : $matches[1][0]) . '", sans-serif;
  --cassy-font-weight-normal: 400;
  --cassy-font-weight-headings: 700;';
    }
  } else {
    $wa->registerAndUseStyle('fontscheme.current', $paramsFontScheme, ['version' => 'auto'], []);
  }
}

// Enable assets
$wa->useStyle('template.cassy.' . ($this->direction === 'rtl' ? 'rtl' : 'ltr'))
  ->useStyle('template.active.language')
  ->useStyle('template.user');

// Get the URLs
$templateCSSUri       = $wa->getAsset('style', 'template.cassy.' . ($this->direction === 'rtl' ? 'rtl' : 'ltr'))->getUri();
$activeLanguageCSSUri = $wa->getAsset('style', 'template.active.language')->getUri();
$userCSSUri           = $wa->getAsset('style', 'template.user')->getUri();
$fontsCSSUri          = $wa->assetExists('style', 'fontscheme.current') ? $wa->getAsset('style', 'fontscheme.current')->getUri() : '';

// Assign the URLs to CSS imports
$templateCSS       = ($templateCSSUri !== '') ? '@import url("' . Uri::root() . substr($templateCSSUri, 1) . '?' . $mv . '");' : '';
$activeLanguageCSS = ($activeLanguageCSSUri !== '') ? '@import url("' . Uri::root() . substr($activeLanguageCSSUri, 1) . '?' . $mv . '");' : '';
$userCSS           = ($userCSSUri !== '') ? '@import url("' . Uri::root() .  substr($userCSSUri, 1) . '?' . $mv . '");' : '';
$fontsCSS          = ($fontsCSSUri !== '') ? '@import url("' .  $fontsCSSUri . '");' : '';

echo <<<CSS
@charset "UTF-8";
/** Template CSS */
$templateCSS

/** Active Language CSS */
$activeLanguageCSS

/** User CSS */
$userCSS

/** Fonts CSS */
$fontsCSS

/** Inline */
:root {
  --hue: 214;
  --template-bg-light: #f0f4fb;
  --template-text-dark: #495057;
  --template-text-light: #ffffff;
  --template-link-color: #2a69b8;
  --template-special-color: #001B4C;
  $fontStyles
}

/* STYLES FOR JOOMLA! EDITOR */
hr#system-readmore {
  color: #f00;
  border: #f00 dashed 1px;
}
CSS;

Introduce style_formats.json and formats.json to allow tinyMCE to use Bootstrap, Tailwind or whatever other CSS frameworks in the produced HTML

Well, this is a redo of #14456. TinyMCE has a way to be customised with couple of json files. In short the menu elements and the toolbar buttons whenever clicked are runing a function and that function can be customised from the json files. Eg the menu Format->Align Left and the button Align Left by default wrapping the selected text to a span with an inline style text-lign: left. In the JSON file we can change this to match our frontend template and produce <span class="text-start">
These are very well documented:

style_formats.json
{
  "0": {
    "title": "Headers",
    "items": {
      "0": {
        "title": "Header 1",
        "format": "h1"
      },
      "1": {
        "title": "Header 2",
        "format": "h2"
      },
      "2": {
        "title": "Header 3",
        "format": "h3"
      },
      "3": {
        "title": "Header 4",
        "format": "h4"
      },
      "4": {
        "title": "Header 5",
        "format": "h5"
      },
      "5": {
        "title": "Header 6",
        "format": "h6"
      }
    }
  },
  "1": {
    "title": "Inline",
    "items": {
      "0": {
        "title": "Bold",
        "icon": "bold",
        "format": "bold"
      },
      "1": {
        "title": "Italic",
        "icon": "italic",
        "format": "italic"
      },
      "2": {
        "title": "Underline",
        "icon": "underline",
        "format": "underline"
      },
      "3": {
        "title": "Strikethrough",
        "icon": "strikethrough",
        "format": "strikethrough"
      },
      "4": {
        "title": "Superscript",
        "icon": "superscript",
        "format": "superscript"
      },
      "5": {
        "title": "Subscript",
        "icon": "subscript",
        "format": "subscript"
      },
      "6": {
        "title": "Code",
        "icon": "code",
        "format": "code"
      }
    }
  },
  "2": {
    "title": "Blocks",
    "items": {
      "0": {
        "title": "paragraph",
        "format": "p"
      },
      "1": {
        "title": "Blockquote",
        "format": "blockquote"
      },
      "2": {
        "title": "Div",
        "format": "div"
      },
      "3": {
        "title": "pre",
        "format": "pre"
      }
    }
  },
  "3": {
    "title": "Alignment",
    "items": {
      "0": {
        "title": "Left",
        "icon": "alignleft",
        "format": "alignleft"
      },
      "1": {
        "title": "Center",
        "icon": "aligncenter",
        "format": "aligncenter"
      },
      "2": {
        "title": "Right",
        "icon": "alignright",
        "format": "alignright"
      },
      "3": {
        "title": "Justify",
        "icon": "alignjustify",
        "format": "alignjustify"
      }
    }
  }
}
formats.json
{
  "alignleft": {
    "selector": "p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img",
    "classes": "text-start"
  },
  "aligncenter": {
    "selector": "p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img",
    "classes": "text-center"
  },
  "alignright": {
    "selector": "p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img",
    "classes": "text-end"
  },
  "alignjustify": {
    "selector": "p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img",
    "classes": "text-justify"
  },
  "bold": {
    "inline": "span",
    "classes": "fw-bold"
  },
  "italic": {
    "inline": "span",
    "classes": "fst-italic"
  },
  "underline": {
    "inline": "span",
    "classes": "text-decoration-underline",
    "exact": "true"
  },
  "strikethrough": {
    "inline": "del",
    "classes": "text-decoration-line-through"
  }
}

Testing Instructions

You will need to apply this PR and also install 2 templates: Cassy a Cassiopeia clone that supports child templates
cassy_1.0.0.zip and admin2021 a clone of Atum again ported to support childs

Actual result BEFORE applying this Pull Request

Expected result AFTER applying this Pull Request

Documentation Changes Required

@thednp @brianteeman

@ciar4n @kawshar could you please provide some feedback here? Is this something that you would support in your templates?

@brianteeman
Copy link
Contributor

I have no idea how you can possibly approve this PR so quickly. There are a LOT of changes that need to be tested. In particular the whole idea of the child templates which I am yet to see to be able to comment fully on. When this PR is finished I will test it.

@dgrammatiko
Copy link
Contributor Author

dgrammatiko commented Sep 25, 2021

When this PR is finished I will test it.

@brianteeman this is a POC so basically it's down to the maintainers to respond with an approval or rejection or something in between. The fact that I provided actual working code instead of pseudo here was just to help people with the decision (fewer things to imagine). I don't expect anyone to test this PR at this state...

Edit, added also an RFC tag, to help anyone that wants to contribute their ideas here

which I am yet to see to be able to comment fully on

there's a Cassiopeia clone here that is following all the requirements for the new mode (child templates):
https://github.com/joomla/joomla-cms/files/7229879/cassy.zip

@dgrammatiko dgrammatiko changed the title [4.1][POC] Make tinyMCE a true WYSIWYG editor [4.1][POC][RFC] Make tinyMCE a true WYSIWYG editor Sep 25, 2021
@joomla-cms-bot joomla-cms-bot added the RFC Request for Comment label Sep 25, 2021
@thednp
Copy link
Contributor

thednp commented Sep 25, 2021

@brianteeman I approve of that little change I commented about, not the entire commit. I probably shouldn't play with those buttons :)

I'm going to dig into the entire commit as soon as I get some strength. I would probably try and hook into the branch itself and do some contributions myself. I think so far the direction is going somewhere and this time we might actually have some results.

I'm interested in having a TinyMCE instance specific to each template/module in the sense that:

  • front-end template will override the instance of TinyMCE editor for content items, aka articles
  • site modules with <filed type="Editor"> set into their moduleName.XML file will override the instance of TinyMCE for its own specific config

Also I'm interested in overriding the entire stuff: TinyMCE javascript init, plugins, toolbars, templates, everything.

Sounds good?

@dgrammatiko
Copy link
Contributor Author

Also I'm interested in overriding the entire stuff: TinyMCE javascript init, plugins, toolbars, templates, everything.

This is already possible at the moment. create a plugin listening for onBeforeCompileHead and in there change anything tinyMCE related (stored at the plg_editor_tinymce->tinyMCE->default and for each id: plg_editor_tinymce->tinyMCE->articletext . You can always check what PHP send to the browser using Joomla.storageOptions

A more graphical representation:
Screenshot 2021-09-25 at 18 06 31

@thednp
Copy link
Contributor

thednp commented Sep 25, 2021

I know I can create an entire plugin basically a JCE 2.0, what I'm interested is to do that without a system plugin or anything, just using the right structure + code for templates and modules WITH the default Joomla TinyMCE editor plugin. This way end-users have less options to dig in order to enable the editor the developer designed. How cool is that: no need for page builders, hacks or bloatware.

@dgrammatiko
Copy link
Contributor Author

what I'm interested is to do that without a system plugin or anything, just using the right structure + code for templates and modules WITH the default Joomla TinyMCE editor plugin

Exactly what I'm proposing here. Let me explain with a simple use case what's happening (thanks to child templates and the existing architecture which I'm using here):

  • You as a template author create a template (front end) and you customize the styles_format.json, format.json, tinyMCE templates and the skin.
  • Me as the end user that got the template from you OOTB got a tinyMCE that fits the rest of the template and produces HTML that is optimal for the template (these were your responsibilities as a template author).
  • But I'm quite an advanced user and I wanted to modify some of your decisions, can I do it? The answer is yes and it's quite easy. All I have to do is create a child template (that will be a one click thing once the PR is done), assign it as default, and head to edit the files. Copy the template's original skin, the tinyMCE templates, the styles_format.json, and the format.json to the child, edit them to whatever fits my bill and Holla, Job done!!

@brianteeman
Copy link
Contributor

My site has two templates. What happens now with the editor? The template doesn't get associated with the content until after it is created.

@dgrammatiko
Copy link
Contributor Author

dgrammatiko commented Sep 25, 2021

My site has two templates. What happens now with the editor? The template doesn't get associated with the content until after it is created.

There are 2 possible outcomes here:

  • Your templates are completely compatible (in the child era, the second template would be just a child where you deviate some options/styles/overrides) and in such case there's no real problem here. Remember editing something in the front end uses the default template, IIRC.
  • Your templates using different CSS Frameworks and in such case just use the default tinyMCE config. By default, tinyMCE config is not changed, the changes are coupled to the template and only if the template is supporting the new Mode. And once again using a child to customise the config to whatever you want is still on the table...


'plugins' => implode(',', array_unique($plugins)),
'plugins' => implode(',', array_unique($this->plugins)),

// Quickbars
'quickbars_image_toolbar' => false,
Copy link
Contributor

@thednp thednp Sep 25, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really hope this gets changed to TRUE and to have align-left align-center align right | edit delete options, where edit is done via the media manager and not the TinyMCE useless pop-up. Something like this could do.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is just a flip of the boolean. I have no clue why it's false by default but probably you can PR the change (not in this PR obviously as a separate own PR)

@brianteeman
Copy link
Contributor

Your templates are completely compatible (in the child era, the second template would be just a child where you deviate some options/styles/overrides) and in such case there's no real problem here. Remember editing something in the front end uses the default template, IIRC.

Why wouldnt it be a completely different with a completely different design, structure and even framework. And no, editing in the front end doesn't necessarily use the default template and you dont address creating content in either site or admin.

Honestly I really dont like the way this sounds like its going

@dgrammatiko
Copy link
Contributor Author

Honestly I really dont like the way this sounds like its going

So, what I'm proposing covers 99% of the users. One site one template. This makes it extremely intuitive for all these users, they don't have to do anything (as long as they pick the right template that supports these features). Also, as I said child templates are here to help people deliver more designs using one template. The necessity for multiple templates should be eradicated by the child templates (for almost all cases).

About the 1% that needs something else they can:

  • not use the child templates at all, the same situation as the current state
  • use the child templates with their own plugin that manages the way that tinyMCE should behave. Joomla can't predict what could happen if someone wants to use 100 templates and quite frankly if you need so diverse templates (apart from the fact that probably there is something fundamentally wrong with the implementation of the site) as I already said DO NOT USE this feature, it's opt in.

@brianteeman
Copy link
Contributor

(as long as they pick the right template that supports these features).

thats the part that concerns me

@dgrammatiko
Copy link
Contributor Author

thats the part that concerns me

There are some missing switches atm that will override the behaviour (use the defaults), maybe that part makes you think that these are dictated, the user still has control over all aspects (on/off, custom overrides).

That said we can educate users, eg have a very good explanation of what coupling your content to the template's CSS means, and also, ask template providers to help us form this feature so it's not another FOOBAR thing that nobody will ever use. As I said this is a POC so I'm expecting input in order to form this to something that would be beneficial for everyone. Then again maybe you're right and Joomla can only deal with inline styles in tinymce (although I was using these tricks for quite some time on client sites) but that would be a very sad realization that the CMS can't do proper 2021 html...

@brianteeman
Copy link
Contributor

This introduces a minor change, legacy templates will have the tinyMCE templates in the /templates/templateName/html/tinymce while the ones supporting the new mode will have to get those files in /media/templates/site/templateName/html/tinymce.

The tinymce templates/snippets were deliberately placed in the /templates folder so that they can be created and edited in the template manager. Unless I am missing something moving them to the /media folder prevents that.

@brianteeman
Copy link
Contributor

This might be controversial but the editor.css that tinyMCE is using IMHO should be an exact copy of the front end template CSS.

It can be today although I personally just include the typography related css

@brianteeman
Copy link
Contributor

Am I missing something. I have applied the PR, npm i, nstalled cassy, made that default. But when I try to create any content in the site or admin I get the following erors


Refused to apply style from '<URL>' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
create-a-post:1 Refused to apply style from 'http://localhost/joomla-cms/joomla-cms/media/plg_editors_tinymce/css/skins/ui/oxide/skin.min.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
create-a-post:1 Refused to apply style from 'http://localhost/joomla-cms/joomla-cms/media/plg_editors_tinymce/css/skins/ui/oxide/content.min.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
create-a-post:1 Refused to apply style from 'http://localhost/joomla-cms/joomla-cms/media/templates/site/cassy/css/template.css?3bf64677bb9dd49735cdf5204357a7bf' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
create-a-post:1 Refused to apply style from 'http://localhost/joomla-cms/joomla-cms/media/plg_editors_tinymce/css/skins/ui/oxide/skin.min.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
create-a-post:1 Refused to apply style from 'http://localhost/joomla-cms/joomla-cms/media/plg_editors_tinymce/css/skins/ui/oxide/content.min.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
create-a-post:1 Refused to apply style from 'http://localhost/joomla-cms/joomla-cms/media/templates/site/cassy/css/template.css?3bf64677bb9dd49735cdf5204357a7bf' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.

@dgrammatiko
Copy link
Contributor Author

Unless I am missing something moving them to the /media folder prevents that.

At the moment Child templates aren't supported in the UI of Joomla but once #32896 is done (which is the prerequisite for enabling child templates) this will be possible. One of the fundamental changes for the child templates is that they should be safer (eg no public access to /templates) and consistent with the rest of Joomla's extensions (eg ALL static assets served from /media).

It can be today although I personally just include the typography related CSS

Placing some STATIC CSS in a file will never be able to accurately represent the styles of a template due to the simple fact that almost all templates allow some kind of colour selection that is stored in the db. By definition this customization cannot be somehow done with static CSS without the need of constantly changing values in multiple places (the template form UI, and the editor.css). This approach just eliminates that, and can still read the editor.css and include that in the response (not sure if I already coded that part right now)

Am I missing something. I have applied the PR, npm i, nstalled cassy, made that default. But when I try to create any content in the site or admin I get the following errors

I probably messed up something. I will check this later on today

@brianteeman
Copy link
Contributor

Unless I am missing something moving them to the /media folder prevents that.

At the moment Child templates aren't supported in the UI of Joomla but once #32896 is done (which is the prerequisite for enabling child templates) this will be possible. One of the fundamental changes for the child templates is that they should be safer (eg no public access to /templates) and consistent with the rest of Joomla's extensions (eg ALL static assets served from /media).

That suggests that they would only work then for a template that has implemented child templates?

I would argue that these content templates/snippets are NOT static assets at all.

Without being able to test it at all then I can't really make any more constructive comment

@dgrammatiko
Copy link
Contributor Author

That suggests that they would only work then for a template that has implemented child templates?

No, existing templates will continue to expect the tinymce in their /html folder. The change affects only the new templates that will support childs. It's not my intention to break anything here, but the change is needed for security and consistency (assets that can be fetched from the browser need to be in a public facing dir)

I would argue that these content templates/snippets are NOT static assets at all.

They are, the definition is coming from the way you are using them. They are fetched DIRECTLY from the browser thus for Joomla should be considered static assets. In the Joomla relm static is anything that is not served through PHP.

Without being able to test it at all then I can't really make any more constructive comment

Will try to fix it in a bit

@brianteeman
Copy link
Contributor

I will check it in my lunch break

thats why I replied asap ;)

@dgrammatiko
Copy link
Contributor Author

@brianteeman I've updated the front end template cassy_1.0.0.zip

@brianteeman
Copy link
Contributor

No errors now and I can test it.

@brianteeman
Copy link
Contributor

probably beyond the scope but cassy is missing var(--cassy-color-primary)

@dgrammatiko
Copy link
Contributor Author

probably beyond the scope but cassy is missing var(--cassy-color-primary)

Here's abetter version:

Updated `jeditor.php`
<?php
/**
 * @package     Joomla.Site
 * @subpackage  Templates.cassy
 *
 * @copyright   (C) 2021 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/** @var Joomla\CMS\Document\HtmlDocument $this */

/**
 * This endpoint returns the CSS content for the template
 */
$this->setMimeEncoding('text/css');
$this->setCharset('utf-8');

$wa         = $this->getWebAssetManager();
$mv         = $this->getMediaVersion();
$fontStyles = '';
$editorCSS  = '';

// Use a font scheme if set in the template style options
$paramsFontScheme = $this->params->get('useFontScheme', false);

if ($paramsFontScheme) {
  if (stripos($paramsFontScheme, 'https://') === 0) {
    $this->getPreloadManager()->preconnect('https://fonts.googleapis.com/', []);
    $this->getPreloadManager()->preconnect('https://fonts.gstatic.com/', []);
    $wa->registerAndUseStyle('fontscheme.current', $paramsFontScheme, [], []);

    if (preg_match_all('/family=([^?:]*):/i', $paramsFontScheme, $matches) > 0) {
      $fontStyles = '--cassy-font-family-body: "' . str_replace('+', ' ', $matches[1][0]) . '", sans-serif;
  --cassy-font-family-headings: "' . str_replace('+', ' ', isset($matches[1][1]) ? $matches[1][1] : $matches[1][0]) . '", sans-serif;
  --cassy-font-weight-normal: 400;
  --cassy-font-weight-headings: 700;';
    }
  } else {
    $wa->registerAndUseStyle('fontscheme.current', $paramsFontScheme, ['version' => 'auto'], []);
  }
}

// Color Theme
$paramsColorName = $this->params->get('colorName', 'colors_standard');
$wa->registerAndUseStyle('theme.' . $paramsColorName, 'media/templates/site/cassy/css/global/' . $paramsColorName . '.css');

// Enable assets
$wa->useStyle('template.cassy.' . ($this->direction === 'rtl' ? 'rtl' : 'ltr'))
  ->useStyle('template.active.language')
  ->useStyle('template.user');

// Get the URLs
$templateCSSUri       = $wa->getAsset('style', 'template.cassy.' . ($this->direction === 'rtl' ? 'rtl' : 'ltr'))->getUri();
$templateColorsUri    = $wa->getAsset('style', 'theme.' . $paramsColorName)->getUri();
$activeLanguageCSSUri = $wa->getAsset('style', 'template.active.language')->getUri();
$userCSSUri           = $wa->getAsset('style', 'template.user')->getUri();
$fontsCSSUri          = $wa->assetExists('style', 'fontscheme.current') ? $wa->getAsset('style', 'fontscheme.current')->getUri() : '';

// Assign the URLs to CSS imports
$templateCSS       = ($templateCSSUri !== '') ? '@import url("' . $templateCSSUri . '?' . $mv . '");' : '';
$templateColorsCSS = ($templateColorsUri !== '') ? '@import url("' . $templateColorsUri . '?' . $mv . '");' : '';
$activeLanguageCSS = ($activeLanguageCSSUri !== '') ? '@import url("' . $activeLanguageCSSUri . '?' . $mv . '");' : '';
$userCSS           = ($userCSSUri !== '') ? '@import url("' . $userCSSUri . '?' . $mv . '");' : '';
$fontsCSS          = ($fontsCSSUri !== '') ? '@import url("' .  (strpos($fontsCSSUri, '/') === 0 ? $fontsCSSUri . '?' . $mv : $fontsCSSUri) .'");' : '';

// The user editor.css from /media/templates/site/cassy/css/editor.css
if (is_file(JPATH_ROOT . '/media/templates/site/cassy/css/editor.css')) {
  $editorCSS = @file_get_contents(JPATH_ROOT . '/media/templates/site/cassy/css/editor.css');
}

echo <<<CSS
@charset "UTF-8";
/** Template CSS */
$templateCSS

/** Template Colours */
$templateColorsCSS

/** Active Language CSS */
$activeLanguageCSS

/** User CSS */
$userCSS

/** Fonts CSS */
$fontsCSS

/** Inline */
:root {
  --hue: 214;
  --template-bg-light: #f0f4fb;
  --template-text-dark: #495057;
  --template-text-light: #ffffff;
  --template-link-color: #2a69b8;
  --template-special-color: #001B4C;
  $fontStyles
}

/* Editor styles from css/editor.css */
$editorCSS
CSS;

@brianteeman
Copy link
Contributor

I can see how it works now ;)

Question 1
There will be a lot of thing to add to the json files for each template. Is it possible to have a fallback json? ie if you miss the aligncenter from your json then instead of falling back to the inline style. This will make the job of the template designer much easier as they will only need to change the json where there own template is different.

@dgrammatiko
Copy link
Contributor Author

dgrammatiko commented Sep 27, 2021

There will be a lot of thing to add to the json files for each template. Is it possible to have a fallback json?

The quick answer is YES, but probably it's the wrong one as well. The defaults already exist in the tinyMCE's internal configuration and yes we can combine merge JSON files with ease. The question that needs to be addressed is what consists of the base JSON that the templates will extend? A reminder that some classes might be CSS Framework specific. A few years back when @ciaran and I were proposing a Joomla CSS Framework and that was because we believed (I still do) that some classes should be owned by the CMS and anyone that implements a Bootstrap, Tailwind, whatever template has to extend their code to cover these classes. Right now there's no common denominator so it's kinda hard to come up with a base JSON that covers everybody. But maybe I'm wrong here...

EDIT: The project could invest into a static site that could generate those JSON files in a gui fashion

@brianteeman
Copy link
Contributor

So my other concern is that the jeditor.php file is very complex (at least for me to understand)

@dgrammatiko
Copy link
Contributor Author

So my other concern is that the jeditor.php file is very complex (at least for me to understand)

That's more a Cassiopeia related issue, in short the jeditor.php is something like:

defined('_JEXEC') or die;

/** @var Joomla\CMS\Document\HtmlDocument $this */

/**  Set the right mime/encoding */
$this->setMimeEncoding('text/css');
$this->setCharset('utf-8');

/** Concatenate and inline all the CSS parts that served in the normal template */
$css = '....';

/* retrun the inlined CSS */
echo $css;

So all the complexity is from the Web Assets, Custom colours, Custom Fonts, etc that are specific to Cassiopeia and the way these were implemented. Another template might have 1/3 of that logic or 4x more code, the sky is the limit...

@brianteeman
Copy link
Contributor

just wanted to say that I get the benefits of this now. Took me a while - sorry.

@thednp
Copy link
Contributor

thednp commented Oct 1, 2021

I'm happy my issue #35606 has such a successful path. I'm happy to come here for a test as soon as I can.

@dgrammatiko dgrammatiko marked this pull request as draft October 10, 2021 11:42
@brianteeman
Copy link
Contributor

I get the benefit of this so much more now.

@dgrammatiko
Copy link
Contributor Author

@brianteeman I’m happy to finalize this if it ever gets an approval but I’m also happy that you already did the container part. Btw the tinymce’s docs have some more there: https://www.tiny.cloud/docs/demo/format-html5/

@brianteeman
Copy link
Contributor

I forgot you had done this and started to do the same exact thing this morning after feedback from my "do more with core" talk last night.

@dgrammatiko
Copy link
Contributor Author

This one could be revisited in v5

@dgrammatiko dgrammatiko deleted the 4.1-dev-tinyMCE2021 branch November 13, 2021 12:04
@thednp
Copy link
Contributor

thednp commented Nov 13, 2021

I'll get back to this as soon as I can, unfortunately couldn't assist lately. Why close?

@dgrammatiko
Copy link
Contributor Author

#35871 (comment)

@joomdonation
Copy link
Contributor

@dgrammatiko I'm the one who wrote the code, not you, so please don't be upset and close your PRs :)

@thednp
Copy link
Contributor

thednp commented Nov 13, 2021

@dgrammatiko

I don't share that guy's opinion, if he wants J3 functionality to be forever, he should probably stick to J3.

I think your PR here is great without even testing it, I've read some code and I like it. I'm sure I'm gonna love it once I've actually tested it :)

So please take it easy man, I'm here.

@dgrammatiko
Copy link
Contributor Author

@joomdonation I'm not gonna close the open PRs that are still valid and I'm also gonna finish the child templates work as I promised because today apparently it's #WorldKindnessDay

@thednp parts of this PR are already implemented with the child templates and also @brianteeman did the base for the JSON in TinyMCE with #35715 so things could at some point reach the point I demoed here. The editor CSS endpoint didn't make it for 4.1, but you could try again in a future release.

@joomdonation
Copy link
Contributor

@dgrammatiko Happy to hear that and thanks !

@thednp
Copy link
Contributor

thednp commented Nov 13, 2021

Please reopen the PR, I'm going to work on it next on my list. I don't see any reason why this wouldn't make it to 4.1.

@dgrammatiko
Copy link
Contributor Author

@thednp as I said before some parts are already part of other PRs.

If you want to work on the remaining parts these are:

  • Introduce style_formats.json and formats.json to allow tinyMCE to use Bootstrap, Tailwind or whatever other CSS frameworks in the produced HTML. (You have to extend the work already started with Tinymce html5 containers #35715)

  • Templates that support the new mode (child templates) could provide an end point jeditor.php, a copy of their index.php that will return a css representative of the template's styles used

You're more than welcome to use any of the code here, eg

That said please get some advice either from @bembelimen (4.1) or @HLeithner, I think the features for 4.1 are already fixed (but I might be wrong)

@brianteeman
Copy link
Contributor

Don't allow yourself be bullied by ignorant fools

dgrammatiko added a commit to dgrammatiko/joomla-cms that referenced this pull request Nov 25, 2021
- simplify the logic for the editor.css
- add the code from joomla#35669 for the template snippets to support files placed in the media folder (aka publically accessible)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
RFC Request for Comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants