Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 58 additions & 13 deletions 14/umbraco-cms/extending-cms/key-vault.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,25 +39,70 @@ The next step is to add the Azure Key Vault endpoint to the `appsettings.json` f
}
```

After adding the Key Vault endpoint you have to update the `CreateHostBuilder` method which you can find in the `Program.cs` file.
After adding the endpoint in the appsettings, it's time to add configuration so that the KeyVault is used. One way to achieve this is to write an extension method for the `WebApplicationBuilder`:

```csharp
Host.CreateDefaultBuilder(args)
.ConfigureUmbracoDefaults()
.ConfigureAppConfiguration((context, config) =>
using System;
using Azure.Identity;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Extensions;

namespace My.Website;

public static class WebApplicationBuilderExtensions
{
public static WebApplicationBuilder ConfigureKeyVault(this WebApplicationBuilder builder)
{
var keyVaultEndpoint = builder.Configuration["AzureKeyVaultEndpoint"];
if (!string.IsNullOrWhiteSpace(keyVaultEndpoint) && Uri.TryCreate(keyVaultEndpoint, UriKind.Absolute, out var validUri))
{
builder.Configuration.AddAzureKeyVault(validUri, new DefaultAzureCredential());
}

return builder;
}
}
```

After creating the extension method, it's possible to call it from the `Program.cs` class, like so:

```csharp
using Microsoft.AspNetCore.Builder;
using My.Project;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Extensions;

WebApplicationBuilder builder = WebApplication.CreateBuilder(args);

builder.ConfigureKeyVault();

builder.CreateUmbracoBuilder()
.AddBackOffice()
.AddWebsite()
.AddDeliveryApi()
.AddComposers()
.Build();

WebApplication app = builder.Build();

await app.BootUmbracoAsync();

app.UseUmbraco()
.WithMiddleware(u =>
{
var settings = config.Build();
var keyVaultEndpoint = settings["AzureKeyVaultEndpoint"];
if (!string.IsNullOrEmpty(keyVaultEndpoint) && Uri.TryCreate(keyVaultEndpoint, UriKind.Absolute, out var validUri))
{
config.AddAzureKeyVault(validUri, new DefaultAzureCredential());
}
u.UseBackOffice();
u.UseWebsite();
})
.ConfigureWebHostDefaults(webBuilder =>
.WithEndpoints(u =>
{
webBuilder.UseStaticWebAssets();
webBuilder.UseStartup<Startup>();
u.UseInstallerEndpoints();
u.UseBackOfficeEndpoints();
u.UseWebsiteEndpoints();
});

await app.RunAsync();
```

### Authentication
Expand Down
18 changes: 14 additions & 4 deletions 14/umbraco-cms/extending-cms/language-files.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,18 @@ description: >-
# Language Files & Localization

Language files are XML files used to translate:
- The Umbraco backoffice user interface so that end users can use Umbraco in their native language. This is particularly important for content editors who do not speak English.
- The member identity errors in an Umbraco website enabling end users to use Umbraco in the website language.
- Read [Add translations for your packages](packages/language-files-for-packages.md) to see how to include translations for your own package.
- Override existing language files

* The Umbraco backoffice user interface so that end users can use Umbraco in their native language. This is particularly important for content editors who do not speak English.
* The member identity errors in an Umbraco website enabling end users to use Umbraco in the website language.
* Read [Add translations for your packages](packages/language-files-for-packages.md) to see how to include translations for your own package.
* Override existing language files.

{% hint style="info" %}
You can use localization files for Document and Media Types as well. You can find more information about this in the [Document Type Localization](../fundamentals/data/defining-content/document-type-localization.md) article.
{% endhint %}

This is an example of such a language file, the most important parts are the `alias` fields of the `<area>` and `<key>` elements. This is what you need to retrieve the values from .NET or Angular.

```xml
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<language alias="en" intName="English (UK)" localName="English (UK)" lcid="" culture="en-GB">
Expand Down Expand Up @@ -91,6 +97,10 @@ If you want to override Umbraco core translations or translations shipped with p
/config/lang/{language}.user.xml
```

{% hint style="info" %}
The `/config/lang/` folders do not exist on a clean installation of the CMS. You will need to create them at the root of your `src` project.&#x20;
{% endhint %}

By default, these files are empty but you can add any new keys you want or override existing ones with your own translations. The nice part about the user files is that they will not get overwritten by the installer when you upgrade your Umbraco versions.

In order for these files to deploy when you do a `dotnet publish`, you need to add the following to your `.csproj` file:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,7 @@ The `UmbracoMediaVideo` media type has the following properties:
* `umbracoBytes` - Label (bigint)

![MediaVideo](../../../../../10/umbraco-cms/fundamentals/data/creating-media/images/umbraco-media-video-media-type.png)

{% hint style="info" %}
You can also create localization files for Media Types. You can read more about this in the [Document Type Localization](../defining-content/document-type-localization.md) article.
{% endhint %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
---
description: Here you will learn how to apply localization for Document Types in Umbraco.
---

# Document Type Localization

The Umbraco backoffice is fully localized to match the user's [configured language](../users.md). When defining Document Types, you can apply localization to:

* Document Type names and descriptions.
* Property names and descriptions.
* Custom property validation messages.
* Tab and group names.

Setting up localization for Document Types is a two-step process:

* Create the localizations in [user defined language files](../../../extending/language-files.md).
* Apply the localizations to the Document Types.

{% hint style="info" %}
Everything in this article also applies to defining [Media Types](../creating-media/).
{% endhint %}

## Creating localizations

User defined language files are created in `/config/lang` and must be named `{language}.user.xml`. For example: `en-us.user.xml`.

There are no specific requirements as to how localizations should be structured for use in Document Types. The following localizations have been used for the samples in this article:

{% code title="en-us.user.xml" lineNumbers="true" %}
```xml
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<language>
<area alias="contentTypes">
<key alias="article">Article page</key>
<key alias="article-desc">A textual, article-like page on the site. Use this as the main type of content.</key>
<key alias="landing">Landing page</key>
<key alias="landing-desc">An inviting, very graphical page. Use this as an entry point for a campaign, and supplement with Articles.</key>
</area>
<area alias="tabs">
<key alias="content">Page content</key>
<key alias="seo">SEO configuration</key>
</area>
<area alias="groups">
<key alias="titles">Page titles</key>
</area>
<area alias="properties">
<key alias="title">Main title</key>
<key alias="title-desc">This is the main title of the page.</key>
<key alias="title-message">The main title is required for this page.</key>
<key alias="subTitle">Sub title</key>
<key alias="subTitle-desc">This is the sub title of the page.</key>
</area>
</language>
```
{% endcode %}

{% hint style="info" %}
Umbraco must be restarted to pick up on changes to language files.
{% endhint %}

## Applying localizations

The localizations are applied by using the syntax `#{area alias}_{key alias}`.

1. Create a **Document Type with template** called `#contentTypes_article` with **alias**: `articlePage`.
2. Under the newly created document type follow these steps:

* Name the **description** to `#contentTypes_article-desc`.
* Create a new **tab** called `#tabs_content`.
* Add a new **group** called `#groups_titles`.
* Add a **property** called `#properties_title` with **alias** `title`.
* Set description to `#properties_title-desc`.
* Use a `TextString` editor.
* Enable to `Set this field as mandatory`.
* Under validation add `#properties_title-message`.

![Applying localization to a property](../images/localization-document-type-editor-validation.png)

* Add a **property** called `#properties_subTitle` with **alias** `subTitle`.
* Set description to `#properties_subTitle-desc`.
* Use a `TextString` editor.
* Enable to `Allow as root` in the **Permissions** tab.

![Applying localization to a Document Type](../images/localization-document-type-editor.png)

3. When creating and editing the content, you will see that the backoffice now uses the configured localizations.&#x20;

![Localized document creation dialog](../images/localization-document-editor-create.png)

4. Create a new "Article" content:

![Localized document editing](../images/localization-document-editor.png)

4. When trying to save the content without adding the mandatory content, you will see a warning as expected:

![Localized property validation](../images/localization-document-editor-validation.png)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions 14/umbraco-cms/implementation/composing.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ Below is a list of collections with their corresponding 'collection type' and ho

### Example - Modifying Collections

This example shows how to control which Healthchecks are available to run in the Umbraco backoffice. Create a C# class which implements IUserComposer, the Compose method gives access to the HealthChecks collection of the Umbraco Composition - first we clear all HealthChecks from the collection, then add back in the ones we want to keep:
This example shows how to control which Healthchecks are available to run in the Umbraco backoffice. Create a C# class which implements IComposer, the Compose method gives access to the HealthChecks collection of the Umbraco Composition - first we clear all HealthChecks from the collection, then add back in the ones we want to keep:

```csharp
using Umbraco.Cms.Core.Composing;
Expand Down Expand Up @@ -390,7 +390,7 @@ public static class WebCompositionExtensions
=> builder.WithCollectionBuilder<MyThingsCollectionBuilder>();
}

public class MyThingComposer : IUserComposer
public class MyThingComposer : IComposer
{
public void Compose(IUmbracoBuilder builder)
{
Expand Down Expand Up @@ -482,7 +482,7 @@ public static class WebCompositionExtensions
=> builder.WithCollectionBuilder<MyThingsCollectionBuilder>();
}

public class MyThingComposer : IUserComposer
public class MyThingComposer : IComposer
{
public void Compose(IUmbracoBuilder builder)
{
Expand Down
2 changes: 1 addition & 1 deletion 14/umbraco-cms/implementation/custom-routing/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ For more detailed information see: [IContentFinder documentation](../../referenc

## Custom MVC routes

You can specify your own custom MVC routes to work within the Umbraco pipeline. It requires your controller to inherit from `UmbracoPageController` and either implement `IVirtualPageController` or use `.ForUmbracoPage` when registering your route, for more information and a complete example of both approaches see [Custom routing documentation](./)
You can specify your own custom MVC routes to work within the Umbraco pipeline. It requires your controller to inherit from `UmbracoPageController` and either implement `IVirtualPageController` or use `.ForUmbracoPage` when registering your route, for more information and a complete example of both approaches see [Custom routing documentation](https://docs.umbraco.com/umbraco-cms/reference/routing/custom-routes#custom-routes-within-the-umbraco-pipeline)

An example of registering a `UmbracoPageController` using `.ForUmbracoPage`:

Expand Down
Loading