diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3ec8ef31fe..c201240f67 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,3 +1,5 @@ +_Looking for Umbraco version 8? [Click here](https://github.com/umbraco/Umbraco-CMS/blob/temp8/CONTRIBUTING.md) to go to the v8 branch_ + # Contributing to Umbraco CMS 👍🎉 First off, thanks for taking the time to contribute! 🎉👍 diff --git a/README.md b/README.md index f7e6089198..70b9759bbe 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ _Looking for Umbraco version 7? [Click here](https://github.com/umbraco/Umbraco- __Ready to try out Version 8? [See the quick start guide](https://github.com/umbraco/Umbraco-CMS/blob/temp8/V8_GETTING_STARTED.md).__ +_Looking for Umbraco version 8? [Click here](https://github.com/umbraco/Umbraco-CMS/tree/temp8) to go to the v8 branch_ + Umbraco CMS =========== The friendliest, most flexible and fastest growing ASP.NET CMS used by more than 443,000 websites worldwide: [https://umbraco.com](https://umbraco.com) @@ -13,7 +15,7 @@ Umbraco is a free open source Content Management System built on the ASP.NET pla ## Watch an introduction video -[![ScreenShot](http://umbraco.com/images/whatisumbraco.png)](https://umbraco.tv/videos/umbraco-v7/content-editor/basics/introduction/cms-explanation/) +[![ScreenShot](https://shop.umbraco.com/images/whatisumbraco.png)](https://umbraco.tv/videos/umbraco-v7/content-editor/basics/introduction/cms-explanation/) ## Umbraco - The Friendly CMS diff --git a/V8_GETTING_STARTED.md b/V8_GETTING_STARTED.md index 3c954091f8..c5e20d2a1c 100644 --- a/V8_GETTING_STARTED.md +++ b/V8_GETTING_STARTED.md @@ -15,7 +15,7 @@ * When the website starts you'll see the Umbraco installer and just follow the prompts * Your all set! -### Wan't to run from a zip instead? +### Want to run from a zip instead? If you just want to try out a few things, you can run the site from a zip file which you can download from here https://github.com/umbraco/Umbraco-CMS/releases/tag/temp8-cg18. diff --git a/src/Umbraco.Core/Persistence/Dtos/ContentDto.cs b/src/Umbraco.Core/Persistence/Dtos/ContentDto.cs index 32e95fcc78..aae5d0d407 100644 --- a/src/Umbraco.Core/Persistence/Dtos/ContentDto.cs +++ b/src/Umbraco.Core/Persistence/Dtos/ContentDto.cs @@ -8,7 +8,7 @@ namespace Umbraco.Core.Persistence.Dtos [ExplicitColumns] internal class ContentDto { - private const string TableName = Constants.DatabaseSchema.Tables.Content; + public const string TableName = Constants.DatabaseSchema.Tables.Content; [Column("nodeId")] [PrimaryKeyColumn(AutoIncrement = false)] diff --git a/src/Umbraco.Core/Persistence/Dtos/ContentTypeDto.cs b/src/Umbraco.Core/Persistence/Dtos/ContentTypeDto.cs index 0cfc53eead..d930abc54c 100644 --- a/src/Umbraco.Core/Persistence/Dtos/ContentTypeDto.cs +++ b/src/Umbraco.Core/Persistence/Dtos/ContentTypeDto.cs @@ -3,11 +3,13 @@ using Umbraco.Core.Persistence.DatabaseAnnotations; namespace Umbraco.Core.Persistence.Dtos { - [TableName(Constants.DatabaseSchema.Tables.ContentType)] + [TableName(TableName)] [PrimaryKey("pk")] [ExplicitColumns] internal class ContentTypeDto { + public const string TableName = Constants.DatabaseSchema.Tables.ContentType; + [Column("pk")] [PrimaryKeyColumn(IdentitySeed = 535)] public int PrimaryKey { get; set; } diff --git a/src/Umbraco.Core/Persistence/Dtos/ContentVersionDto.cs b/src/Umbraco.Core/Persistence/Dtos/ContentVersionDto.cs index 13b7c30d45..7a6ab94b47 100644 --- a/src/Umbraco.Core/Persistence/Dtos/ContentVersionDto.cs +++ b/src/Umbraco.Core/Persistence/Dtos/ContentVersionDto.cs @@ -10,7 +10,7 @@ namespace Umbraco.Core.Persistence.Dtos [ExplicitColumns] internal class ContentVersionDto { - private const string TableName = Constants.DatabaseSchema.Tables.ContentVersion; + public const string TableName = Constants.DatabaseSchema.Tables.ContentVersion; [Column("id")] [PrimaryKeyColumn] diff --git a/src/Umbraco.Core/Persistence/Dtos/DocumentCultureVariationDto.cs b/src/Umbraco.Core/Persistence/Dtos/DocumentCultureVariationDto.cs index be4cf7c023..78e819e714 100644 --- a/src/Umbraco.Core/Persistence/Dtos/DocumentCultureVariationDto.cs +++ b/src/Umbraco.Core/Persistence/Dtos/DocumentCultureVariationDto.cs @@ -8,7 +8,7 @@ namespace Umbraco.Core.Persistence.Dtos [ExplicitColumns] internal class DocumentCultureVariationDto { - private const string TableName = Constants.DatabaseSchema.Tables.DocumentCultureVariation; + public const string TableName = Constants.DatabaseSchema.Tables.DocumentCultureVariation; [Column("id")] [PrimaryKeyColumn] diff --git a/src/Umbraco.Core/Persistence/Dtos/LanguageDto.cs b/src/Umbraco.Core/Persistence/Dtos/LanguageDto.cs index 78e5670830..12c9fd0bd4 100644 --- a/src/Umbraco.Core/Persistence/Dtos/LanguageDto.cs +++ b/src/Umbraco.Core/Persistence/Dtos/LanguageDto.cs @@ -3,11 +3,13 @@ using Umbraco.Core.Persistence.DatabaseAnnotations; namespace Umbraco.Core.Persistence.Dtos { - [TableName(Constants.DatabaseSchema.Tables.Language)] + [TableName(TableName)] [PrimaryKey("id")] [ExplicitColumns] internal class LanguageDto { + public const string TableName = Constants.DatabaseSchema.Tables.Language; + [Column("id")] [PrimaryKeyColumn(IdentitySeed = 2)] public short Id { get; set; } diff --git a/src/Umbraco.Core/Persistence/Dtos/MediaVersionDto.cs b/src/Umbraco.Core/Persistence/Dtos/MediaVersionDto.cs index e27a99a2ae..f71b3149cf 100644 --- a/src/Umbraco.Core/Persistence/Dtos/MediaVersionDto.cs +++ b/src/Umbraco.Core/Persistence/Dtos/MediaVersionDto.cs @@ -3,15 +3,17 @@ using Umbraco.Core.Persistence.DatabaseAnnotations; namespace Umbraco.Core.Persistence.Dtos { - [TableName(Constants.DatabaseSchema.Tables.MediaVersion)] + [TableName(TableName)] [PrimaryKey("id", AutoIncrement = false)] [ExplicitColumns] internal class MediaVersionDto { + public const string TableName = Constants.DatabaseSchema.Tables.MediaVersion; + [Column("id")] [PrimaryKeyColumn(AutoIncrement = false)] [ForeignKey(typeof(ContentVersionDto))] - [Index(IndexTypes.UniqueNonClustered, Name = "IX_" + Constants.DatabaseSchema.Tables.MediaVersion, ForColumns = "id, path")] + [Index(IndexTypes.UniqueNonClustered, Name = "IX_" + TableName, ForColumns = "id, path")] public int Id { get; set; } [Column("path")] diff --git a/src/Umbraco.Core/Persistence/Dtos/NodeDto.cs b/src/Umbraco.Core/Persistence/Dtos/NodeDto.cs index 38e8ed0900..924f7ea301 100644 --- a/src/Umbraco.Core/Persistence/Dtos/NodeDto.cs +++ b/src/Umbraco.Core/Persistence/Dtos/NodeDto.cs @@ -10,7 +10,7 @@ namespace Umbraco.Core.Persistence.Dtos [ExplicitColumns] internal class NodeDto { - private const string TableName = Constants.DatabaseSchema.Tables.Node; + public const string TableName = Constants.DatabaseSchema.Tables.Node; public const int NodeIdSeed = 1060; [Column("id")] diff --git a/src/Umbraco.Core/Persistence/Dtos/UserDto.cs b/src/Umbraco.Core/Persistence/Dtos/UserDto.cs index c6cc889ab0..028b760ba5 100644 --- a/src/Umbraco.Core/Persistence/Dtos/UserDto.cs +++ b/src/Umbraco.Core/Persistence/Dtos/UserDto.cs @@ -6,11 +6,13 @@ using Umbraco.Core.Persistence.DatabaseModelDefinitions; namespace Umbraco.Core.Persistence.Dtos { - [TableName(Constants.DatabaseSchema.Tables.User)] + [TableName(TableName)] [PrimaryKey("id", AutoIncrement = true)] [ExplicitColumns] internal class UserDto { + public const string TableName = Constants.DatabaseSchema.Tables.User; + public UserDto() { UserGroupDtos = new List(); diff --git a/src/Umbraco.Core/Persistence/Dtos/UserLoginDto.cs b/src/Umbraco.Core/Persistence/Dtos/UserLoginDto.cs index 86d306b06a..e03efa8fe9 100644 --- a/src/Umbraco.Core/Persistence/Dtos/UserLoginDto.cs +++ b/src/Umbraco.Core/Persistence/Dtos/UserLoginDto.cs @@ -4,17 +4,19 @@ using Umbraco.Core.Persistence.DatabaseAnnotations; namespace Umbraco.Core.Persistence.Dtos { - [TableName(Constants.DatabaseSchema.Tables.UserLogin)] + [TableName(TableName)] [PrimaryKey("sessionId", AutoIncrement = false)] [ExplicitColumns] internal class UserLoginDto { + public const string TableName = Constants.DatabaseSchema.Tables.UserLogin; + [Column("sessionId")] [PrimaryKeyColumn(AutoIncrement = false)] public Guid SessionId { get; set; } [Column("userId")] - [ForeignKey(typeof(UserDto), Name = "FK_" + Constants.DatabaseSchema.Tables.UserLogin + "_umbracoUser_id")] + [ForeignKey(typeof(UserDto), Name = "FK_" + TableName + "_umbracoUser_id")] public int UserId { get; set; } /// diff --git a/src/Umbraco.Core/Persistence/NPocoSqlExtensions.cs b/src/Umbraco.Core/Persistence/NPocoSqlExtensions.cs index 60172ef687..178b68b4f8 100644 --- a/src/Umbraco.Core/Persistence/NPocoSqlExtensions.cs +++ b/src/Umbraco.Core/Persistence/NPocoSqlExtensions.cs @@ -869,12 +869,28 @@ namespace Umbraco.Core.Persistence var u = new SqlUpd(sql.SqlContext); u = updates(u); - for (var i = 0; i < u.SetExpressions.Count; i++) + var first = true; + foreach (var setExpression in u.SetExpressions) { - var setExpression = u.SetExpressions[i]; - sql.Append(setExpression.Item1 + "=@0" + (i < u.SetExpressions.Count - 1 ? "," : ""), setExpression.Item2); + switch (setExpression.Item2) + { + case null: + sql.Append((first ? "" : ",") + " " + setExpression.Item1 + "=NULL"); + break; + case string s when s == string.Empty: + sql.Append((first ? "" : ",") + " " + setExpression.Item1 + "=''"); + break; + default: + sql.Append((first ? "" : ",") + " " + setExpression.Item1 + "=@0", setExpression.Item2); + break; + } + + first = false; } + if (!first) + sql.Append(" "); + return sql; } diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs index f775def629..442c2ce2b4 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs @@ -560,7 +560,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax public virtual string CreateTable => "CREATE TABLE {0} ({1})"; public virtual string DropTable => "DROP TABLE {0}"; - public virtual string AddColumn => "ALTER TABLE {0} ADD COLUMN {1}"; + public virtual string AddColumn => "ALTER TABLE {0} ADD {1}"; public virtual string DropColumn => "ALTER TABLE {0} DROP COLUMN {1}"; public virtual string AlterColumn => "ALTER TABLE {0} ALTER COLUMN {1}"; public virtual string RenameColumn => "ALTER TABLE {0} RENAME COLUMN {1} TO {2}"; diff --git a/src/Umbraco.Core/StringExtensions.cs b/src/Umbraco.Core/StringExtensions.cs index 98e831f73f..a69aa4bbe1 100644 --- a/src/Umbraco.Core/StringExtensions.cs +++ b/src/Umbraco.Core/StringExtensions.cs @@ -1363,14 +1363,25 @@ namespace Umbraco.Core return ReplaceMany(text, regexSpecialCharacters); } + /// + /// Checks whether a string "haystack" contains within it any of the strings in the "needles" collection and returns true if it does or false if it doesn't + /// + /// The string to check + /// The collection of strings to check are contained within the first string + /// The type of comparision to perform - defaults to + /// True if any of the needles are contained with haystack; otherwise returns false + /// Added fix to ensure the comparison is used - see http://issues.umbraco.org/issue/U4-11313 public static bool ContainsAny(this string haystack, IEnumerable needles, StringComparison comparison = StringComparison.CurrentCulture) { - if (haystack == null) throw new ArgumentNullException("haystack"); - if (string.IsNullOrEmpty(haystack) == false || needles.Any()) + if (haystack == null) + throw new ArgumentNullException("haystack"); + + if (string.IsNullOrEmpty(haystack) || needles == null || !needles.Any()) { - return needles.Any(value => haystack.IndexOf(value) >= 0); + return false; } - return false; + + return needles.Any(value => haystack.IndexOf(value, comparison) >= 0); } public static bool CsvContains(this string csv, string value) diff --git a/src/Umbraco.Tests/Migrations/AdvancedMigrationTests.cs b/src/Umbraco.Tests/Migrations/AdvancedMigrationTests.cs index cdab84ddb9..33185b694a 100644 --- a/src/Umbraco.Tests/Migrations/AdvancedMigrationTests.cs +++ b/src/Umbraco.Tests/Migrations/AdvancedMigrationTests.cs @@ -263,7 +263,7 @@ namespace Umbraco.Tests.Migrations var table = DefinitionFactory.GetTableDefinition(typeof(NodeDto), SqlSyntax); var column = table.Columns.First(x => x.Name == "id"); var create = SqlSyntax.Format(column); // returns [id] INTEGER NOT NULL IDENTITY(1060,1) - Database.Execute($"ALTER TABLE {SqlSyntax.GetQuotedTableName("umbracoNode")} ADD COLUMN " + create); + Database.Execute($"ALTER TABLE {SqlSyntax.GetQuotedTableName("umbracoNode")} ADD " + create); } } } diff --git a/src/Umbraco.Tests/Persistence/NPocoTests/NPocoSqlExtensionsTests.cs b/src/Umbraco.Tests/Persistence/NPocoTests/NPocoSqlExtensionsTests.cs index e37c2fbeaa..458479b293 100644 --- a/src/Umbraco.Tests/Persistence/NPocoTests/NPocoSqlExtensionsTests.cs +++ b/src/Umbraco.Tests/Persistence/NPocoTests/NPocoSqlExtensionsTests.cs @@ -111,6 +111,15 @@ INNER JOIN [dto2] ON [dto1].[id] = [dto2].[dto1id]".NoCrLf(), sql.SQL.NoCrLf()); Assert.AreEqual("SELECT [dto1].[id] AS [Id] , [dto2].[id] AS [id2]".NoCrLf(), sql.SQL.NoCrLf()); } + [Test] + public void UpdateTests() + { + var sql = Sql() + .Update(u => u.Set(x => x.EditorAlias, "Umbraco.ColorPicker")) + .Where(x => x.EditorAlias == "Umbraco.ColorPickerAlias"); + sql.WriteToConsole(); + } + [TableName("dto1")] [PrimaryKey("id", AutoIncrement = false)] [ExplicitColumns] diff --git a/src/Umbraco.Tests/Strings/StringExtensionsTests.cs b/src/Umbraco.Tests/Strings/StringExtensionsTests.cs index 55976e0d89..207c929f15 100644 --- a/src/Umbraco.Tests/Strings/StringExtensionsTests.cs +++ b/src/Umbraco.Tests/Strings/StringExtensionsTests.cs @@ -58,7 +58,7 @@ namespace Umbraco.Tests.Strings [TestCase("hello.txt", "hello")] [TestCase("this.is.a.Txt", "this.is.a")] [TestCase("this.is.not.a. Txt", "this.is.not.a. Txt")] - [TestCase("not a file","not a file")] + [TestCase("not a file", "not a file")] public void Strip_File_Extension(string input, string result) { var stripped = input.StripFileExtension(); @@ -152,6 +152,19 @@ namespace Umbraco.Tests.Strings Assert.AreEqual(expected, output); } + [TestCase("pineapple", new string[] { "banana", "apple", "blueberry", "strawberry" }, StringComparison.CurrentCulture, true)] + [TestCase("PINEAPPLE", new string[] { "banana", "apple", "blueberry", "strawberry" }, StringComparison.CurrentCulture, false)] + [TestCase("pineapple", new string[] { "banana", "Apple", "blueberry", "strawberry" }, StringComparison.CurrentCulture, false)] + [TestCase("pineapple", new string[] { "banana", "Apple", "blueberry", "strawberry" }, StringComparison.OrdinalIgnoreCase, true)] + [TestCase("pineapple", new string[] { "banana", "blueberry", "strawberry" }, StringComparison.OrdinalIgnoreCase, false)] + [TestCase("Strawberry unicorn pie", new string[] { "Berry" }, StringComparison.OrdinalIgnoreCase, true)] + [TestCase("empty pie", new string[0], StringComparison.OrdinalIgnoreCase, false)] + public void ContainsAny(string haystack, IEnumerable needles, StringComparison comparison, bool expected) + { + bool output = haystack.ContainsAny(needles, comparison); + Assert.AreEqual(expected, output); + } + // FORMAT STRINGS // note: here we just ensure that the proper helper gets called properly diff --git a/src/Umbraco.Web.UI.Client/setupgulp.bat b/src/Umbraco.Web.UI.Client/setupgulp.bat new file mode 100644 index 0000000000..5cddec3747 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/setupgulp.bat @@ -0,0 +1,23 @@ +@ECHO OFF + +ECHO. +ECHO. +ECHO This will only work when you have NPM available on the command line +ECHO Works great with NodeJS Portable - https://gareth.flowers/nodejs-portable/ +ECHO. +ECHO. +set /P c=Are you sure you want to continue [Y/N]? +if /I "%c%" EQU "Y" goto :setupgulp +if /I "%c%" EQU "N" goto :eof + +:setupgulp +call npm install +call npm -g install bower +call npm -g install gulp +call npm -g install gulp-cli + +ECHO. +ECHO. +ECHO You should now be able to run: gulp build +ECHO. +ECHO. \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/healthcheck.html b/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/healthcheck.html index 22147de190..be74948ad5 100644 --- a/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/healthcheck.html +++ b/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/healthcheck.html @@ -36,7 +36,7 @@
- + {{ group.totalWarning }}
diff --git a/src/Umbraco.Web.UI.Client/src/views/languages/edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/languages/edit.controller.js index 3dc0845afc..6ee5a5bd7a 100644 --- a/src/Umbraco.Web.UI.Client/src/views/languages/edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/languages/edit.controller.js @@ -41,7 +41,14 @@ if($routeParams.create) { vm.page.name = vm.labels.addLanguage; - languageResource.getCultures().then(function(cultures) { + languageResource.getCultures().then(function (culturesDictionary) { + var cultures = []; + angular.forEach(culturesDictionary, function (value, key) { + cultures.push({ + name: key, + displayName: value + }); + }); vm.availableCultures = cultures; }); } diff --git a/src/Umbraco.Web.UI.Client/src/views/languages/edit.html b/src/Umbraco.Web.UI.Client/src/views/languages/edit.html index 4e0f3aba60..d2b5ef6433 100644 --- a/src/Umbraco.Web.UI.Client/src/views/languages/edit.html +++ b/src/Umbraco.Web.UI.Client/src/views/languages/edit.html @@ -25,7 +25,7 @@ Required diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 89151e65f4..c6877a1d9c 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -488,7 +488,7 @@ - + Web.Template.config diff --git a/src/Umbraco.Web.UI/Umbraco/Views/Preview/Index.cshtml b/src/Umbraco.Web.UI/Umbraco/Views/Preview/Index.cshtml index 38f7203407..0b1c3fbe17 100644 --- a/src/Umbraco.Web.UI/Umbraco/Views/Preview/Index.cshtml +++ b/src/Umbraco.Web.UI/Umbraco/Views/Preview/Index.cshtml @@ -9,6 +9,7 @@ Umbraco Canvas Designer +
diff --git a/src/Umbraco.Web.UI/Umbraco/Views/Preview/web.config b/src/Umbraco.Web.UI/Umbraco/Views/web.config similarity index 73% rename from src/Umbraco.Web.UI/Umbraco/Views/Preview/web.config rename to src/Umbraco.Web.UI/Umbraco/Views/web.config index 339972c139..d378fee13b 100644 --- a/src/Umbraco.Web.UI/Umbraco/Views/Preview/web.config +++ b/src/Umbraco.Web.UI/Umbraco/Views/web.config @@ -16,6 +16,13 @@ + + + + + + + @@ -27,7 +34,7 @@ - + @@ -35,6 +42,7 @@ + diff --git a/src/Umbraco.Web.UI/Views/Web.config b/src/Umbraco.Web.UI/Views/Web.config index 9c0bd5b5df..b809c2167e 100644 --- a/src/Umbraco.Web.UI/Views/Web.config +++ b/src/Umbraco.Web.UI/Views/Web.config @@ -1,6 +1,6 @@ - +
@@ -31,35 +31,19 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + diff --git a/src/Umbraco.Web.UI/config/BackOfficeTours/getting-started.json b/src/Umbraco.Web.UI/config/BackOfficeTours/getting-started.json index 836b7a965c..4556fd6496 100644 --- a/src/Umbraco.Web.UI/config/BackOfficeTours/getting-started.json +++ b/src/Umbraco.Web.UI/config/BackOfficeTours/getting-started.json @@ -73,7 +73,7 @@ { "element": "#applications [data-element='section-help']", "title": "Help", - "content": "If you ever find yourself in trouble click here to open the help drawer.", + "content": "If you ever find yourself in trouble click here to open the Help drawer.", "event": "click", "backdropOpacity": 0.6 }, @@ -108,7 +108,7 @@ "steps": [ { "title": "Create your first Document Type", - "content": "

Step 1 of any site is to create a Document Type.
A Document Type is a template for content. For each type of content you want to create you'll create a Document Type. This will define were content based on this Document Type can be created, how many properties it holds and what the input method should be for these properties.

When you have at least one Document type in place you can start creating content and this content can the be used in a template.

In this tour you will learn how to set up a basic Document Type with a property to enter a short text.

", + "content": "

Step 1 of any site is to create a Document Type.
A Document Type is a template for content. For each type of content you want to create you'll create a Document Type. This will define where content based on this Document Type can be created, how many properties it holds and what the input method should be for these properties.

When you have at least one Document type in place you can start creating content and this content can then be used in a template.

In this tour you will learn how to set up a basic Document Type with a property to enter a short text.

", "type": "intro" }, { @@ -121,14 +121,14 @@ { "element": "#tree [data-element='tree-item-documentTypes']", "title": "Create Document Type", - "content": "

Hover the Document Type tree and click the three small dots to open the context menu.

", + "content": "

Hover over the Document Type tree and click the three small dots to open the context menu.

", "event": "click", "eventElement": "#tree [data-element='tree-item-documentTypes'] [data-element='tree-item-options']" }, { "element": "#dialog [data-element='action-documentType']", "title": "Create Document Type", - "content": "

Click Document Type to create a new document type with a template. The template will be automatically created and set as the default template for this Document Type

You will use the template in a later tour render content.

", + "content": "

Click Document Type to create a new document type with a template. The template will be automatically created and set as the default template for this Document Type

You will use the template in a later tour to render content.

", "event": "click" }, { @@ -157,7 +157,7 @@ { "element": "[data-element='property-add']", "title": "Add a property", - "content": "

Properties are the different input fields on a content page.

On our Home Page we wan't to add a welcome text.

Click Add property to open the property dialog.

", + "content": "

Properties are the different input fields on a content page.

On our Home Page we want to add a welcome text.

Click Add property to open the property dialog.

", "event": "click" }, { @@ -181,7 +181,7 @@ "element": "[data-element~='overlay-editor-picker']", "elementPreventClick": true, "title": "Editor picker", - "content": "

In the editor picker dialog we can pick one of the many build in editor.

You can choose from preconfigured data types (Reuse) or create a new configuration (Available editors)

" + "content": "

In the editor picker dialog we can pick one of the many built-in editor.

You can choose from preconfigured data types (Reuse) or create a new configuration (Available editors)

" }, { "element": "[data-element~='overlay-editor-picker'] [data-element='editor-Textarea']", @@ -193,12 +193,12 @@ "element": "[data-element~='overlay-editor-settings']", "elementPreventClick": true, "title": "Editor settings", - "content": "Each property editor can have individual settings. For the textarea editor you can set a charachter limit but in this case it is not needed" + "content": "Each property editor can have individual settings. For the textarea editor you can set a character limit but in this case it is not needed" }, { "element": "[data-element~='overlay-editor-settings'] [data-element='button-overlaySubmit']", "title": "Save editor", - "content": "Click Submit to save the editor.", + "content": "Click Submit to save the changes.", "event": "click" }, { @@ -245,7 +245,7 @@ { "element": "[data-element='tree-root']", "title": "Open context menu", - "content": "

Open the context menu by hovering the root of the content section.

Now click the three small dots to the right.

", + "content": "

Open the context menu by hovering over the root of the content section.

Now click the three small dots to the right.

", "event": "click", "eventElement": "[data-element='tree-root'] [data-element='tree-item-options']" }, diff --git a/src/Umbraco.Web/BatchedDatabaseServerMessenger.cs b/src/Umbraco.Web/BatchedDatabaseServerMessenger.cs index a28a180d50..4abb8f1e0b 100644 --- a/src/Umbraco.Web/BatchedDatabaseServerMessenger.cs +++ b/src/Umbraco.Web/BatchedDatabaseServerMessenger.cs @@ -33,9 +33,7 @@ namespace Umbraco.Web _databaseFactory = databaseFactory; } - // invoked by BatchedDatabaseServerMessengerStartup which is an ApplicationEventHandler - // with default "ShouldExecute", so that method will run if app IsConfigured and database - // context IsDatabaseConfigured - we still want to check CanConnect though to be safe + // invoked by DatabaseServerRegistrarAndMessengerComponent internal void Startup() { UmbracoModule.EndRequest += UmbracoModule_EndRequest; diff --git a/src/Umbraco.Web/Components/DatabaseServerRegistrarAndMessengerComponent.cs b/src/Umbraco.Web/Components/DatabaseServerRegistrarAndMessengerComponent.cs index e07a36bbfc..bada87408f 100644 --- a/src/Umbraco.Web/Components/DatabaseServerRegistrarAndMessengerComponent.cs +++ b/src/Umbraco.Web/Components/DatabaseServerRegistrarAndMessengerComponent.cs @@ -99,6 +99,8 @@ namespace Umbraco.Web.Components _messenger = serverMessenger as BatchedDatabaseServerMessenger; if (_messenger == null) throw new Exception("panic: messenger"); + _messenger.Startup(); + _runtime = runtime; _logger = logger; _registrationService = registrationService; diff --git a/src/Umbraco.Web/Properties/AssemblyInfo.cs b/src/Umbraco.Web/Properties/AssemblyInfo.cs index b7d046787e..2e8c612aba 100644 --- a/src/Umbraco.Web/Properties/AssemblyInfo.cs +++ b/src/Umbraco.Web/Properties/AssemblyInfo.cs @@ -34,8 +34,11 @@ using System.Runtime.InteropServices; [assembly: InternalsVisibleTo("Umbraco.Forms.Web")] // Umbraco Headless -[assembly: InternalsVisibleTo("Umbraco.Headless")] +[assembly: InternalsVisibleTo("Umbraco.Headless")] // v8 [assembly: InternalsVisibleTo("Umbraco.Compat7")] +// code analysis +// IDE1006 is broken, wants _value syntax for consts, etc - and it's even confusing ppl at MS, kill it +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "~_~")] diff --git a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs index 652e6daa9f..062a696ffc 100644 --- a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs @@ -710,7 +710,7 @@ namespace Umbraco.Web.PublishedCache.NuCache return; foreach (var payload in payloads) - _logger.Debug($"Notified {payload.ChangeTypes} for {payload.ItemType} {payload.Id}"); + _logger.Debug($"Notified {payload.ChangeTypes} for {payload.ItemType} {payload.Id}"); Notify(_contentStore, payloads, RefreshContentTypesLocked); Notify(_mediaStore, payloads, RefreshMediaTypesLocked); diff --git a/src/Umbraco.Web/PublishedCache/UmbracoContextPublishedSnapshotAccessor.cs b/src/Umbraco.Web/PublishedCache/UmbracoContextPublishedSnapshotAccessor.cs index 706d67020a..76936dd2cb 100644 --- a/src/Umbraco.Web/PublishedCache/UmbracoContextPublishedSnapshotAccessor.cs +++ b/src/Umbraco.Web/PublishedCache/UmbracoContextPublishedSnapshotAccessor.cs @@ -16,14 +16,10 @@ namespace Umbraco.Web.PublishedCache get { var umbracoContext = _umbracoContextAccessor.UmbracoContext; - if (umbracoContext == null) throw new Exception("The IUmbracoContextAccessor could not provide an UmbracoContext."); - return umbracoContext.PublishedSnapshot; + return umbracoContext?.PublishedSnapshot; } - set - { - throw new NotSupportedException(); // not ok to set - } + set => throw new NotSupportedException(); // not ok to set } } } diff --git a/src/Umbraco.Web/Trees/ContentTreeController.cs b/src/Umbraco.Web/Trees/ContentTreeController.cs index c19cecd712..b083c85bab 100644 --- a/src/Umbraco.Web/Trees/ContentTreeController.cs +++ b/src/Umbraco.Web/Trees/ContentTreeController.cs @@ -47,10 +47,10 @@ namespace Umbraco.Web.Trees /// protected override TreeNode GetSingleTreeNode(IEntitySlim entity, string parentId, FormDataCollection queryStrings) { - var langId = queryStrings["culture"].TryConvertTo(); + var langId = queryStrings?["culture"]; var allowedUserOptions = GetAllowedUserMenuItemsForNode(entity); - if (CanUserAccessNode(entity, allowedUserOptions, langId.Success ? langId.Result : null)) + if (CanUserAccessNode(entity, allowedUserOptions, langId)) { //Special check to see if it ia a container, if so then we'll hide children. var isContainer = entity.IsContainer; // && (queryStrings.Get("isDialog") != "true"); diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 6f61144786..537be3fbfa 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -1189,9 +1189,6 @@ Code - - Code - Code @@ -1206,9 +1203,6 @@ True Settings.settings - - Code - Code @@ -1590,4 +1584,4 @@ - + \ No newline at end of file diff --git a/src/Umbraco.Web/UmbracoHelper.cs b/src/Umbraco.Web/UmbracoHelper.cs index 577af22167..7375dac98d 100644 --- a/src/Umbraco.Web/UmbracoHelper.cs +++ b/src/Umbraco.Web/UmbracoHelper.cs @@ -861,7 +861,7 @@ namespace Umbraco.Web { return ContentQuery.Search(skip, take, out totalRecords, criteria, searchProvider); } - + /// /// Searhes content. /// diff --git a/src/Umbraco.Web/umbraco.presentation/default.aspx.cs b/src/Umbraco.Web/umbraco.presentation/default.aspx.cs index dcfe5fb5b3..84888f13d7 100644 --- a/src/Umbraco.Web/umbraco.presentation/default.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/default.aspx.cs @@ -62,9 +62,21 @@ namespace umbraco FireBeforeRequestInit(args); //if we are cancelling then return and don't proceed - if (args.Cancel) return; - - this.MasterPageFile = template.GetMasterPageName(_upage.Template); + if (args.Cancel) return; + + var template = Current.Services.FileService.GetTemplate(_upage.Template); + if (template != null) + { + var alias = template.MasterTemplateAlias; + var file = alias.Replace(" ", "") + ".master"; + var path = SystemDirectories.Masterpages + "/" + file; + + + if (File.Exists(IOHelper.MapPath(VirtualPathUtility.ToAbsolute(path)))) + this.MasterPageFile = path; + else + this.MasterPageFile = SystemDirectories.Umbraco + "/masterPages/default.master"; + } // reset the friendly path so it's used by forms, etc. Context.RewritePath(UmbracoContext.Current.OriginalRequestUrl.PathAndQuery); diff --git a/src/Umbraco.Web/umbraco.presentation/helper.cs b/src/Umbraco.Web/umbraco.presentation/helper.cs deleted file mode 100644 index e745f7cc95..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/helper.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using System.Collections; -using Umbraco.Web.Macros; - -namespace umbraco -{ - /// - /// Summary description for helper. - /// - [Obsolete("This needs to be removed, do not use")] - public class helper - { - public static bool IsNumeric(string number) - { - int result; - return int.TryParse(number, out result); - } - - public static string FindAttribute(IDictionary attributes, string key) - { - return FindAttribute(null, attributes, key); - } - - public static string FindAttribute(IDictionary pageElements, IDictionary attributes, string key) - { - // fix for issue 14862: lowercase for case insensitive matching - key = key.ToLower(); - - var attributeValue = string.Empty; - if (attributes[key] != null) - attributeValue = attributes[key].ToString(); - - attributeValue = MacroRenderer.ParseAttribute(pageElements, attributeValue); - return attributeValue; - } - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/item.cs b/src/Umbraco.Web/umbraco.presentation/item.cs index bd36ee429c..c183e3833e 100644 --- a/src/Umbraco.Web/umbraco.presentation/item.cs +++ b/src/Umbraco.Web/umbraco.presentation/item.cs @@ -11,6 +11,7 @@ using Umbraco.Web; using Umbraco.Core.Profiling; using Umbraco.Core.Strings; using Umbraco.Web.Composing; +using Umbraco.Web.Macros; namespace umbraco { @@ -55,7 +56,7 @@ namespace umbraco /// internal item(IPublishedContent publishedContent, IDictionary elements, IDictionary attributes) { - _fieldName = helper.FindAttribute(attributes, "field"); + _fieldName = FindAttribute(attributes, "field"); if (_fieldName.StartsWith("#")) { @@ -64,7 +65,7 @@ namespace umbraco else { // Loop through XML children we need to find the fields recursive - var recursive = helper.FindAttribute(attributes, "recursive") == "true"; + var recursive = FindAttribute(attributes, "recursive") == "true"; if (publishedContent == null) { @@ -90,7 +91,7 @@ namespace umbraco //now we check if the value is still empty and if so we'll check useIfEmpty if (string.IsNullOrEmpty(_fieldContent)) { - var altFieldName = helper.FindAttribute(attributes, "useIfEmpty"); + var altFieldName = FindAttribute(attributes, "useIfEmpty"); if (string.IsNullOrEmpty(altFieldName) == false) { if (publishedContent != null && (publishedContent.HasProperty(altFieldName) || recursive)) @@ -114,6 +115,13 @@ namespace umbraco ParseItem(attributes); } + static string FindAttribute(IDictionary attributes, string key) + { + key = key.ToLowerInvariant(); + var attributeValue = attributes.Contains(key) ? attributes[key].ToString() : string.Empty; + return MacroRenderer.ParseAttribute(null, attributeValue); + } + /// /// Returns the recursive value using a legacy strategy of looking at the xml cache and the splitPath in the elements collection /// @@ -160,21 +168,21 @@ namespace umbraco using (Current.ProfilingLogger.DebugDuration("Start parsing " + _fieldName)) { HttpContext.Current.Trace.Write("item", "Start parsing '" + _fieldName + "'"); - if (helper.FindAttribute(attributes, "textIfEmpty") != "" && _fieldContent == "") - _fieldContent = helper.FindAttribute(attributes, "textIfEmpty"); + if (FindAttribute(attributes, "textIfEmpty") != "" && _fieldContent == "") + _fieldContent = FindAttribute(attributes, "textIfEmpty"); _fieldContent = _fieldContent.Trim(); // DATE FORMATTING FUNCTIONS - if (helper.FindAttribute(attributes, "formatAsDateWithTime") == "true") + if (FindAttribute(attributes, "formatAsDateWithTime") == "true") { if (_fieldContent == "") _fieldContent = DateTime.Now.ToString(); _fieldContent = Convert.ToDateTime(_fieldContent).ToLongDateString() + - helper.FindAttribute(attributes, "formatAsDateWithTimeSeparator") + + FindAttribute(attributes, "formatAsDateWithTimeSeparator") + Convert.ToDateTime(_fieldContent).ToShortTimeString(); } - else if (helper.FindAttribute(attributes, "formatAsDate") == "true") + else if (FindAttribute(attributes, "formatAsDate") == "true") { if (_fieldContent == "") _fieldContent = DateTime.Now.ToString(); @@ -183,7 +191,7 @@ namespace umbraco // TODO: Needs revision to check if parameter-tags has attributes - if (helper.FindAttribute(attributes, "stripParagraph") == "true" && _fieldContent.Length > 5) + if (FindAttribute(attributes, "stripParagraph") == "true" && _fieldContent.Length > 5) { _fieldContent = _fieldContent.Trim(); string fieldContentLower = _fieldContent.ToLower(); @@ -200,20 +208,20 @@ namespace umbraco } // CASING - if (helper.FindAttribute(attributes, "case") == "lower") + if (FindAttribute(attributes, "case") == "lower") _fieldContent = _fieldContent.ToLower(); - else if (helper.FindAttribute(attributes, "case") == "upper") + else if (FindAttribute(attributes, "case") == "upper") _fieldContent = _fieldContent.ToUpper(); - else if (helper.FindAttribute(attributes, "case") == "title") + else if (FindAttribute(attributes, "case") == "title") _fieldContent = _fieldContent.ToCleanString(CleanStringType.Ascii | CleanStringType.Alias | CleanStringType.PascalCase); // OTHER FORMATTING FUNCTIONS - if (helper.FindAttribute(attributes, "urlEncode") == "true") + if (FindAttribute(attributes, "urlEncode") == "true") _fieldContent = HttpUtility.UrlEncode(_fieldContent); - if (helper.FindAttribute(attributes, "htmlEncode") == "true") + if (FindAttribute(attributes, "htmlEncode") == "true") _fieldContent = HttpUtility.HtmlEncode(_fieldContent); - if (helper.FindAttribute(attributes, "convertLineBreaks") == "true") + if (FindAttribute(attributes, "convertLineBreaks") == "true") _fieldContent = _fieldContent.Replace("\n", "
\n"); HttpContext.Current.Trace.Write("item", "Done parsing '" + _fieldName + "'"); diff --git a/src/Umbraco.Web/umbraco.presentation/template.cs b/src/Umbraco.Web/umbraco.presentation/template.cs deleted file mode 100644 index 8fad4c8b55..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/template.cs +++ /dev/null @@ -1,391 +0,0 @@ -using System; -using System.Text; -using System.IO; -using System.Text.RegularExpressions; -using System.Web.UI; -using System.Collections; -using Umbraco.Core.Cache; -using Umbraco.Core.Configuration; -using Umbraco.Web; -using Umbraco.Web.Cache; -using Umbraco.Core.IO; -using System.Web; -using Umbraco.Core.Models; -using Umbraco.Core.Xml; -using Umbraco.Web.Composing; -using Umbraco.Web.Macros; - -namespace umbraco -{ - /// - /// Holds methods for parsing and building umbraco templates - /// - [Obsolete("Do not use this class, use Umbraco.Core.Service.IFileService to work with templates")] - public class template - { - #region private variables - - readonly StringBuilder _templateOutput = new StringBuilder(); - - private string _templateDesign = ""; - int _masterTemplate = -1; - private string _templateName = ""; - private string _templateAlias = ""; - - #endregion - - #region public properties - public string TemplateContent - { - set - { - _templateOutput.Append(value); - } - get - { - return _templateOutput.ToString(); - } - } - - public int MasterTemplate - { - get { return _masterTemplate; } - } - - //added fallback to the default template to avoid nasty .net errors. - //This is referenced in /default.aspx.cs during page rendering. - public string MasterPageFile - { - get - { - - string file = TemplateAlias.Replace(" ", "") + ".master"; - string path = SystemDirectories.Masterpages + "/" + file; - - - if (System.IO.File.Exists(IOHelper.MapPath(VirtualPathUtility.ToAbsolute(path)))) - return path; - else - return SystemDirectories.Umbraco + "/masterPages/default.master"; - } - } - - //Support for template folders, if a alternative skin folder is requested - //we will try to look for template files in another folder - public string AlternateMasterPageFile(string templateFolder) - { - string file = TemplateAlias.Replace(" ", "") + ".master"; - string path = SystemDirectories.Masterpages + "/" + templateFolder + "/" + file; - - //if it doesn't exists then we return the normal file - if (!System.IO.File.Exists(IOHelper.MapPath(VirtualPathUtility.ToAbsolute(path)))) - { - - string originalPath = IOHelper.MapPath(VirtualPathUtility.ToAbsolute(MasterPageFile)); - string copyPath = IOHelper.MapPath(VirtualPathUtility.ToAbsolute(path)); - - string newFile; - using (var fs = new FileStream(originalPath, FileMode.Open, FileAccess.ReadWrite)) - using (var f = new StreamReader(fs)) - { - newFile = f.ReadToEnd(); - } - - newFile = newFile.Replace("MasterPageFile=\"~/masterpages/", "MasterPageFile=\""); - - using (var fs = new FileStream(copyPath, FileMode.Create, FileAccess.Write)) - using (var replacement = new StreamWriter(fs)) - { - replacement.Write(newFile); - } - } - - return path; - - } - - - public string TemplateAlias - { - get { return _templateAlias; } - } - #endregion - - #region public methods - - public override string ToString() - { - return this._templateName; - } - - public Control parseStringBuilder(StringBuilder tempOutput, page umbPage) - { - - Control pageContent = new Control(); - - bool stop = false; - bool debugMode = UmbracoContext.Current.HttpContext.IsDebuggingEnabled; - - while (!stop) - { - System.Web.HttpContext.Current.Trace.Write("template", "Begining of parsing rutine..."); - int tagIndex = tempOutput.ToString().ToLower().IndexOf(" -1) - { - string tempElementContent = ""; - pageContent.Controls.Add(new LiteralControl(tempOutput.ToString().Substring(0, tagIndex))); - - tempOutput.Remove(0, tagIndex); - - string tag = tempOutput.ToString().Substring(0, tempOutput.ToString().IndexOf(">") + 1); - Hashtable attributes = new Hashtable(XmlHelper.GetAttributesFromElement(tag)); - - // Check whether it's a single tag () or a tag with children (...) - if (tag.Substring(tag.Length - 2, 1) != "/" && tag.IndexOf(" ") > -1) - { - string closingTag = ""; - // Tag with children are only used when a macro is inserted by the umbraco-editor, in the - // following format: "", so we - // need to delete extra information inserted which is the image-tag and the closing - // umbraco_macro tag - if (tempOutput.ToString().IndexOf(closingTag) > -1) - { - tempOutput.Remove(0, tempOutput.ToString().IndexOf(closingTag)); - } - } - - - - System.Web.HttpContext.Current.Trace.Write("umbTemplate", "Outputting item: " + tag); - - // Handle umbraco macro tags - if (tag.ToString().ToLower().IndexOf("umbraco_macro") > -1) - { - if (debugMode) - pageContent.Controls.Add(new LiteralControl("
")); - - umbraco.presentation.templateControls.Macro macroControl = new umbraco.presentation.templateControls.Macro(); - macroControl.Alias = helper.FindAttribute(attributes, "macroalias"); - IDictionaryEnumerator ide = attributes.GetEnumerator(); - while (ide.MoveNext()) - if (macroControl.Attributes[ide.Key.ToString()] == null) - macroControl.Attributes.Add(ide.Key.ToString(), ide.Value.ToString()); - pageContent.Controls.Add(macroControl); - - if (debugMode) - pageContent.Controls.Add(new LiteralControl("
")); - } - else - { - if (tag.ToLower().IndexOf("umbraco_getitem") > -1) - { - umbraco.presentation.templateControls.Item itemControl = new umbraco.presentation.templateControls.Item(); - itemControl.Field = helper.FindAttribute(attributes, "field"); - IDictionaryEnumerator ide = attributes.GetEnumerator(); - while (ide.MoveNext()) - if (itemControl.Attributes[ide.Key.ToString()] == null) - itemControl.Attributes.Add(ide.Key.ToString(), ide.Value.ToString()); - pageContent.Controls.Add(itemControl); - - } - } - tempOutput.Remove(0, tempOutput.ToString().IndexOf(">") + 1); - tempOutput.Insert(0, tempElementContent); - } - else - { - pageContent.Controls.Add(new LiteralControl(tempOutput.ToString())); - break; - } - - } - - return pageContent; - - } - - - /// - /// Parses the content of the templateOutput stringbuilder, and matches any tags given in the - /// XML-file /umbraco/config/umbracoTemplateTags.xml. - /// Replaces the found tags in the StringBuilder object, with "real content" - /// - /// - public void Parse(page umbPage) - { - System.Web.HttpContext.Current.Trace.Write("umbracoTemplate", "Start parsing"); - - // First parse for known umbraco tags - // - macros - // - print item from page, level, or recursive - MatchCollection tags = Regex.Matches(_templateOutput.ToString(), "<\\?UMBRACO_MACRO[^>]*/>|<\\?UMBRACO_GETITEM[^>]*/>|<\\?(?[\\S]*)[^>]*/>", RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); - - foreach (Match tag in tags) - { - Hashtable attributes = new Hashtable(XmlHelper.GetAttributesFromElement(tag.Value)); - - - if (tag.ToString().ToLower().IndexOf("umbraco_macro") > -1) - { - var macroId = helper.FindAttribute(attributes, "macroid"); - if (macroId != "") - _templateOutput.Replace(tag.Value, string.Empty); - } - else - { - if (tag.ToString().ToLower().IndexOf("umbraco_getitem") > -1) - { - try - { - var tempElementContent = umbPage.Elements[helper.FindAttribute(attributes, "field")].ToString(); - var tempMacros = Regex.Matches(tempElementContent, "<\\?UMBRACO_MACRO(?[^>]*)>]*><\\/\\?UMBRACO_MACRO>", RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); - foreach (Match tempMacro in tempMacros) - { - var tempAttributes = new Hashtable(XmlHelper.GetAttributesFromElement(tempMacro.Groups["attributes"].Value)); - var macroId = helper.FindAttribute(tempAttributes, "macroid"); - if (Convert.ToInt32(macroId) > 0) - _templateOutput.Replace(tag.Value, string.Empty); - } - - _templateOutput.Replace(tag.Value, tempElementContent); - } - catch (Exception e) - { - System.Web.HttpContext.Current.Trace.Warn("umbracoTemplate", "Error reading element (" + helper.FindAttribute(attributes, "field") + ")", e); - } - } - } - } - - System.Web.HttpContext.Current.Trace.Write("umbracoTemplate", "Done parsing"); - } - - - - #endregion - - #region private methods - - private static MacroModel GetMacro(string macroId) - { - HttpContext.Current.Trace.Write("umbracoTemplate", "Starting macro (" + macroId + ")"); - // it's all obsolete anyways... - var macro = Current.Services.MacroService.GetByAlias(macroId); - return macro == null ? null : new MacroModel(macro); - } - - #endregion - - #region constructors - - public static string GetMasterPageName(int templateID) - { - return GetMasterPageName(templateID, null); - } - - public static string GetMasterPageName(int templateID, string templateFolder) - { - var t = new template(templateID); - - return !string.IsNullOrEmpty(templateFolder) - ? t.AlternateMasterPageFile(templateFolder) - : t.MasterPageFile; - } - - public template(int templateID) - { - var tId = templateID; - - var t = Current.ApplicationCache.RuntimeCache.GetCacheItem