Skip to main content
Home  ›  Blog

2sxc 15 with Google Translate - Merry X-Mas

2sxc 15 brings Google Translate, huge internal clean-up and upgrades to third party components like TinyMCE. Merry X-Mas!


  1. Integrated Google Translate into the Edit UI
  2. Updated many third party components like TinyMCE, RazorBlade and more
  3. Loads of nice features to make life easier
  4. Prepared the foundation for WYSIWYG awesomeness in 2023 Q1

Google Translate Integration

Editors can now automatically translate their texts and WYSIWYG content with a few clicks using Google Translate. 

Example from English to German

Example from English to Arabic

Note that in this example, we can choose from two languages, because DE has content as well:

How Translate Works

There were a lot of challenges, but we believe that we nailed it. 

  1. When you want to translate a single field, you just have to pick the source language and it translates it.
  2. To translate the entire item, select translate all field. You'll then get a dialog to choose the source language. This dialog will also tell you if all fields in that language have content etc.
  3. When translating all, there is a lot of logic built in so it will only take fields which it's supposed to translate - and you can override these configurations.
    1. Example: A name or street field could contain a text such as "Charity" (a real name). If it were auto translated, this would be terrible. So you can configure fields to not auto-translate.
    2. Example: Number or GPS fields won't auto-translate by default - because they usually won't change. But you can also set it to auto-unlock when you do Translate-All, to make the editors life easier

A huge thanks to bond for websolutions! This feature was made possible because part of the work was sponsored by them. We are super grateful for such contributions! This didn't cover the entire cost, but enough to jump-start it. If you want to use it too, become a Patron AdvancedCMS.

No More Undescore _Razor.cshtml

The underscore in front of every Razor file is a security measure for certain scenarios that don't apply to 2sxc. Because of this, we are now removing this strange behavior and defaulting to non-underscore files.

If for whatever reason you want them - feel free to keep using them 😜.

TinyMCE Upgrade to v6

We upgraded TinyMCE from v5 to v6 and slightly enhanced the toolbars. The default toolbars now have a paste and past-as-text button, which was one of the biggest problems users had when working with WYSIWYG. Before: 


This is also the foundation for upcoming features in Q1, where we wish to improve the WYSIWYG for rich-content scenarios such as blogs. Because one of the major challenges is adding images and ensuring proper allignment and responsive behavior when you are writing long content (such as this).

Important: If you had a custom WYSIWYG Input Field, you must ensure that it still works. TinyMCE is mostly compatible from v5 to v6, but there could be breaking changes.

Razor Blade 4 Upgrade + HtmlTag Service

RazorBlade is a well integrated library of Razor helpers created by the same team as 2sxc. Since we use it a lot ourselves, we made some enhancements which will improve productivity. Don't worry if you don't understand the following lines - if you do, enjoy 😏.

  1. All Tag objects now implement a common IHtmlTag interface. This is helpful in scenarios where you need typed objects but don't know what exact type it is. Before you had an ITag<Div> and an ITag<P> which were not as easy to mix.
  2. We created a new IHtmlTagService (on Razor.Blade) and added it to the Kit on Kit.HtmlTag. It's almost the same as the static ToSic.Razor.Blade.Tag object, but not quite. The main difference is that it's now a fluid, functional API where every change returns a new object. If you don't understand the difference, don't worry, if you do, rejoice 🀘🏾.

Third Party Upgrades

We upgraded a lot of our third party components, such as:

  1. TinyMCE from v5 to v6
  2. CsvHelper to latest version
  3. RazorBlade from v3 to v4
  4. Koi

For normal use of 2sxc this should be non-breaking. 

But if you did some advanced work and used non-public APIs, this could lead to surprises. 

DataSource APIs Refactored (Breaking Change)

DataSources were using an architecture from the times before Dependency Injection. This was technical debt that had to be addressed. Since we changed something internal with logging - which requires all custom data sources to recompile anyhow, we also did this in the same go.

⚠️ This is a breaking change, but will only affect you if you created custom data sources. in that case you'll have to make some adjustments and recompile. See docs.

New Awesome Productivity APIs

New Page.TurnOn(...)

turnOn has been a key part of 2sxc for about a year now, but adding turnOn to a Razor-Page was a bit challenging when you needed to add data for the method etc. The new IPageService.TurnOn(...) makes it much easier. 

ImageService with imgAltFallback and Description

The ImageService is used to create perfect img and picture tags - in multiple sizes, formats such as WebP and more. A common challenge is to provide an alt-text. Because by default the editor can manually define the alt-text, but the Razor would often want to provide a fallback. This was difficult to do, but now the commands have an imgAltFallback property for these cases. In addition, the img/picture objects have a Description property which makes it easier to access the image metadata. 

Page.Parameters.Set(key, value) Enhancement

Previously the value always had to be a string. Now it can be anything, which will be auto-converted to string.

Dynamic Entity / Settings Get enhancements

Dynamic entities are what you usually use in Razor when you write something like @Content.Name. The property Name doesn't really exist on the object, but the system makes it happen. 

But in some cases you want more control. For example, there is a @Content.Get("Name") where you can get it for other purposes (such as @Content.Get("Link", convertLinks: false). This has been part of the API for years. We've now enhanced it a lot:

  1. New Get<type>("name") for typed objects
    This way the resulting object can be typed as a string, int etc.This is especially great if you want values to be converted - say you have a decimal (the way numbers are stored) and really just want the int.
  2. New Get("name", fallback: "unknown")
    This will return a value typed the way fallback is typed - so it's actually a Get<type>(name,fallback). It will get you the fallback if name doesn't exist, can't be found or is not convertable.
  3. New Get("Children.Children.Name") path access
    In some cases you need sub-sub-objects but need to be careful about null-checks because the entire path may not exist. This new accessor makes it easy and safe - you'll just get a null if the path doesn't work.
  4. New Settings.Get(path) - same behavior as Get-path, but with stack traversal
  5. New Resources.Get(path) - same behavior as Get-path, but with stack traversal

DataSource ValueFilter can now do Contains on Numbers

Value Filters are often used to find-items-which-have-this-value. It also has a "contains" operator, but this didn't work for numbers. Now you can provide numbers in a comma-separated way, and use it to find-all-which-have-one-of-the-supplied-numbers.

SQL Data Timeline Compression

2sxc stores every change to entities so that users can roll back changes. This is stored in a DataTimeline table, which can grow significantly with time. Since the data isn't used much (only when undoing changes) we felt that we could compress the data instead of storing it as plain JSON. For now, we're using a ZIP compression because Brotli isn't available in .net 4.7.2. Read more in the docs.

This is a feature for people who love 2sic so much they support it = 🦸🏻‍♀️ Patrons Infrastructure.

Custom GPS Default Coordinates

When people add addresses there are default GPS coordinates which were currently hardwired in the UI. It was also possible to create defaults for each field, but now basic patrons can activate a feature to preset this system-wide. 

Ability to Sync Apps with ADAM Assets

Previously you were able to sync apps by storing their state in the app.xml, copying the folder to a site which had the app installed already, and re-sync the app. This was often done using a Git repository to better sync various systems. But what was always missing were the ADAM assets - so here's what's new:

  1. You can now save the state of the app with ADAM assets
  2. You can import it with the assets
  3. You can also add the folder to a new system which doesn't have the app installed, and import it directly.

These are all very advanced features and only for 🦸🏻‍♀️ Patron SuperAdmins.

Other Enhancements

  1. Database Clean-Up
  2. Install ZIPs were renamed to make it less confusing
  3. Deployment in NuGet (Oqtane) changed - to ToSic.Sxc.Oqtane.Install
  4. Api Keys like Google-Maps and Google-Translate are now stored in the backend and provided to the UI
  5. Change the ".data" folder in the 2sxc files to be "App_Data" to protect it as it could contain license information in future.
  6. Ability to store special corporate licenses in the "App_Data/system-custom" so that larger customers can pre-install licenses. 

TL;DR - Merry X-Mas!

We're really excited - and hope you are too. Get your personal christmas gift on github!

Merry Christmas from the whole 2sxc team!

Daniel Mettler grew up in the jungles of Indonesia and is founder and CEO of 2sic internet solutions in Switzerland and Liechtenstein, an 20-head web specialist with over 800 DNN projects since 1999. He is also chief architect of 2sxc (see github), an open source module for creating attractive content and DNN Apps.

Read more posts by Daniel Mettler