Skip to content
Merged

v17 #86

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
5e42a2a
merge (#70)
thientu995 Jan 27, 2026
4a7482c
Merge pull request #72 from T4VN/v16/release
thientu995 Jan 27, 2026
4e35e5e
Sync wiki at Tue Jan 27 09:50:25 UTC 2026
invalid-email-address Jan 27, 2026
3abc857
s (#76)
thientu995 Jan 27, 2026
1654d4d
Merge pull request #74 from T4VN/gh-pages-wiki-sync-20260127-095025
thientu995 Jan 27, 2026
68489d7
Merge pull request #78 from T4VN/gh-pages
thientu995 Jan 27, 2026
a278333
Merge pull request #79 from T4VN/main
thientu995 Jan 27, 2026
7744bef
Merge pull request #80 from T4VN/v16/release
thientu995 Jan 27, 2026
aab8a9b
update component introduction
thientu995 Jan 30, 2026
5106f79
update id intro to class intro
thientu995 Jan 30, 2026
9c21a90
add component intro detail
thientu995 Jan 30, 2026
54638d3
REMOVE ID
thientu995 Jan 30, 2026
a4aaef0
add component Endorsements
thientu995 Jan 30, 2026
2220e76
Merge pull request #81 from T4VN/v16/dev
thientu995 Jan 30, 2026
3c84ccc
remove button learn more
thientu995 Jan 31, 2026
5f0b322
FIX PAGE NOTFOUND
thientu995 Feb 1, 2026
2db9c14
update div and id to class
thientu995 Feb 1, 2026
f2bb31f
Support multi templates blockgrid and blocklist
thientu995 Feb 1, 2026
83158bc
update template blockgrid and blocklist
thientu995 Feb 4, 2026
bba5706
Add image to README for visual enhancement
thientu995 Feb 4, 2026
e88fd1c
Merge pull request #82 from T4VN/main
thientu995 Feb 4, 2026
dda7e78
Merge pull request #83 from T4VN/v16/release
thientu995 Feb 4, 2026
ad2409c
Merge pull request #84 from T4VN/v16/dev
thientu995 Feb 4, 2026
13a426e
V16/release (#85)
thientu995 Feb 4, 2026
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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
**uTPro** is a powerful **Starter Kit Template** built to **accelerate website development on the Umbraco platform**.
It enables developers to create **enterprise‑grade websites** faster, more reliably, and with a professional structure from day one.

<img width="1200" height="297" alt="image" src="https://github.com/user-attachments/assets/41cd2a67-8bc1-40ca-a689-3db1bcee1b24" />

---

## 🔑 Core Principles
Expand Down
54 changes: 54 additions & 0 deletions docs/1.-Intro.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# <img width="50" height="50" alt="Logo" src="https://github.com/user-attachments/assets/09bd91e7-76d6-4223-8ffe-60b3c9cde3b0" /> uTPro – Umbraco Turbo Pro
## For developers, by developers

**uTPro** is a powerful **Starter Kit Template** built to **accelerate website development on the Umbraco platform**.
It enables developers to create **enterprise‑grade websites** faster, more reliably, and with a professional structure from day one.

---

## 🔑 Core Principles

- **Umbraco Turbo Pro**
Speed up Umbraco development with a streamlined, production‑ready foundation that ensures stability and scalability.

- **Universal Template Project**
A flexible, ready‑to‑use structure that adapts to multiple use cases: enterprise websites, product showcases, landing pages, and more.

- **Ultimate Tech Productivity**
Reduce repetitive setup tasks, maximize efficiency, and let developers focus on delivering real value instead of boilerplate work.

---

## 🚀 Why uTPro?

- **Fast to start** – Launch projects in minutes with a clean, optimized base.
- **Flexible** – Easily customize to fit unique business or creative needs.
- **Scalable** – Built to support both small projects and enterprise‑level solutions.
- **Free & Open Source** – 100% customizable, extendable, and community‑driven.

---

## 🌐 Perfect for

- Corporate websites and enterprise portals
- Product landing pages and marketing campaigns
- Developer teams who want a consistent, professional starting point
- Agencies looking to deliver faster without sacrificing quality

---

## ⚙️ Pre‑installed Utilities

uTPro comes with a curated set of utilities and best practices already integrated, so you can start building immediately:

- **Pre‑configured build scripts** (minification, bundling, cache‑busting).
- **SEO‑friendly meta setup** and Open Graph defaults.
- **Accessibility helpers** to ensure inclusive design.
- **Performance optimizations** (lazy loading, async scripts, caching hints).
- **Sample components** (navigation, footer, hero section) ready to customize.

**With the support of extensions:** [Smidge](https://github.com/Shazwazza/Smidge), [UmbracoSeoVisualizer](https://marketplace.umbraco.com/package/umbracoseovisualizer), [Umbraco.Community.BlockPreview](https://marketplace.umbraco.com/package/umbraco.community.blockpreview), [uSync](https://marketplace.umbraco.com/package/usync), [WebMarkupMin.AspNetCoreLatest](https://www.nuget.org/packages/WebMarkupMin.AspNetCoreLatest/), [LigerShark.WebOptimizer.Core](https://www.nuget.org/packages/LigerShark.WebOptimizer.Core)...

---

uTPro is **completely free and open source**, giving developers the freedom to **customize, extend, and innovate without limits**.
40 changes: 40 additions & 0 deletions docs/2.-Setup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# 2.1 Setup Domain
In addition to the configurations used for Umbraco, we also provide other configurations for backoffice and language customization:

<img width="322" height="90" alt="image" src="https://github.com/user-attachments/assets/e9317805-d459-424c-a3d0-2a7b0e32b4a7" />

If you want to use multi site or configure separate backoffice, please update the **hosts file** according to each operating system.

* For Windows: C:\Windows\System32\Drivers\etc\hosts)
* For MacOS and Linux: /etc/hosts

<img width="606" height="488" alt="image" src="https://github.com/user-attachments/assets/fb6a735d-f1bd-4657-a473-bb2702dc5781" />

---
# 2.2 Setup Project
Setting up uTPro is simple. Once you have downloaded the source code, you can open the project solution file in Visual Studio. We recommend using Visual Studio 2022 (or later).

<img width="260" height="138" alt="image" src="https://github.com/user-attachments/assets/a3075e3f-7ddd-4dba-a891-924ea3cab723" />

Then follow the minimum requirements of the Umbraco CMS project:

* Database: SQL Server (Please change the ConnectionString in the appsettings.json with key: **umbracoDbDSN** => create an **empty database** on SQL Server. Then use the database name you created and edit it in **appsettings**.

<img width="177" height="80" alt="image" src="https://github.com/user-attachments/assets/e11e9a72-fd0d-4206-a287-602c5b7a4701" />).

<img width="954" height="124" alt="image" src="https://github.com/user-attachments/assets/8b9a772a-5d6c-492b-a3c0-1aaadfdd2585" />

* Target framework: .NET 9 (Changes depending on the Umbraco version in use)

<img width="847" height="307" alt="image" src="https://github.com/user-attachments/assets/ffd40c2a-a951-4910-8350-3c91ee1450db" />

---
# 2.3 Setup Data
The project has been integrated with data, and you can use **uSync to synchronize data** after installing Umbraco CMS.

<img width="800" alt="image" src="https://github.com/user-attachments/assets/288360f8-c34f-42c9-8098-3d9436c03e7f" />

In the "Everything" group, select "Import" and wait for the results, then refresh the page, return to the "Content" tab to check the results.

<img width="502" height="269" alt="image" src="https://github.com/user-attachments/assets/b0e66bf7-e4ea-4f5f-be43-e3259c37939b" />

12 changes: 12 additions & 0 deletions docs/3.-Project-Structure.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
uTPro is developed in modular fashion. In this section we will go into details of each module and inner workings of its structure.

This is an empty Project structure with no specialized features created yet:

<img width="249" height="301" alt="image" src="https://github.com/user-attachments/assets/df9f411a-639e-4c9f-ab61-83e872d5145f" />

# 3.1 uTPro.Web
# 3.2 uTPro.Configure
# 3.3 uTPro.Common
# 3.4 uTPro.Extension
# 3.5 uTPro.Foundation
# 3.6 uTPro.Feature (Optional)
19 changes: 19 additions & 0 deletions docs/4.-Configurations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
In addition to the configurations used for Umbraco, we also provide other configurations for backoffice and language customization:

# 4.1 Configuration Remember Language - Culture and Hostnames
We do provide multilingual configuration by **cookie**. This defaults Umbraco to support multilingual only! You can find our **"Culture and Hostnames"** settings in the "Home" node (_**uTPro -> Sites -> Home**_)

<img width="922" height="554" alt="image" src="https://github.com/user-attachments/assets/ee51eba4-9738-493e-ba79-4d33a150fb60" />

**IMPORTANT:** Make sure that the default language (first access user has no cookie and url has no language set) is set to END "/" by default and set it to the last position (In the picture we are using Vietnamese as the default language). Make sure each language has a hostname for Remember Language to work properly.

You can disable this feature by setting **Enabled: "false"** for **RememberLanguage**:

<img width="405" height="144" alt="image" src="https://github.com/user-attachments/assets/e41601ea-39bc-46cb-8c37-1c158c10adb3" />

# 4.2 Configuration Backoffice and Website run separately
You can separate Backoffice and Website into 2 separate domains, if you have enabled and configured the domain for Backoffice, try accessing the Website domain and "/umbraco" to see the result.

<img width="308" height="96" alt="image" src="https://github.com/user-attachments/assets/a031509d-06aa-4458-964d-f46c6d075ef7" />


8 changes: 8 additions & 0 deletions docs/_Footer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
✍️ **Author**: Nguyễn Thiên Tứ
📬 **Contact**: [thientu@t4vn.com](mailto:thientu@t4vn.com)
📄 **Website**: [t4vn.com](https://t4vn.com)
📦 **Repository**: [github.com/T4VN/uTPro](https://github.com/T4VN/uTPro)
📍 **Location**: Ho Chi Minh City, VietNam
🕒 Timezone: GMT+7
✨ **SPECIAL**: We also offer a **LOW COST PREMIUM** version for those who want exclusive customization tailored to their personal style. Your support means a lot to us!
16 changes: 8 additions & 8 deletions uTPro/Common/uTPro.Common/Models/CMS/File.generated.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// <auto-generated>
// This code was generated by a tool.
//
// Umbraco.ModelsBuilder.Embedded v16.4.1+3472ff9
// Umbraco.ModelsBuilder.Embedded v16.5.0+8b2c22a
//
// Changes to this file will be lost if the code is regenerated.
// </auto-generated>
Expand All @@ -24,15 +24,15 @@ public partial class File : PublishedContentModel
{
// helpers
#pragma warning disable 0109 // new is redundant
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.4.1+3472ff9")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.5.0+8b2c22a")]
public new const string ModelTypeAlias = "File";
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.4.1+3472ff9")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.5.0+8b2c22a")]
public new const PublishedItemType ModelItemType = PublishedItemType.Media;
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.4.1+3472ff9")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.5.0+8b2c22a")]
[return: global::System.Diagnostics.CodeAnalysis.MaybeNull]
public new static IPublishedContentType GetModelContentType(IPublishedContentTypeCache contentTypeCache)
=> PublishedModelUtility.GetModelContentType(contentTypeCache, ModelItemType, ModelTypeAlias);
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.4.1+3472ff9")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.5.0+8b2c22a")]
[return: global::System.Diagnostics.CodeAnalysis.MaybeNull]
public static IPublishedPropertyType GetModelPropertyType<TValue>(IPublishedContentTypeCache contentTypeCache, Expression<Func<File, TValue>> selector)
=> PublishedModelUtility.GetModelPropertyType(GetModelContentType(contentTypeCache), selector);
Expand All @@ -52,22 +52,22 @@ public File(IPublishedContent content, IPublishedValueFallback publishedValueFal
///<summary>
/// File size
///</summary>
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.4.1+3472ff9")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.5.0+8b2c22a")]
[ImplementPropertyType("umbracoBytes")]
public virtual long UmbracoBytes => this.Value<long>(_publishedValueFallback, "umbracoBytes");

///<summary>
/// File extension
///</summary>
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.4.1+3472ff9")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.5.0+8b2c22a")]
[global::System.Diagnostics.CodeAnalysis.MaybeNull]
[ImplementPropertyType("umbracoExtension")]
public virtual string UmbracoExtension => this.Value<string>(_publishedValueFallback, "umbracoExtension");

///<summary>
/// File
///</summary>
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.4.1+3472ff9")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.5.0+8b2c22a")]
[global::System.Diagnostics.CodeAnalysis.MaybeNull]
[ImplementPropertyType("umbracoFile")]
public virtual string UmbracoFile => this.Value<string>(_publishedValueFallback, "umbracoFile");
Expand Down
10 changes: 5 additions & 5 deletions uTPro/Common/uTPro.Common/Models/CMS/Folder.generated.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// <auto-generated>
// This code was generated by a tool.
//
// Umbraco.ModelsBuilder.Embedded v16.4.1+3472ff9
// Umbraco.ModelsBuilder.Embedded v16.5.0+8b2c22a
//
// Changes to this file will be lost if the code is regenerated.
// </auto-generated>
Expand All @@ -24,15 +24,15 @@ public partial class Folder : PublishedContentModel
{
// helpers
#pragma warning disable 0109 // new is redundant
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.4.1+3472ff9")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.5.0+8b2c22a")]
public new const string ModelTypeAlias = "Folder";
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.4.1+3472ff9")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.5.0+8b2c22a")]
public new const PublishedItemType ModelItemType = PublishedItemType.Media;
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.4.1+3472ff9")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.5.0+8b2c22a")]
[return: global::System.Diagnostics.CodeAnalysis.MaybeNull]
public new static IPublishedContentType GetModelContentType(IPublishedContentTypeCache contentTypeCache)
=> PublishedModelUtility.GetModelContentType(contentTypeCache, ModelItemType, ModelTypeAlias);
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.4.1+3472ff9")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.5.0+8b2c22a")]
[return: global::System.Diagnostics.CodeAnalysis.MaybeNull]
public static IPublishedPropertyType GetModelPropertyType<TValue>(IPublishedContentTypeCache contentTypeCache, Expression<Func<Folder, TValue>> selector)
=> PublishedModelUtility.GetModelPropertyType(GetModelContentType(contentTypeCache), selector);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// <auto-generated>
// This code was generated by a tool.
//
// Umbraco.ModelsBuilder.Embedded v16.4.1+3472ff9
// Umbraco.ModelsBuilder.Embedded v16.5.0+8b2c22a
//
// Changes to this file will be lost if the code is regenerated.
// </auto-generated>
Expand All @@ -24,15 +24,15 @@ public partial class GlobalFolderArchives : PublishedContentModel
{
// helpers
#pragma warning disable 0109 // new is redundant
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.4.1+3472ff9")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.5.0+8b2c22a")]
public new const string ModelTypeAlias = "globalFolderArchives";
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.4.1+3472ff9")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.5.0+8b2c22a")]
public new const PublishedItemType ModelItemType = PublishedItemType.Content;
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.4.1+3472ff9")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.5.0+8b2c22a")]
[return: global::System.Diagnostics.CodeAnalysis.MaybeNull]
public new static IPublishedContentType GetModelContentType(IPublishedContentTypeCache contentTypeCache)
=> PublishedModelUtility.GetModelContentType(contentTypeCache, ModelItemType, ModelTypeAlias);
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.4.1+3472ff9")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.5.0+8b2c22a")]
[return: global::System.Diagnostics.CodeAnalysis.MaybeNull]
public static IPublishedPropertyType GetModelPropertyType<TValue>(IPublishedContentTypeCache contentTypeCache, Expression<Func<GlobalFolderArchives, TValue>> selector)
=> PublishedModelUtility.GetModelPropertyType(GetModelContentType(contentTypeCache), selector);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// <auto-generated>
// This code was generated by a tool.
//
// Umbraco.ModelsBuilder.Embedded v16.4.1+3472ff9
// Umbraco.ModelsBuilder.Embedded v16.5.0+8b2c22a
//
// Changes to this file will be lost if the code is regenerated.
// </auto-generated>
Expand All @@ -24,15 +24,15 @@ public partial class GlobalFolderNavigationLinkForSite : PublishedContentModel
{
// helpers
#pragma warning disable 0109 // new is redundant
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.4.1+3472ff9")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.5.0+8b2c22a")]
public new const string ModelTypeAlias = "globalFolderNavigationLinkForSite";
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.4.1+3472ff9")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.5.0+8b2c22a")]
public new const PublishedItemType ModelItemType = PublishedItemType.Content;
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.4.1+3472ff9")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.5.0+8b2c22a")]
[return: global::System.Diagnostics.CodeAnalysis.MaybeNull]
public new static IPublishedContentType GetModelContentType(IPublishedContentTypeCache contentTypeCache)
=> PublishedModelUtility.GetModelContentType(contentTypeCache, ModelItemType, ModelTypeAlias);
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.4.1+3472ff9")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.5.0+8b2c22a")]
[return: global::System.Diagnostics.CodeAnalysis.MaybeNull]
public static IPublishedPropertyType GetModelPropertyType<TValue>(IPublishedContentTypeCache contentTypeCache, Expression<Func<GlobalFolderNavigationLinkForSite, TValue>> selector)
=> PublishedModelUtility.GetModelPropertyType(GetModelContentType(contentTypeCache), selector);
Expand All @@ -52,7 +52,7 @@ public GlobalFolderNavigationLinkForSite(IPublishedContent content, IPublishedVa
///<summary>
/// Items
///</summary>
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.4.1+3472ff9")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.5.0+8b2c22a")]
[global::System.Diagnostics.CodeAnalysis.MaybeNull]
[ImplementPropertyType("navigationItems")]
public virtual global::Umbraco.Cms.Core.Models.Blocks.BlockListModel NavigationItems => this.Value<global::Umbraco.Cms.Core.Models.Blocks.BlockListModel>(_publishedValueFallback, "navigationItems");
Expand Down
Loading
Loading