Skip to content

Commit 7d5329d

Browse files
committed
Merge branch 'main' into v15/correct-package-manifest
# Conflicts: # 15/umbraco-cms/customizing/extending-overview/extension-registry/extension-manifest.md # 15/umbraco-cms/customizing/umbraco-package.md
2 parents 88b0de5 + ce0b891 commit 7d5329d

File tree

1,171 files changed

+18586
-10074
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,171 files changed

+18586
-10074
lines changed

.github/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ This is the documentation project for Umbraco. The scope of this project is to p
77
# Contributing [![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/umbraco/UmbracoDocs/issues) [![GitHub contributors](https://img.shields.io/github/contributors/umbraco/UmbracoDocs.svg)](https://GitHub.com/umbraco/UmbracoDocsgraphs/contributors/)
88
We :heart: valuable contributions from everyone who is willing to help. It does not matter to us if it's something trivial like correcting spelling mistakes, raising an issue or writing a tutorial! Every little bit of help counts and it all helps make Umbraco easier to use, for everyone.
99
Otherwise, [bug reports](https://github.com/umbraco/UmbracoDocs/issues/), [bug fixes](https://github.com/umbraco/UmbracoDocs/pulls) and any feedback on Umbraco are always appreciated.
10-
Look at the [Contributor Guidelines](https://docs.umbraco.com/contribute/getting-started) to learn how you can get involved and help with the Umbraco Documentation.
10+
Look at the [Contributor Guidelines](https://docs.umbraco.com/contributing/documentation/getting-started) to learn how you can get involved and help with the Umbraco Documentation.
1111
## License [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE.md)
1212
This library is released under the [MIT License](LICENSE.md).

10/umbraco-cms/fundamentals/code/debugging/logging.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ keywords: logging serilog messagetemplates logs v9 version9
66

77
In Umbraco we use the underlying logging framework of [Serilog](https://serilog.net/).
88

9-
Out of the box we write a JSON log file that contains a more rich logfile, that allows tools to perform searches & correlation on log patterns a lot easier.
9+
Out of the box, we write a JSON log file that contains a more detailed logfile. This allows tools to perform searches and correlations on log patterns more efficiently.
1010

1111
The default location of this file is written to `umbraco/Logs` and contains the Machine name, along with the date too:
1212

@@ -20,7 +20,7 @@ Serilog is a logging framework that allows us to do structured logging or write
2020
2021-08-10 09:33:23,677 [P25776/D1/T22] INFO Umbraco.Cms.Core.Services.Implement.ContentService - Document Home (id=1062) has been published.
2121
```
2222

23-
Here is an example of the same log message represented as JSON, you can see here we have much more information that would allow us to search & filter logs based on these properties with an appropriate logging system.
23+
Here is an example of the same log message represented as JSON. More information is available and allows you to search and filter logs based on these properties with an appropriate logging system.
2424

2525
```json
2626
{
@@ -46,13 +46,13 @@ Here is an example of the same log message represented as JSON, you can see here
4646
}
4747
```
4848

49-
To learn more about structured logging and message templates you can read more about it over on the [https://messagetemplates.org](https://messagetemplates.org) website or alternatively watch this video from the Serilog creator - [https://www.youtube.com/watch?v=OhmNp8UPEEg](https://www.youtube.com/watch?v=OhmNp8UPEEg)
49+
To learn more about structured logging and message templates you can read more about it over on the [https://messagetemplates.org](https://messagetemplates.org) website. Alternatively watch this video from the Serilog creator - [https://www.youtube.com/watch?v=OhmNp8UPEEg](https://www.youtube.com/watch?v=OhmNp8UPEEg)
5050

5151
## Writing to the log
5252

53-
Umbraco writes log messages, but you are also able to use the Umbraco logger to write the log file as needed, so you can get further insights and details about your implementation.
53+
Umbraco writes log messages, but you are also able to use the Umbraco logger to write the log file as needed. This allows you to gain further insights and details about your implementation.
5454

55-
Here is an example of using the logger to write an Information message to the log which will contain one property of **Name** which will output the name variable that is passed into the method
55+
Here is an example of using the logger to write an Information message to the log. It will contain one property, **Name**, which will output the name variable that is passed into the method.
5656

5757
```csharp
5858
using Microsoft.AspNetCore.Mvc;

10/umbraco-cms/legacy-documentation/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ This documentation platform covers only major versions of the Umbraco CMS since
88

99
The documentation for Umbraco 7 and 8 lives on [our.umbraco.com](https://our.umbraco.com/documentation/).
1010

11-
<table data-card-size="large" data-view="cards"><thead><tr><th align="center"></th><th data-hidden></th><th data-hidden></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td align="center"><strong>Umbraco 7 Documentation</strong></td><td></td><td></td><td></td><td><a href="https://our.umbraco.com/documentation/">https://our.umbraco.com/documentation/</a></td></tr><tr><td align="center"><strong>Umbraco 8 Documentation</strong></td><td></td><td></td><td></td><td><a href="https://our.umbraco.com/documentation/">https://our.umbraco.com/documentation/</a></td></tr><tr><td align="center"><strong>Umbraco 11 Documentation</strong></td><td></td><td></td><td></td><td><a href="https://github.com/umbraco/UmbracoDocs/tree/umbraco-eol-versions">https://github.com/umbraco/UmbracoDocs/tree/umbraco-eol-versions</a></td></tr></tbody></table>
11+
<table data-card-size="large" data-view="cards"><thead><tr><th align="center"></th><th data-hidden></th><th data-hidden></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td align="center"><strong>Umbraco 7 Documentation</strong></td><td></td><td></td><td></td><td><a href="https://our.umbraco.com/documentation/">https://our.umbraco.com/documentation/</a></td></tr><tr><td align="center"><strong>Umbraco 8 Documentation</strong></td><td></td><td></td><td></td><td><a href="https://our.umbraco.com/documentation/">https://our.umbraco.com/documentation/</a></td></tr><tr><td align="center"><strong>Umbraco EOL Documentation</strong></td><td></td><td></td><td></td><td><a href="https://github.com/umbraco/UmbracoDocs/tree/umbraco-eol-versions">https://github.com/umbraco/UmbracoDocs/tree/umbraco-eol-versions</a></td></tr></tbody></table>

10/umbraco-cms/reference/cache/examples/tags.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ For this example we're working with tags. On my site I have two tag properties:
1818

1919
We're going to expose an endpoint that allows us to get the tags from each group.
2020

21-
The tags from the `default` should be cached for a minute and the `blog` tags will be cached until site restart or if you publish a blog post node in the Backoffice.
21+
The tags from the `default` should be cached for a minute. The `blog` tags will be cached until site restart or if you publish a blog post node in the Backoffice.
2222

2323
## Example
2424

10/umbraco-cms/reference/configuration/richtexteditorsettings.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ A config with all the values can be seen underneath. Since there is a lot of def
1616
"Umbraco": {
1717
"CMS": {
1818
"RichTextEditor": {
19-
"Plugins": ["paste", "anchor", "charmap", "table",{...}],
20-
"ValidElements": "+a[id|style|rel|data-id|data-udi|rev|charset|hreflang|dir|lang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup],-strong/-b[class|style],-em/-i[class|style],-strike[class|style],-u[class|style],#p[id|style|dir|class|align]{...}]",
19+
"Plugins": ["paste", "anchor", "charmap", "table", "lists", "advlist", "hr", "autolink", "directionality", "tabfocus", "searchreplace"],
20+
"ValidElements": "+a[id|style|rel|data-id|data-udi|rev|charset|hreflang|dir|lang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup],-strong/-b[class|style],-em/-i[class|style],-strike[class|style],-s[class|style],-u[class|style],#p[id|style|dir|class|align],-ol[class|reversed|start|style|type],-ul[class|style],-li[class|style],br[class],img[id|dir|lang|longdesc|usemap|style|class|src|onmouseover|onmouseout|border|alt=|title|hspace|vspace|width|height|align|umbracoorgwidth|umbracoorgheight|onresize|onresizestart|onresizeend|rel|data-id],-sub[style|class],-sup[style|class],-blockquote[dir|style|class],-table[border=0|cellspacing|cellpadding|width|height|class|align|summary|style|dir|id|lang|bgcolor|background|bordercolor],-tr[id|lang|dir|class|rowspan|width|height|align|valign|style|bgcolor|background|bordercolor],tbody[id|class],thead[id|class],tfoot[id|class],#td[id|lang|dir|class|colspan|rowspan|width|height|align|valign|style|bgcolor|background|bordercolor|scope],-th[id|lang|dir|class|colspan|rowspan|width|height|align|valign|style|scope],caption[id|lang|dir|class|style],-div[id|dir|class|align|style],-span[class|align|style],-pre[class|align|style],address[class|align|style],-h1[id|dir|class|align|style],-h2[id|dir|class|align|style],-h3[id|dir|class|align|style],-h4[id|dir|class|align|style],-h5[id|dir|class|align|style],-h6[id|style|dir|class|align|style],hr[class|style],small[class|style],dd[id|class|title|style|dir|lang],dl[id|class|title|style|dir|lang],dt[id|class|title|style|dir|lang],object[class|id|width|height|codebase|*],param[name|value|_value|class],embed[type|width|height|src|class|*],map[name|class],area[shape|coords|href|alt|target|class],bdo[class],button[class],iframe[*],figure,figcaption,cite,video[*],audio[*],picture[*],source[*],canvas[*]",
2121
"InvalidElements": "font",
2222
"Commands": [
2323
{

10/umbraco-cms/reference/querying/itagquery.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ description: "Working with tags in Umbraco"
77

88
# ITagQuery
99

10-
The `ITagQuery` interface is your primary way to work with tags in Umbraco, the interface allows you to get the various tags like content tags and media tags, as well as getting content by tag, for instance getting all content nodes with the "Umbraco" tag.
10+
The `ITagQuery` interface is your primary way to work with tags in Umbraco. This interface allows you to get different tags, such as content tags and media tags. It also lets you retrieve content by tag, for instance, getting all content nodes with the "Umbraco" tag.
1111

1212
## How to reference ITagQuery
1313

@@ -49,7 +49,7 @@ namespace UmbracoHelperDocs.Controllers
4949
```
5050

5151
{% hint style="warning" %}
52-
`ITagQuery` is a scoped service, meaning that it should only be injected into scoped or transient services, for more information see the official [Microsoft Documentation](https://docs.microsoft.com/en-us/dotnet/core/extensions/dependency-injection#scoped)
52+
`ITagQuery` is a scoped service, meaning that it should only be injected into scoped or transient services. For more information see the official [Microsoft Documentation](https://docs.microsoft.com/en-us/dotnet/core/extensions/dependency-injection#scoped)
5353
{% endhint %}
5454

5555
## Examples
@@ -58,7 +58,7 @@ All examples are from a view using the injection shown above, but working with t
5858

5959
### GetAllContentTags([string tagGroup])
6060

61-
Get a collection of tags used by content items on the site, you can optionally pass in a group name to only list tags belonging to a specific tag group
61+
Get a collection of tags used by content items on the site. Optionally, you can pass in a group name to only list tags belonging to a specific tag group
6262

6363
```csharp
6464
@{
@@ -69,7 +69,7 @@ Get a collection of tags used by content items on the site, you can optionally p
6969

7070
### GetAllMediaTags([string tagGroup])
7171

72-
Get a collection of tags used by media items on the site, you can optionally pass in a group name to only list tags belonging to a specific tag group
72+
Get a collection of tags used by media items on the site. Optionally, you can pass in a group name to only list tags belonging to a specific tag group
7373

7474
```csharp
7575
@{
@@ -80,7 +80,7 @@ Get a collection of tags used by media items on the site, you can optionally pas
8080

8181
### GetAllMemberTags([string tagGroup])
8282

83-
Get a collection of tags used by members on the site, you can optionally pass in a group name to only list tags belonging to a specific tag group
83+
Get a collection of tags used by members on the site. Optionally, you can pass in a group name to only list tags belonging to a specific tag group
8484

8585
```csharp
8686
@{
@@ -91,7 +91,7 @@ Get a collection of tags used by members on the site, you can optionally pass in
9191

9292
### GetAllTags([string tagGroup])
9393

94-
Get a collection of tags used on the site, you can optionally pass in a group name to only list tags belonging to a specific tag group
94+
Get a collection of tags used on the site. Optionally, you can pass in a group name to only list tags belonging to a specific tag group
9595

9696
```csharp
9797
@{
@@ -152,7 +152,7 @@ Get a collection of tags by entity id (queries content, media and members), and
152152

153153
### GetTagsForProperty(int contentId, string propertyTypeAlias, [string tagGroup])
154154

155-
Get a collection of tags assigned to a property of an entity (queries content, media and members), and you can optionally filter by tag group as well
155+
Get a collection of tags assigned to a property of an entity (queries content, media and members). Optionally, you can filter by tag group as well
156156

157157
```csharp
158158
@{

10/umbraco-cms/tutorials/multilanguage-setup.md

Lines changed: 107 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
---
2-
meta.Title: Multilanguage setup in Umbraco
3-
product: CMS
42
description: A guide to multilanguage setup in Umbraco
53
---
64

75
# Creating a Multilingual Site
86

9-
You can use **language variants** to setup a multilingual site. **Language Variants** allow you to have variants of the same content all under the same project. So, if you open a page and a language variant is enabled, you will see the option to switch the language from the drop-down list. Additionally, you can view or input the translated content.
7+
You can use **language variants** to set up a multilingual site. **Language Variants** allow you to have variants of the same content all under the same project. So, if you open a page and a language variant is enabled, you will see the option to switch the language from the drop-down list. Additionally, you can view or input the translated content.
108

11-
This tutorial explains how to set-up a basic multilingual website.
9+
This tutorial explains how to set up a basic multilingual website.
1210

1311
## Adding a New language
1412

@@ -226,3 +224,108 @@ For viewing purposes, I've added a stylesheet to my website. The final result sh
226224
**German Version:**
227225

228226
<figure><img src="images/final-result-da.png" alt=""><figcaption></figcaption></figure>
227+
228+
## Using Multiple languages across APIs
229+
230+
When requesting content over an API, the culture will fall back to the default, unless explicitly set.
231+
232+
To do this, you can use the IVariationContextAccessor.
233+
234+
```csharp
235+
public class ExampleController : SurfaceController
236+
{
237+
private readonly ILocalizationService _localizationService;
238+
private readonly IVariationContextAccessor _variationContextAccessor;
239+
240+
public ExampleController(IUmbracoContextAccessor umbracoContextAccessor, IUmbracoDatabaseFactory databaseFactory, ServiceContext services, AppCaches appCaches, IProfilingLogger profilingLogger, IPublishedUrlProvider publishedUrlProvider, ILocalizationService localizationService, IVariationContextAccessor variationContextAccessor) : base(umbracoContextAccessor, databaseFactory, services, appCaches, profilingLogger, publishedUrlProvider)
241+
{
242+
_localizationService = localizationService;
243+
_variationContextAccessor = variationContextAccessor;
244+
}
245+
246+
public IActionResult Index(string culture = null)
247+
{
248+
IEnumerable<ILanguage> UmbracoLanguages = _localizationService.GetAllLanguages(); //a helpful method to get all configured languages
249+
var requestedCulture = UmbracoLanguages.FirstOrDefault(l => l.IsoCode == culture);
250+
251+
if (requestedCulture != null)
252+
{
253+
_variationContextAccessor.VariationContext = new VariationContext(requestedCulture.IsoCode);
254+
}
255+
256+
//this will now be in the requested culture
257+
var content = UmbracoContext.Content.GetAtRoot();
258+
259+
//Content requested in this View Component will now be in the requested culture
260+
return ViewComponent();
261+
}
262+
}
263+
```
264+
265+
### Creating a Language Switching Navigation
266+
267+
To navigate between languages, we need to do two key things:
268+
269+
1. Get all the languages that the site can provide
270+
2. Identify the language used on the current page
271+
272+
Once you have these, you need to loop through the languages and provide links to each home node.
273+
274+
### Getting all the languages for a site
275+
276+
There are two ways to achieve this. One is to use `localizationService.GetAllLanguages();` to call the database, which is expensive and ideally includes caching.
277+
278+
The alternative is to get the Home node and find all cultures associated with it. This has a few benefits including speed and providing us with a link to show the user. It is the process you will use when following this guide.
279+
280+
### Identify the language for the current page
281+
282+
This is achieved in `cs.html` files using `umbracoHelper.AssignedContentItem.GetCultureFromDomains();`.
283+
284+
#### Steps
285+
286+
Now that you have what you need, take the following steps to create a working example.
287+
288+
1. Create a new view called `Navigation.cshtml`
289+
2. Paste in the following code:
290+
291+
```cshtml
292+
@using Umbraco.Cms.Web.Common
293+
@inject IUmbracoHelperAccessor _umbracoHelperAccessor;
294+
295+
@{
296+
_umbracoHelperAccessor.TryGetUmbracoHelper(out var umbracoHelper);
297+
298+
var homePage = umbracoHelper.ContentAtRoot().FirstOrDefault(c => c.ContentType.Alias == "{{homeNodeContentAlias}}");
299+
var cultures = homePage?.Cultures;
300+
}
301+
302+
@if (cultures.Count > 1)
303+
{
304+
<ul aria-label="Language switcher">
305+
@foreach (var cult in cultures)
306+
{
307+
//get the settings for this culture
308+
System.Globalization.CultureInfo culture = new System.Globalization.CultureInfo(cult.Key);
309+
//if the current page has a language variant, otherwise link to the homepage language variant
310+
string langUrl = umbracoHelper.AssignedContentItem.Url(cult.Key, UrlMode.Relative) ?? homePage.Url(cult.Key, UrlMode.Relative);
311+
312+
<li>
313+
@if (cult.Key.ToLower() == umbracoHelper.AssignedContentItem.GetCultureFromDomains().ToLower())
314+
{
315+
<span aria-current="true" >@culture.NativeName</span>
316+
}
317+
else
318+
{
319+
<a href="@langUrl" hreflang="@cult.Key" lang="@cult.Key" >@culture.NativeName</a>
320+
}
321+
</li>
322+
}
323+
</ul>
324+
}
325+
```
326+
327+
3. Replace `{{homeNodeContentAlias}}` with the Document Type alias of your Home node.
328+
329+
This will render links to either the language variant of the current page or the home node for the language variant.
330+
331+
Additionally, `System.Globalization.CultureInfo` is used to obtain the native name of the language being rendered. This is useful if a user does not speak the default language.

0 commit comments

Comments
 (0)