Skip to content
Merged
119 changes: 20 additions & 99 deletions .github/README.md
Original file line number Diff line number Diff line change
@@ -1,114 +1,35 @@
# jcdcdev.Umbraco.ReadingTime

[![Umbraco Marketplace](https://img.shields.io/badge/Umbraco-Marketplace-%233544B1?style=flat&logo=umbraco)](https://marketplace.umbraco.com/package/jcdcdev.umbraco.readingtime)
[![GitHub License](https://img.shields.io/github/license/jcdcdev/jcdcdev.Umbraco.ReadingTime?color=8AB803&label=License&logo=github)](https://github.com/jcdcdev/jcdcdev.Umbraco.ReadingTime/blob/main/LICENSE)
[![NuGet Downloads](https://img.shields.io/nuget/dt/jcdcdev.Umbraco.ReadingTime?color=cc9900&label=Downloads&logo=nuget)](https://www.nuget.org/packages/jcdcdev.Umbraco.ReadingTime/)
[![Umbraco Marketplace](https://img.shields.io/badge/Umbraco-Marketplace-%233544B1?style=flat&logo=umbraco)](https://marketplace.umbraco.com/package/jcdcdev.Umbraco.ReadingTime)
[![License](https://img.shields.io/github/license/jcdcdev/jcdcdev.Umbraco.ReadingTime?color=8AB803&label=License&logo=github)](https://github.com/jcdcdev/jcdcdev.Umbraco.ReadingTime?tab=MIT-1-ov-file)
[![NuGet Downloads](https://img.shields.io/nuget/dt/jcdcdev.Umbraco.ReadingTime?color=cc9900&label=Downloads&logo=nuget)](https://www.nuget.org/packages/jcdcdev.Umbraco.ReadingTime)
[![Project Website](https://img.shields.io/badge/Project%20Website-jcdc.dev-jcdcdev?style=flat&color=3c4834&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgZmlsbD0id2hpdGUiIGNsYXNzPSJiaSBiaS1wYy1kaXNwbGF5IiB2aWV3Qm94PSIwIDAgMTYgMTYiPgogIDxwYXRoIGQ9Ik04IDFhMSAxIDAgMCAxIDEtMWg2YTEgMSAwIDAgMSAxIDF2MTRhMSAxIDAgMCAxLTEgMUg5YTEgMSAwIDAgMS0xLTF6bTEgMTMuNWEuNS41IDAgMSAwIDEgMCAuNS41IDAgMCAwLTEgMG0yIDBhLjUuNSAwIDEgMCAxIDAgLjUuNSAwIDAgMC0xIDBNOS41IDFhLjUuNSAwIDAgMCAwIDFoNWEuNS41IDAgMCAwIDAtMXpNOSAzLjVhLjUuNSAwIDAgMCAuNS41aDVhLjUuNSAwIDAgMCAwLTFoLTVhLjUuNSAwIDAgMC0uNS41TTEuNSAyQTEuNSAxLjUgMCAwIDAgMCAzLjV2N0ExLjUgMS41IDAgMCAwIDEuNSAxMkg2djJoLS41YS41LjUgMCAwIDAgMCAxSDd2LTRIMS41YS41LjUgMCAwIDEtLjUtLjV2LTdhLjUuNSAwIDAgMSAuNS0uNUg3VjJ6Ii8+Cjwvc3ZnPg==)](https://jcdc.dev/umbraco-packages/reading-time)

Custom Data Type for calculating reading time. With full variant support!

The following editors are currently supported:

- Rich Text
- Markdown
- Block Grid
- Block List
- Nested Content
- Textstring
Custom Data Type for calculating reading time. With full variant support!

The following editors are currently supported:

- Rich Text
- Markdown
- Block Grid
- Block List
- Nested Content
- Textstring
- Textarea

## Quick Start

1. Install the [NuGet package](https://www.nuget.org/packages/jcdcdev.Umbraco.ReadingTime) in your Umbraco CMS website project.
```
dotnet add package jcdcdev.Umbraco.ReadingTime
```
2. Add the Reading Time data type to a document type. You can configure:
- `Words per minute` (default is 200)
- `Min Unit` (default is Minute)
- `Max Unit` (default is Minute)
![A screenshot of the BackOffice showing Reading Time data type](https://raw.githubusercontent.com/jcdcdev/jcdcdev.Umbraco.ReadingTime/main/docs/screenshots/datatype.png)
3. Save and publish content.
4. Reading Time will display in the backoffice

![A screenshot of the BackOffice showing Reading Time](https://raw.githubusercontent.com/jcdcdev/jcdcdev.Umbraco.ReadingTime/main/docs/screenshots/backoffice.png)

## Using the value in your templates

In your template, you can accessing the Reading Time property value like any other property:

```html
@Model.ReadingTime.DisplayTime()
```

![A screenshot of page showing Reading Time](https://raw.githubusercontent.com/jcdcdev/jcdcdev.Umbraco.ReadingTime/main/docs/screenshots/displaytime.png)

### Overriding the default display
The `DisplayTime` method will format the reading time as a string using [Humanizer](https://github.com/Humanizr/Humanizer). This supports variants, meaning the reading time will be displayed based on the pluralisation rules of the current culture (e.g. "1 minute", "2 minutes", "0 minuter").

Min and max `TimeUnit` values are derived from the Data Type settings. The below example shows how you can ensure only seconds are displayed.

```csharp
Model.ReadingTime.DisplayTime(minUnit: TimeUnit.Second, maxUnit: TimeUnit.Second)
```

## Configuration

You can change the average words per minute in the data type settings.
> [!WARNING]
> Version 14 is no longer supported and is End of Life (EOL).

When creating a new data type, the default will be 200 words per minute.
> Please review the [security policy](https://github.com/jcdcdev/jcdcdev.Umbraco.ReadingTime?tab=security-ov-file#supported-versions) for more information.

## Limitations

**Values are derived from published content only.**

Unpublished (saved) content is _not_ included in the calculation.

**Words per minute applies to all variants.**

It is not currently possible to configure words per minute per culture.

## Extending

You can extend the data type to support additional editors by implementing the `IReadingTimeValueProvider` interface.

```csharp
public class MyCustomReadingTimeValueProvider : IReadingTimeValueProvider
{
public bool CanConvert(IPropertyType type)
{
return type.EditorAlias == "MyCustomEditorAlias";
}

public TimeSpan? GetReadingTime(IProperty property, string? culture, string? segment, IEnumerable<string> availableCultures, ReadingTimeConfiguration config)
{
var value = property.GetValue(culture, segment, true);
if (value is string text)
{
return text.GetReadingTime(config.WordsPerMinute);
}

return null;
}
}
```
## Contributing

Don't forget to register your custom value provider:
Contributions to this package are most welcome! Please visit the [Contributing](https://github.com/jcdcdev/jcdcdev.Umbraco.ReadingTime/contribute) page.

```csharp
public class Composer : IComposer
{
public void Compose(IUmbracoBuilder builder)
{
builder.ReadingTimeValueProviders().Append<MyCustomReadingTimeValueProvider>();
}
}
```
## Acknowledgements (Thanks)

## Contributing
- LottePitcher - [opinionated-package-starter](https://github.com/LottePitcher/opinionated-package-starter)

Contributions to this package are most welcome! Please read the [Contributing Guidelines](https://github.com/jcdcdev/jcdcdev.Umbraco.ReadingTime/blob/main/.github/CONTRIBUTING.md).

## Acknowledgments (thanks!)

- LottePitcher - [opinionated-package-starter](https://github.com/LottePitcher/opinionated-package-starter)
62 changes: 62 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Security Policy

## Supported Versions

The following table outlines the versions of the project that are currently supported with security & feature updates:

> [!NOTE]
> Once a version starts its security phase, it will no longer receive feature updates. Only critical bug fixes and security updates will be provided.

| Package Version | Umbraco Version | Security Phase Start | End of Life |
| ---------------------------------------------------------------------------------- | --------------- | -------------------- | ----------- |
| [10.x](https://github.com/jcdcdev/jcdcdev.Umbraco.ReadingTime/tree/v10) | 10 | 2024-06-16 | 2025-06-16 |
| [13.x](https://github.com/jcdcdev/jcdcdev.Umbraco.ReadingTime/tree/v13) | 13 | 2025-12-14 | 2026-12-14 |
| [15.x](https://github.com/jcdcdev/jcdcdev.Umbraco.ReadingTime/tree/v15) | 15 | 2025-08-14 | 2025-11-14 |
## Unsupported Versions

| Package Version | Umbraco Version | End of Life |
| ---------------------------------------------------------------------------------- | --------------- | ----------- |
| [12.x](https://github.com/jcdcdev/jcdcdev.Umbraco.ReadingTime/tree/v12) | 12 | 2024-06-29 |
| [14.x](https://github.com/jcdcdev/jcdcdev.Umbraco.ReadingTime/tree/v14) | 14 | 2025-05-30 |


## Future Support

Project maintainers plan to support all STS (Short-Term Support) and LTS (Long-Term Support) versions of Umbraco. However, exact release dates cannot be guaranteed.

> [!NOTE]
> Visit [jcdc.dev/blog/umbraco-version-information](https://jcdc.dev/blog/umbraco-version-information) for more information on Umbraco versions.

## Reporting a Vulnerability

If you discover a vulnerability in this project, please follow one of these steps to report it:

- Create an [issue](https://github.com/jcdcdev/jcdcdev.Umbraco.ReadingTime/security/advisories/new)
- Contact the project author privately at [jcdc.dev/contact](https://jcdc.dev/contact)

### Details

Include as much information as possible about the vulnerability, including:

- Steps to reproduce
- Potential impact
- Any suggested fixes

### Acknowledgment

You will receive an acknowledgment of your report as soon as possible.

> [!NOTE]
> Response times may vary depending on other commitments.

### Resolution

Once the vulnerability is confirmed, project maintainers will work to resolve it as quickly as possible.

You will be notified once the issue has been resolved or rejected.

> [!TIP]
> If the vulnerability is accepted, you will receive credit in the release notes.

Thank you for helping to keep this project secure!

63 changes: 47 additions & 16 deletions docs/README_nuget.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,58 @@
# jcdcdev.Umbraco.ReadingTime

[![Documentation](https://img.shields.io/badge/Docs-Quickstart-394933?style=flat&logo=github)](https://github.com/jcdcdev/jcdcdev.Umbraco.ReadingTime/tree/main?tab=readme-ov-file#quick-start)
[![Umbraco Marketplace](https://img.shields.io/badge/Umbraco-Marketplace-%233544B1?style=flat&logo=umbraco)](https://marketplace.umbraco.com/package/jcdcdev.umbraco.readingtime)
[![GitHub License](https://img.shields.io/github/license/jcdcdev/jcdcdev.Umbraco.ReadingTime?color=8AB803&label=License&logo=github)](https://github.com/jcdcdev/jcdcdev.Umbraco.ReadingTime/blob/main/LICENSE)
[![NuGet Downloads](https://img.shields.io/nuget/dt/jcdcdev.Umbraco.ReadingTime?color=cc9900&label=Downloads&logo=nuget)](https://www.nuget.org/packages/jcdcdev.Umbraco.ReadingTime/)
[![Documentation](https://img.shields.io/badge/Docs-Quickstart-394933?style=flat&logo=github)](https://github.com/jcdcdev/jcdcdev.Umbraco.ReadingTime/#quick-start)
[![Umbraco Marketplace](https://img.shields.io/badge/Umbraco-Marketplace-%233544B1?style=flat&logo=umbraco)](https://marketplace.umbraco.com/package/jcdcdev.Umbraco.ReadingTime)
[![License](https://img.shields.io/github/license/jcdcdev/jcdcdev.Umbraco.ReadingTime?color=8AB803&label=License&logo=github)](https://github.com/jcdcdev/jcdcdev.Umbraco.ReadingTime?tab=MIT-1-ov-file)
[![NuGet Downloads](https://img.shields.io/nuget/dt/jcdcdev.Umbraco.ReadingTime?color=cc9900&label=Downloads&logo=nuget)](https://www.nuget.org/packages/jcdcdev.Umbraco.ReadingTime)
[![Project Website](https://img.shields.io/badge/Project%20Website-jcdc.dev-jcdcdev?style=flat&color=3c4834&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgZmlsbD0id2hpdGUiIGNsYXNzPSJiaSBiaS1wYy1kaXNwbGF5IiB2aWV3Qm94PSIwIDAgMTYgMTYiPgogIDxwYXRoIGQ9Ik04IDFhMSAxIDAgMCAxIDEtMWg2YTEgMSAwIDAgMSAxIDF2MTRhMSAxIDAgMCAxLTEgMUg5YTEgMSAwIDAgMS0xLTF6bTEgMTMuNWEuNS41IDAgMSAwIDEgMCAuNS41IDAgMCAwLTEgMG0yIDBhLjUuNSAwIDEgMCAxIDAgLjUuNSAwIDAgMC0xIDBNOS41IDFhLjUuNSAwIDAgMCAwIDFoNWEuNS41IDAgMCAwIDAtMXpNOSAzLjVhLjUuNSAwIDAgMCAuNS41aDVhLjUuNSAwIDAgMCAwLTFoLTVhLjUuNSAwIDAgMC0uNS41TTEuNSAyQTEuNSAxLjUgMCAwIDAgMCAzLjV2N0ExLjUgMS41IDAgMCAwIDEuNSAxMkg2djJoLS41YS41LjUgMCAwIDAgMCAxSDd2LTRIMS41YS41LjUgMCAwIDEtLjUtLjV2LTdhLjUuNSAwIDAgMSAuNS0uNUg3VjJ6Ii8+Cjwvc3ZnPg==)](https://jcdc.dev/umbraco-packages/reading-time)

Custom Data Type for calculating reading time. With full variant support!

The following editors are currently supported:

- Rich Text
- Markdown
- Block Grid
- Block List
- Nested Content
- Textstring
Custom Data Type for calculating reading time. With full variant support!

The following editors are currently supported:

- Rich Text
- Markdown
- Block Grid
- Block List
- Nested Content
- Textstring
- Textarea

## Quick Start

1. Install the [NuGet package](https://www.nuget.org/packages/jcdcdev.Umbraco.ReadingTime) in your Umbraco CMS website project.
```
dotnet add package jcdcdev.Umbraco.ReadingTime
```
2. Add the Reading Time data type to a document type. You can configure:
- `Words per minute` (default is 200)
- `Min Unit` (default is Minute)
- `Max Unit` (default is Minute)
3. Save and publish content.
4. Reading Time will display in the backoffice

### Using the value in your templates

In your template, you can accessing the Reading Time property value like any other property:

```html
@Model.ReadingTime.DisplayTime()
```

## Configuration

You can change the average words per minute in the data type settings.

When creating a new data type, the default will be 200 words per minute.

## Contributing

Contributions to this package are most welcome! Please read the [Contributing Guidelines](https://github.com/jcdcdev/jcdcdev.Umbraco.ReadingTime/blob/main/.github/CONTRIBUTING.md).
Contributions to this package are most welcome! Please visit the [Contributing](https://github.com/jcdcdev/jcdcdev.Umbraco.ReadingTime/contribute) page.

## Acknowledgements (Thanks)

- LottePitcher - [opinionated-package-starter](https://github.com/LottePitcher/opinionated-package-starter)


## Acknowledgments (thanks!)

- LottePitcher - [opinionated-package-starter](https://github.com/LottePitcher/opinionated-package-starter)
13 changes: 7 additions & 6 deletions src/jcdcdev.Umbraco.ReadingTime.Client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/jcdcdev.Umbraco.ReadingTime.Client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"@hey-api/openapi-ts": "^0.66.5",
"@umbraco-cms/backoffice": "^14.3.3",
"typescript": "^5.8.3",
"vite": "^6.3.2"
"vite": "^6.3.5"
},
"volta": {
"node": "20.9.0"
Expand Down
Loading