Skip to content

Commit

Permalink
Merge pull request #45 from ProWorksCorporation/v13/main
Browse files Browse the repository at this point in the history
V13/main
  • Loading branch information
protherj authored May 9, 2024
2 parents 83b4952 + a4ea8e8 commit eefe5de
Show file tree
Hide file tree
Showing 15 changed files with 161 additions and 24 deletions.
45 changes: 45 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,51 @@ The details on each configuration value are described below:
| pluginsToExclude | Array of TinyMCE plugins names to exclude | [] | This excludes these plugins from being selected or used by the Umbraco Rich Text Editor and the TinyMCE Premium Rich Text Editor |
| customConfig | JSON TinyMCE Configuration | {} | See the [Tiny Documentation](https://www.tiny.cloud/docs/tinymce/6/plugins/) for the plugin configuration. Only used by the TinyMCE Premium Rich Text Editor. |

### Additional Advanced Custom Configuration

In addition to the customConfig setting in the "TinyMceConfig" section of the appSettings.config above, there is a way to extend the configuration to allow for javascript functions to be used. No javascript functions can be added to the "customConfig" above because it is not valid JSON.

To allow javascript to be present in for the configuration of the TinyMCE Premium Plugin you will need to add a custom App_Plugin to extend Umbraco's back-office.

#### Here are the steps below:

1. Add an App_Plugins folder to the Umbraco project at the root if one is not present
2. Add a folder and call it something like "TinyMCE.Premium.Overrides". This is arbitrary, but if you change it then the package.manifest will need to change the paths below.
3. Add a new .js file to the "TinyMCE.Premium.Overrides" folder. Something like "tinymce.custom.config.js" works well.
4. In the "tinymce.custom.config.js" file add the code below:

```
!(function () {
function init() {
window.tinymcepremium.Config.custom_user_config = {
// Add your config here -- can contain javascript after the ":"
spellchecker_ignore_list: [ "senectus", "malesuada" ]
};
}
/**
* Initialize after the app.ready event
*/
angular.module("umbraco").run(function ($rootScope) {
$rootScope.$on('app.ready', init)
})
})()
```
5. Add a new "package.manifest" file in the "TinyMCE.Premium.Overrides" folder.
6. In the "package.manifest" file add the code below:
```
{
"javascript": [
"/App_Plugins/TinyMCE.Premium.Overrides/tinymce.custom.config.js"
]
}
```

Now when the TinyMCE Premium editor loads up, it will load the configuration in the "tinymce.custom.config.js" files as well.

## Data Types

### Umbraco's Rich Text Editor
Expand Down
13 changes: 7 additions & 6 deletions src/TinyMCE.Umbraco.Premium/Composers/TinyMceComposer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -271,17 +271,18 @@ public void Compose(IUmbracoBuilder builder)
/// <inheritdoc />
private class ServerVariablesParsingNotificationHandler : INotificationHandler<ServerVariablesParsingNotification>
{
private TinyMceConfig _tinyMceConfig;
private TinyMceConfig _tinyMceConfig;

public ServerVariablesParsingNotificationHandler(IOptions<TinyMceConfig> tinyMceConfig) {
_tinyMceConfig = tinyMceConfig.Value;
}
public ServerVariablesParsingNotificationHandler(IOptions<TinyMceConfig> tinyMceConfig) {
_tinyMceConfig = tinyMceConfig.Value;
}

/// <inheritdoc />
public void Handle(ServerVariablesParsingNotification notification) => notification.ServerVariables.Add("tinymcepremium", new
/// <inheritdoc />
public void Handle(ServerVariablesParsingNotification notification) => notification.ServerVariables.Add("tinymcepremium", new
{
apiKey = _tinyMceConfig != null ? _tinyMceConfig.apikey : "",
openAiApikey = _tinyMceConfig != null ? _tinyMceConfig.openAiApikey : "",
pluginsToExclude = _tinyMceConfig != null ? _tinyMceConfig.pluginsToExclude : Array.Empty<string>()
});
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/TinyMCE.Umbraco.Premium/TinyMCE.Umbraco.Premium.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<PackageId>tinymce.umbraco.premium</PackageId>
<Product>TinyMCE.Umbraco.Premium</Product>
<Title>TinyMCE.Umbraco.Premium</Title>
<Version>13.2.2</Version>
<Version>13.2.3</Version>
<Description>Umbraco CMS package that enables the TinyMCE-based Rich Text Editor (RTE) in Umbraco versions 12+ to be licensed to access the paid Premium features in TinyMCE.</Description>
<PackageTags>umbraco plugin package tinymce</PackageTags>
<Authors>jasonproworks</Authors>
Expand Down
2 changes: 1 addition & 1 deletion src/TinyMCE.Umbraco.Premium/package.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="13.0.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<umbPackage>
<info>
<package>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
(function (config, undefined) {

config.custom_user_config = {
};

}(window.tinymcepremium.Config = window.tinymcepremium.Config || {}));
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,33 @@
}

var tinymcePremiumPluginsList = window.tinymcepremium.Config.tinymcePremiumPluginsList;
var pluginsToRemoveCompletely = Umbraco.Sys.ServerVariables.tinymcepremium.pluginsToExclude;

// Remove extra plugins that maybe no longer apply but were saved to prevalues at some point
var allPossiblePlugins = _.pluck($scope.tinyMceConfig.plugins, "name");
var premiumPlugins = _.pluck(tinymcePremiumPluginsList, "alias");
allPossiblePlugins = _.union(allPossiblePlugins, premiumPlugins);
allPossiblePlugins = _.difference(allPossiblePlugins, pluginsToRemoveCompletely);
$scope.model.value.plugins = _.intersection(allPossiblePlugins, $scope.model.value.plugins);
$scope.model.value.pluginsToExclude = _.difference(allPossiblePlugins, $scope.model.value.plugins);

var allPlugins = allPossiblePlugins;
var modifiedTinymcePremiumPluginsList = _.filter(tinymcePremiumPluginsList, function (p) { return _.indexOf(pluginsToRemoveCompletely, p.alias) < 0 });

// Setup the checklist data for selecting plugins
if (tinymcePremiumPluginsList != null) {
$scope.tinyMceConfig.pluginOptions = _.map(tinymcePremiumPluginsList, obj => {
if (modifiedTinymcePremiumPluginsList != null) {

// adding plugins that have been added via config or are defaults
_.each(allPlugins, function (p) {
if (p != null) {
var relatedPlugin = _.findWhere(modifiedTinymcePremiumPluginsList, { alias: p });
if (!relatedPlugin) {
modifiedTinymcePremiumPluginsList = _.union(modifiedTinymcePremiumPluginsList, [{ name: p, alias: p }]);
}
}
});

$scope.tinyMceConfig.pluginOptions = _.map(modifiedTinymcePremiumPluginsList, obj => {

const objPlugin = Utilities.extend(obj, {
displayName: obj.name,
Expand All @@ -74,7 +90,7 @@
}

var allCommands = $scope.tinyMceConfig.commands;
_.each(tinymcePremiumPluginsList, function (p) {
_.each(modifiedTinymcePremiumPluginsList, function (p) {
if (p.command != null) {
var relatedCommand = _.findWhere(allCommands, { alias: p.command.alias });
if (!relatedCommand) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
const plugins = document.createElement('script')
plugins.referrerPolicy = 'origin'

//console.log('init()')

//console.log(Umbraco.Sys.ServerVariables.tinymcepremium.apiKey)

// Compose the URL to the TinyMCE plugins.min.js file using the Umbraco.Sys.ServerVariables.tinymcepremium.apiKey variable.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"~/App_Plugins/TinyMCE.Umbraco.Premium/premuim.rte.component.js",
"~/App_Plugins/TinyMCE.Umbraco.Premium/Defaults/advtemplate.templates.js",
"~/App_Plugins/TinyMCE.Umbraco.Premium/Defaults/mergetags.templates.js",
"~/App_Plugins/TinyMCE.Umbraco.Premium/Defaults/ai.templates.js"
"~/App_Plugins/TinyMCE.Umbraco.Premium/Defaults/ai.templates.js",
"~/App_Plugins/TinyMCE.Umbraco.Premium/Defaults/custom.config.templates.js"
],
"bundleOptions": "None"
}
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,12 @@
}
}
}

// Load any User Defined Custom Config
if (window.tinymcepremium.Config.custom_user_config != null) {
Utilities.extend(standardConfig, window.tinymcepremium.Config.custom_user_config);
}

if (standardConfig.plugins.indexOf("powerpaste")) {
// remove the "paste" plugin per TinyMCE docs
standardConfig.plugins = _.without(standardConfig.plugins, "paste");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"javascript": [
"/App_Plugins/TinyMCE.Premium.Overrides/tinymce.custom.config.js"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
!(function () {

function init() {

window.tinymcepremium.Config.custom_user_config = {
mentions_fetch: (query, success) => {
// Fetch your full user list from the server and cache locally
var users = [
{
id: "1",
name: 'John Smith'
},
{
id: "2",
name: 'Joe Cool'
},
{
id: "3",
name: 'Zander Geulph'
}

];

// query.term is the text the user typed after the '@'
var filteredUsers = _.filter(users, function (user) {
return user.name.toLowerCase().indexOf(query.term.toLowerCase()) !== -1;
});

filteredUsers = filteredUsers.slice(0, 10);

// Where the user object must contain the properties `id` and `name`
// but you could additionally include anything else you deem useful.
success(filteredUsers);

}
};
}

/**
* Initialize after the app.ready event where we have access
* to the Umbraco.Sys.ServerVariables variables as well as any AngularJS services.
*/
angular.module("umbraco").run(function ($rootScope) {
$rootScope.$on('app.ready', init)
})

})()
9 changes: 9 additions & 0 deletions src/Umbraco.Cms.Demo/Umbraco.Cms.Demo.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@
<RuntimeHostConfigurationOption Include="System.Globalization.AppLocalIcu" Value="72.1.0.3" Condition="$(RuntimeIdentifier.StartsWith('linux')) or $(RuntimeIdentifier.StartsWith('win')) or ('$(RuntimeIdentifier)' == '' and !$([MSBuild]::IsOSPlatform('osx')))" />
</ItemGroup>

<ItemGroup>
<Folder Include="App_Plugins\TinyMCE.Premium.Overrides\" />
</ItemGroup>

<ItemGroup>
<None Include="app_plugins\tinymce.premium.overrides\package.manifest" />
<None Include="app_plugins\tinymce.premium.overrides\tinymce.custom.config.js" />
</ItemGroup>

<PropertyGroup>
<!-- Razor files are needed for the backoffice to work correctly -->
<CopyRazorGenerateFilesToPublishDirectory>true</CopyRazorGenerateFilesToPublishDirectory>
Expand Down
12 changes: 6 additions & 6 deletions src/Umbraco.Cms.Demo/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
}
},
"RichTextEditor": {
"Plugins": [],
"Plugins": ["mentions"],
"Commands": [],
"CustomConfig": {
"test": "test",
Expand All @@ -41,14 +41,14 @@
}
}
},
"ConnectionStrings": {
"umbracoDbDSN": "Data Source=|DataDirectory|/Umbraco.sqlite.db;Cache=Shared;Foreign Keys=True;Pooling=True",
"umbracoDbDSN_ProviderName": "Microsoft.Data.Sqlite"
},
//"ConnectionStrings": {
// "umbracoDbDSN": "Data Source=|DataDirectory|/Umbraco.sqlite.db;Cache=Shared;Foreign Keys=True;Pooling=True",
// "umbracoDbDSN_ProviderName": "Microsoft.Data.Sqlite"
//},
"TinyMceConfig": {
"apikey": "Add To User Secrets",
"openAiApikey": "Add To User Secrets",
"pluginsToExclude": [],
"pluginsToExclude": [ "typography", "tinymcespellchecker" ],
"customConfig": {
"spellchecker_ignore_list": [ "senectus", "malesuada" ],
"advtemplate_templates": [
Expand Down
2 changes: 1 addition & 1 deletion src/Umbraco.Cms.Demo/readme.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
This is a demo website for testing the package. It is intentionally an Umbraco 12.0.0 site to test for support of that version.
This is a demo website for testing the package. It is intentionally an Umbraco 13.2.2 site to test for support of that version.
9 changes: 4 additions & 5 deletions src/Umbraco.Cms.Demo/uSync/v9/DataTypes/TinyMcePremium.config
Original file line number Diff line number Diff line change
Expand Up @@ -69,34 +69,33 @@
"autolink",
"directionality",
"searchreplace",
"mentions",
"accordion",
"codesample",
"emoticons",
"help",
"insertdatetime",
"wordcount",
"a11ychecker",
"casechange",
"checklist",
"export",
"footnotes",
"pageembed",
"permanentpen",
"tinymcespellchecker",
"advcode",
"advtable",
"advtemplate",
"ai",
"mediaembed",
"linkchecker",
"powerpaste",
"autocorrect"
],
"pluginsToExclude": [
"typography",
"a11ychecker",
"formatpainter",
"mergetags",
"tableofcontents"
"tableofcontents",
"ai"
],
"customConfigAsString": "{\n\t\"entity_encoding\": \"raw\",\n\t\"advcode_inline\": \"True\",\n\t\"spellchecker_language\": \"en\",\n\t\"test\": \"test\",\n\t\"advtemplate_templates\": \"[{\\\"title\\\":\\\"Quick replies\\\",\\\"items\\\":[{\\\"title\\\":\\\"Message received\\\",\\\"content\\\":\\\"\\\\u003Cp dir=\\\\u0022ltr\\\\u0022\\\\u003EHey {{Customer.FirstName}}!\\\\u003C/p\\\\u003E\\\\n\\\\u003Cp dir=\\\\u0022ltr\\\\u0022\\\\u003EJust a quick note to say we\\\\u0026rsquo;ve received your message, and will get back to you within 48 hours.\\\\u003C/p\\\\u003E\\\\n\\\\u003Cp dir=\\\\u0022ltr\\\\u0022\\\\u003EFor reference, your ticket number is: {{Ticket.Number}}\\\\u003C/p\\\\u003E\\\\n\\\\u003Cp dir=\\\\u0022ltr\\\\u0022\\\\u003EShould you have any questions in the meantime, just reply to this email and it will be attached to this ticket.\\\\u003C/p\\\\u003E\\\\n\\\\u003Cp\\\\u003E\\\\u003Cstrong\\\\u003E\\\\u0026nbsp;\\\\u003C/strong\\\\u003E\\\\u003C/p\\\\u003E\\\\n\\\\u003Cp dir=\\\\u0022ltr\\\\u0022\\\\u003ERegards,\\\\u003C/p\\\\u003E\\\\n\\\\u003Cp dir=\\\\u0022ltr\\\\u0022\\\\u003E{{Agent.FirstName}}\\\\u003C/p\\\\u003E\\\"},{\\\"title\\\":\\\"Thanks for the feedback\\\",\\\"content\\\":\\\"\\\\u003Cp dir=\\\\u0022ltr\\\\u0022\\\\u003EHi {{Customer.FirstName}},\\\\u003C/p\\\\u003E\\\\n\\\\u003Cp dir=\\\\u0022ltr\\\\u0022\\\\u003EWe appreciate you taking the time to provide feedback on {{Product.Name}}.\\\\u003C/p\\\\u003E\\\\n\\\\u003Cp dir=\\\\u0022ltr\\\\u0022\\\\u003EIt sounds like it wasn\\\\u0026rsquo;t able to fully meet your expectations, for which we apologize. Rest assured our team looks at each piece of feedback and uses it to decide what to focus on next with {{Product.Name}}.\\\\u003C/p\\\\u003E\\\\n\\\\u003Cp dir=\\\\u0022ltr\\\\u0022\\\\u003E\\\\u003Cstrong\\\\u003E\\\\u0026nbsp;\\\\u003C/strong\\\\u003E\\\\u003C/p\\\\u003E\\\\n\\\\u003Cp dir=\\\\u0022ltr\\\\u0022\\\\u003EAll the best, and let us know if there\\\\u0026rsquo;s anything else we can do to help.\\\\u003C/p\\\\u003E\\\\n\\\\u003Cp dir=\\\\u0022ltr\\\\u0022\\\\u003E-{{Agent.FirstName}}\\\\u003C/p\\\\u003E\\\"},{\\\"title\\\":\\\"Still working on case\\\",\\\"content\\\":\\\"\\\\u003Cp dir=\\\\u0022ltr\\\\u0022\\\\u003EHi {{Customer.FirstName}},\\\\u003C/p\\\\u003E\\\\n\\\\u003Cp dir=\\\\u0022ltr\\\\u0022\\\\u003EJust a quick note to let you know we\\\\u0026rsquo;re still working on your case. It\\\\u0026rsquo;s taking a bit longer than we hoped, but we\\\\u0026rsquo;re aiming to get you an answer in the next 48 hours.\\\\u003C/p\\\\u003E\\\\n\\\\u003Cp dir=\\\\u0022ltr\\\\u0022\\\\u003EStay tuned,\\\\u003C/p\\\\u003E\\\\n\\\\u003Cp dir=\\\\u0022ltr\\\\u0022\\\\u003E{{Agent.FirstName}}\\\\u003C/p\\\\u003E\\\"}]}]\",\n\t\"spellchecker_ignore_list\": \"[\\\"senectus\\\",\\\"malesuada\\\"]\"\n}"
},
Expand Down

0 comments on commit eefe5de

Please sign in to comment.