Compare commits

...

65 Commits

Author SHA1 Message Date
Sebastiaan Janssen af0011f32a Fixes U4-1432 4.11.2 - Tinymce strips 'src' attribute from images 2013-01-11 08:23:31 -01:00
Sebastiaan Janssen ab6c5ac21a Added tag Release-4.11.2 for changeset 73711b806a40 2013-01-10 11:05:52 -01:00
Sebastiaan Janssen 227a38fb98 Removed tag 4.11.2 2013-01-10 11:05:43 -01:00
Sebastiaan Janssen 06f9dee649 Added tag 4.11.2 for changeset 73711b806a40 2013-01-10 11:05:34 -01:00
Sebastiaan Janssen 75680192bb Merge 4.11.2 into default 2013-01-10 11:05:13 -01:00
Sebastiaan Janssen a53efb394f Closing 4.11.2 branch 2013-01-10 10:54:56 -01:00
Sebastiaan Janssen 98ed32c8cf Include the new translation files in the project so they get in the build too 2013-01-10 09:55:35 -01:00
Sebastiaan Janssen df10ebebca Get latest translations in 2013-01-10 08:21:27 -01:00
Sebastiaan Janssen 88dc73cd66 Fix the unpublished/pendinchanges/published display 2013-01-10 07:29:04 -01:00
Sebastiaan Janssen cd0919aeeb Update version to 4.11.2 2013-01-09 16:03:56 -01:00
Sebastiaan Janssen ce6711b587 Duplicate fix (ce2f47c11322) #U4-1366 - conflict with partial view macro engine. 2013-01-09 13:58:55 -01:00
Sebastiaan Janssen e6178efcfb Duplicating fix for U4-483 so that this also fixes U4-1391 in the 4.11.x branch 2013-01-07 08:12:53 -01:00
Sebastiaan Janssen 30cf0e2040 Add some logging to PhysicalFileSystem 2012-12-26 06:49:54 -01:00
Sebastiaan Janssen 48d620cdb0 Cleanup RTE ImageHelper a little bit, still bad code but more readable now 2012-12-26 06:27:30 -01:00
Sebastiaan Janssen 3bd487d092 Fixed #U4-1323 Stripping umbraco path out of source is not needed any more 2012-12-26 05:54:34 -01:00
Sebastiaan Janssen 6c8c37256b Cleanup media uploader in RTE a little 2012-12-26 05:50:48 -01:00
Sebastiaan Janssen 37b1fcbaf0 Fix image uploader in RTE, when used in VDir it returns the right path now
no need for relative path hacks
2012-12-26 05:49:03 -01:00
Sebastiaan Janssen dc111768e3 Slight MediaFactory refactors, mostly to fix issue U4-1344 where files wouldn't
upload if the "magic" umbraco props don't exist (witdth, height, bytes)
2012-12-23 11:46:04 -01:00
leekelleher 6589d5d5d3 MNTP: Fixed an long-time CSS bug. Aligned the header with the right-panel. 2012-12-21 15:58:02 +00:00
Sebastiaan Janssen e6975a71d5 Additional fix for U4-1312 Cant publish child node, because parent not published
When you unpublish a node which it's descendants also get unpublished, but as
soon as you publish the parent node again, they don't end up in the XML cache
any more, leading to this error again. Now putting all previously published
documents back into the XML cache when the parent gets published
2012-12-20 14:05:28 -01:00
Sebastiaan Janssen 33b497e5f4 Additional fix for U4-1341 - nodes should appear dimmed when unpublished, but
they appeared as changed (and not dimmed, therefore looked published)
2012-12-20 13:42:30 -01:00
Sebastiaan Janssen c5e7c81c19 Notification and tree refresh when unpublishing content 2012-12-20 09:25:50 -01:00
Sebastiaan Janssen 47d1fe7082 Fixed U4-703 - Updating or re-installing package causes duplicate trees 2012-12-19 09:05:23 -01:00
Sebastiaan Janssen 735bd574ff Didn't mean to commit test code, sorry! 2012-12-17 12:29:43 -01:00
Sebastiaan Janssen 5c0d9785e0 Don't check log comment length if it is null.. helped with a broken recycle bin
not deleting content because sometimes the title of the content would be null
2012-12-17 09:25:55 -01:00
Sebastiaan Janssen db14868324 attributes["macroalias"] would YSOD instead of give back a null 2012-12-14 13:51:01 -01:00
Stephan 06952833ef U4-1212, U4-1312 - fix Document.PathPublished 2012-12-13 15:48:46 -01:00
Shannon Deminick 2a90e93a6f Updated partial view macro engine to support storing the files in the App_Plugins/[packagename]/Views/MacroPartials
so they can be stored with a package and not pollute the main file system.
2012-12-07 07:04:11 +05:00
Shannon Deminick 0d94ddb96e Got macro parameters working with Partial View Macros, changed PartialViewMacroPage to inherit from
UmbracoViewPage<PartialViewMacroModel> so that UmbracoHelper, etc... are available.
2012-12-07 06:31:53 +05:00
Shannon Deminick c7645b55ba Partial View Macros now being rendered, now to implement the remaining parts with things like
parameters, etc...
2012-12-04 22:06:55 +05:00
Shannon Deminick 208806c027 Updated more partial view macro engine and its rendering... nearly there. 2012-12-04 11:31:03 +05:00
Shannon Deminick 8024610364 Fixes up some logging API issues. Fixed up tracing in the macro class. Added support for Partial View macro rendering in the macro class. 2012-12-04 11:08:02 +05:00
Shannon Deminick 8e4644568b Updated loghelper to be able to Warn and also trace Warn with an exception. Updated the macro control to check for the
Partial View Macro, added Partial View macro to the enum.
2012-12-04 05:58:24 +05:00
Shannon Deminick e0a71830fa Updated macro editor to support Partial view macros. Improves the JS in the editor (no more c# based js) which auto clears
other fields and drop downs when other files are selected.
2012-12-04 05:42:15 +05:00
Shannon Deminick 5b0057c258 Added missing files. 2012-12-04 03:29:02 +05:00
Shannon Deminick fb61c55fa7 Started on PartialViewMacros 2012-12-04 03:26:04 +05:00
Stephan a70ef52964 fix xpath syntax error with legacy XML schema 2012-11-30 13:33:24 -01:00
Stephan 51204ee401 U4-1212 - bugfix Document.PathPublished 2012-12-11 17:37:33 -01:00
Sebastiaan Janssen 657f165ffb Created branch 4.11.2 2012-12-17 12:22:11 -01:00
Casey Neehouse 3bd98d851a Reverting the config files that inadvertently got committed. 2012-11-29 21:42:37 +05:00
Casey Neehouse 9eea46b19b Modification of UserControl usage to allow for Virtual Path to be used correctly. 2012-11-29 21:27:42 +05:00
Sebastiaan Janssen 76fb5d260f Moved tag Release-4.11.1 to changeset 6eb5f2fb5a88 (from changeset 7f827760cb49) 2012-11-28 13:35:30 -01:00
Sebastiaan Janssen 267cd46ea0 Another additional fix to make the reloading of trees work after package install 2012-11-28 13:34:35 -01:00
Sebastiaan Janssen 96f6a0161f Merge with 4.11.1 2012-11-28 13:08:13 -01:00
Sebastiaan Janssen 7bc53adc67 Closing 4.11.1 branch 2012-11-28 13:06:01 -01:00
Sebastiaan Janssen 8ecff73c18 Added tag Release-4.11.1 for changeset 7f827760cb49 2012-11-28 13:05:21 -01:00
Stephan 35e65ad18c add support for "/foo" hostnames ONLY for backward compat.
fix invalid hostname message
2012-11-28 12:43:19 -01:00
Sebastiaan Janssen 8def8eaa86 Bumping the version to 4.11.1 2012-11-28 09:44:03 -01:00
Sebastiaan Janssen c0774ad9b9 Merge 2012-11-28 09:24:54 -01:00
Sebastiaan Janssen f306cbe457 Move invalidDomain entry to the correct area. 2012-11-28 09:24:40 -01:00
Sebastiaan Janssen 577b989c4c Aha, string needs to start all the way to the left to appear nicely in the editor 2012-11-28 08:41:54 -01:00
Sebastiaan Janssen e6b162f4f6 Add translation for invalid hostname 2012-11-28 08:37:08 -01:00
Stephan b40cc1879f missing entry in language file 2012-11-28 07:36:08 -01:00
Shannon Deminick 8a7c7bf77d Merge 2012-11-27 21:47:20 +05:00
Shannon Deminick 38a1179de5 applied patch from rev 189f37a1dd63 which reverts the last minute changes before 4.11
release, namely changes to the ApplicationTreeRegistrar, TreeDefinitionCollection, theend installer step.
2012-11-27 21:45:57 +05:00
Sebastiaan Janssen f263b4d92b Fixes U4-1162 - In MVC mode, creating a child template doesn't set the layout
correctly (it's missing the .cshtml extension)
2012-11-27 15:36:54 -01:00
Sebastiaan Janssen c612727116 Add translations that got lost in merge, fixes U4-1254 2012-11-27 14:07:13 -01:00
Sebastiaan Janssen ab9c9df7d6 Reverting last minute hacks around the pluginmanager and adding Shannon's fixes
from changeset 85f9e5879e60
2012-11-27 13:27:33 -01:00
Stephan c607e50433 U4-1245, U4-1186... fix the mess I created with hostnames 2012-11-27 12:43:57 -01:00
Stephan df5555bdf1 Opened branch 4.11.1 2012-11-27 12:40:42 -01:00
Sebastiaan Janssen 9506339e6f Merge with 4.11.0 2012-11-23 13:37:17 -01:00
Sebastiaan Janssen 68605a7560 Closed branch 4.11.0 2012-11-23 13:36:14 -01:00
Sebastiaan Janssen 839dd7315a Added tag Release-4.11.0 for changeset 20e4dff821d8 2012-11-23 13:33:15 -01:00
NielsHartvig@UMBRACORATI.localdomain d148c10c66 Update to sanitizer 2012-11-16 14:24:24 -01:00
NielsHartvig@UMBRACORATI.localdomain 2b573b9070 The BOSS is fixing U4-367 2012-11-16 14:08:28 -01:00
102 changed files with 4545 additions and 2181 deletions
+8
View File
@@ -12,3 +12,11 @@ d03fcffb8834a9583a56813bb44b6abbd9f042cc Release-4.6.0
de73e687ddf6086ed52b6554676c1632865d07f2 Release-4.9.0
8d7d8609e2e4b971da99cd97f72132ce85ce3333 Release-4.9.1
f6da531fbb4c251ff61d314e2a7effb13c71e74a Release-4.10.0
20e4dff821d8ac2527a5353618fa1a23ea1d8b34 Release-4.11.0
7f827760cb49d749616859f528d19dde64807947 Release-4.11.1
7f827760cb49d749616859f528d19dde64807947 Release-4.11.1
6eb5f2fb5a88aa29ea544499df9160a1b31b5638 Release-4.11.1
73711b806a4044dbf0d7d7c095ddfdda23b09932 4.11.2
73711b806a4044dbf0d7d7c095ddfdda23b09932 4.11.2
0000000000000000000000000000000000000000 4.11.2
73711b806a4044dbf0d7d7c095ddfdda23b09932 Release-4.11.2
+1 -1
View File
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>UmbracoCms.Core</id>
<version>4.11.0</version>
<version>4.11.2</version>
<title>Umbraco Cms Core Binaries</title>
<authors>Morten Christensen</authors>
<owners>Umbraco HQ</owners>
+2 -2
View File
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>UmbracoCms</id>
<version>4.11.0</version>
<version>4.11.2</version>
<title>Umbraco Cms</title>
<authors>Morten Christensen</authors>
<owners>Umbraco HQ</owners>
@@ -15,7 +15,7 @@
<language>en-US</language>
<tags>umbraco</tags>
<dependencies>
<dependency id="UmbracoCms.Core" version="4.11.0" />
<dependency id="UmbracoCms.Core" version="4.11.2" />
</dependencies>
</metadata>
<files>
@@ -28,7 +28,7 @@ namespace Umbraco.Core.Configuration
#region Private static fields
// CURRENT UMBRACO VERSION ID
private const string CurrentUmbracoVersion = "4.11.0";
private const string CurrentUmbracoVersion = "4.11.2";
private static string _reservedUrlsCache;
private static string _reservedPathsCache;
+121 -110
View File
@@ -4,124 +4,135 @@ using Umbraco.Core.Logging;
namespace Umbraco.Core
{
/// <summary>
/// Starts the timer and invokes a callback upon disposal. Provides a simple way of timing an operation by wrapping it in a <code>using</code> (C#) statement.
/// </summary>
/// <example>
/// <code>
/// Console.WriteLine("Testing Stopwatchdisposable, should be 567:");
// using (var timer = new DisposableTimer(result => Console.WriteLine("Took {0}ms", result)))
// {
// Thread.Sleep(567);
// }
/// </code>
/// </example>
public class DisposableTimer : DisposableObject
{
private readonly Stopwatch _stopwatch = Stopwatch.StartNew();
private readonly Action<long> _callback;
/// <summary>
/// Starts the timer and invokes a callback upon disposal. Provides a simple way of timing an operation by wrapping it in a <code>using</code> (C#) statement.
/// </summary>
/// <example>
/// <code>
/// Console.WriteLine("Testing Stopwatchdisposable, should be 567:");
// using (var timer = new DisposableTimer(result => Console.WriteLine("Took {0}ms", result)))
// {
// Thread.Sleep(567);
// }
/// </code>
/// </example>
public class DisposableTimer : DisposableObject
{
private readonly Stopwatch _stopwatch = Stopwatch.StartNew();
private readonly Action<long> _callback;
protected DisposableTimer(Action<long> callback)
{
_callback = callback;
}
protected DisposableTimer(Action<long> callback)
{
_callback = callback;
}
public Stopwatch Stopwatch
{
get { return _stopwatch; }
}
public Stopwatch Stopwatch
{
get { return _stopwatch; }
}
/// <summary>
/// Starts the timer and invokes the specified callback upon disposal.
/// </summary>
/// <param name="callback">The callback.</param>
/// <returns></returns>
public static DisposableTimer Start(Action<long> callback)
{
return new DisposableTimer(callback);
}
/// <summary>
/// Starts the timer and invokes the specified callback upon disposal.
/// </summary>
/// <param name="callback">The callback.</param>
/// <returns></returns>
public static DisposableTimer Start(Action<long> callback)
{
return new DisposableTimer(callback);
}
/// <summary>
/// Adds a start and end log entry as Info and tracks how long it takes until disposed.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="startMessage"></param>
/// <param name="completeMessage"></param>
/// <returns></returns>
public static DisposableTimer TraceDuration<T>(string startMessage, string completeMessage)
{
return TraceDuration(typeof(T), startMessage, completeMessage);
}
public static DisposableTimer TraceDuration<T>(Func<string> startMessage, Func<string> completeMessage)
{
return TraceDuration(typeof(T), startMessage, completeMessage);
}
/// <summary>
/// Adds a start and end log entry as Info and tracks how long it takes until disposed.
/// </summary>
/// <param name="loggerType"></param>
/// <param name="startMessage"></param>
/// <param name="completeMessage"></param>
/// <returns></returns>
public static DisposableTimer TraceDuration(Type loggerType, string startMessage, string completeMessage)
{
LogHelper.Info(loggerType, () => startMessage);
return new DisposableTimer(x => LogHelper.Info(loggerType, () => completeMessage + " (took " + x + "ms)"));
}
public static DisposableTimer TraceDuration(Type loggerType, Func<string> startMessage, Func<string> completeMessage)
{
LogHelper.Debug(loggerType, startMessage);
return new DisposableTimer(x => LogHelper.Info(loggerType, () => completeMessage() + " (took " + x + "ms)"));
}
/// <summary>
/// Adds a start and end log entry as Debug and tracks how long it takes until disposed.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="startMessage"></param>
/// <param name="completeMessage"></param>
/// <returns></returns>
public static DisposableTimer DebugDuration<T>(string startMessage, string completeMessage)
{
return DebugDuration(typeof(T), startMessage, completeMessage);
}
/// <summary>
/// Adds a start and end log entry as Info and tracks how long it takes until disposed.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="startMessage"></param>
/// <param name="completeMessage"></param>
/// <returns></returns>
public static DisposableTimer TraceDuration<T>(string startMessage, string completeMessage)
{
return TraceDuration(typeof(T), startMessage, completeMessage);
}
/// <summary>
/// Adds a start and end log entry as Debug and tracks how long it takes until disposed.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="startMessage"></param>
/// <param name="completeMessage"></param>
/// <returns></returns>
public static DisposableTimer DebugDuration<T>(Func<string> startMessage, Func<string> completeMessage)
{
return DebugDuration(typeof(T), startMessage, completeMessage);
}
/// <summary>
/// Adds a start and end log entry as Info and tracks how long it takes until disposed.
/// </summary>
/// <param name="loggerType"></param>
/// <param name="startMessage"></param>
/// <param name="completeMessage"></param>
/// <returns></returns>
public static DisposableTimer TraceDuration(Type loggerType, string startMessage, string completeMessage)
{
LogHelper.Info(loggerType, () => startMessage);
return new DisposableTimer(x => LogHelper.Info(loggerType, () => completeMessage + " (took " + x + "ms)"));
}
/// <summary>
/// Adds a start and end log entry as Debug and tracks how long it takes until disposed.
/// </summary>
/// <param name="loggerType"></param>
/// <param name="startMessage"></param>
/// <param name="completeMessage"></param>
/// <returns></returns>
public static DisposableTimer DebugDuration(Type loggerType, string startMessage, string completeMessage)
{
LogHelper.Debug(loggerType, () => startMessage);
return new DisposableTimer(x => LogHelper.Debug(loggerType, () => completeMessage + " (took " + x + "ms)"));
}
/// <summary>
/// Adds a start and end log entry as Debug and tracks how long it takes until disposed.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="startMessage"></param>
/// <param name="completeMessage"></param>
/// <returns></returns>
public static DisposableTimer DebugDuration<T>(string startMessage, string completeMessage)
{
return DebugDuration(typeof(T), startMessage, completeMessage);
}
/// <summary>
/// Adds a start and end log entry as Debug and tracks how long it takes until disposed.
/// </summary>
/// <param name="loggerType"></param>
/// <param name="startMessage"></param>
/// <param name="completeMessage"></param>
/// <returns></returns>
public static DisposableTimer DebugDuration(Type loggerType, Func<string> startMessage, Func<string> completeMessage)
{
LogHelper.Debug(loggerType, startMessage);
return new DisposableTimer(x => LogHelper.Debug(loggerType, () => completeMessage() + " (took " + x + "ms)"));
}
/// <summary>
/// Adds a start and end log entry as Debug and tracks how long it takes until disposed.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="startMessage"></param>
/// <param name="completeMessage"></param>
/// <returns></returns>
public static DisposableTimer DebugDuration<T>(Func<string> startMessage, Func<string> completeMessage)
{
return DebugDuration(typeof(T), startMessage, completeMessage);
}
/// <summary>
/// Handles the disposal of resources. Derived from abstract class <see cref="DisposableObject"/> which handles common required locking logic.
/// </summary>
protected override void DisposeResources()
{
_callback.Invoke(Stopwatch.ElapsedMilliseconds);
}
}
/// <summary>
/// Adds a start and end log entry as Debug and tracks how long it takes until disposed.
/// </summary>
/// <param name="loggerType"></param>
/// <param name="startMessage"></param>
/// <param name="completeMessage"></param>
/// <returns></returns>
public static DisposableTimer DebugDuration(Type loggerType, string startMessage, string completeMessage)
{
LogHelper.Debug(loggerType, () => startMessage);
return new DisposableTimer(x => LogHelper.Debug(loggerType, () => completeMessage + " (took " + x + "ms)"));
}
/// <summary>
/// Adds a start and end log entry as Debug and tracks how long it takes until disposed.
/// </summary>
/// <param name="loggerType"></param>
/// <param name="startMessage"></param>
/// <param name="completeMessage"></param>
/// <returns></returns>
public static DisposableTimer DebugDuration(Type loggerType, Func<string> startMessage, Func<string> completeMessage)
{
LogHelper.Debug(loggerType, startMessage);
return new DisposableTimer(x => LogHelper.Debug(loggerType, () => completeMessage() + " (took " + x + "ms)"));
}
/// <summary>
/// Handles the disposal of resources. Derived from abstract class <see cref="DisposableObject"/> which handles common required locking logic.
/// </summary>
protected override void DisposeResources()
{
_callback.Invoke(Stopwatch.ElapsedMilliseconds);
}
}
}
+7 -3
View File
@@ -220,7 +220,7 @@ namespace Umbraco.Core.IO
{
foreach (var character in Path.GetInvalidFileNameChars())
{
filePath = filePath.Replace(character, '_');
filePath = filePath.Replace(character, '-');
}
}
else
@@ -240,10 +240,14 @@ namespace Umbraco.Core.IO
if (reservedCharacters.IndexOf(character) == -1)
stringBuilder.Append(character);
else
stringBuilder.Append("_");
stringBuilder.Append("-");
}
return stringBuilder.ToString();
// Remove repeating dashes
// From: http://stackoverflow.com/questions/5111967/regex-to-remove-a-specific-repeated-character
var reducedString = Regex.Replace(stringBuilder.ToString(), "-+", "-");
return reducedString;
}
}
}
+23 -13
View File
@@ -1,14 +1,14 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using Umbraco.Core.CodeAnnotations;
using Umbraco.Core.Logging;
namespace Umbraco.Core.IO
{
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1156", "Will be declared public after 4.10")]
internal class PhysicalFileSystem : IFileSystem
{
@@ -43,9 +43,13 @@ namespace Umbraco.Core.IO
return Directory.EnumerateDirectories(path).Select(GetRelativePath);
}
catch (UnauthorizedAccessException ex)
{ }
{
LogHelper.Error<PhysicalFileSystem>("Not authorized to get directories", ex);
}
catch (DirectoryNotFoundException ex)
{ }
{
LogHelper.Error<PhysicalFileSystem>("Directory not found", ex);
}
return Enumerable.Empty<string>();
}
@@ -65,7 +69,9 @@ namespace Umbraco.Core.IO
Directory.Delete(GetFullPath(path), recursive);
}
catch (DirectoryNotFoundException ex)
{ }
{
LogHelper.Error<PhysicalFileSystem>("Directory not found", ex);
}
}
public bool DirectoryExists(string path)
@@ -80,9 +86,7 @@ namespace Umbraco.Core.IO
public void AddFile(string path, Stream stream, bool overrideIfExists)
{
if (FileExists(path) && !overrideIfExists)
throw new InvalidOperationException(string.Format("A file at path '{0}' already exists",
path));
if (FileExists(path) && !overrideIfExists) throw new InvalidOperationException(string.Format("A file at path '{0}' already exists", path));
EnsureDirectory(Path.GetDirectoryName(path));
@@ -108,9 +112,13 @@ namespace Umbraco.Core.IO
return Directory.EnumerateFiles(path, filter).Select(GetRelativePath);
}
catch (UnauthorizedAccessException ex)
{ }
{
LogHelper.Error<PhysicalFileSystem>("Not authorized to get directories", ex);
}
catch (DirectoryNotFoundException ex)
{ }
{
LogHelper.Error<PhysicalFileSystem>("Directory not found", ex);
}
return Enumerable.Empty<string>();
}
@@ -130,7 +138,9 @@ namespace Umbraco.Core.IO
File.Delete(GetFullPath(path));
}
catch (FileNotFoundException ex)
{ }
{
LogHelper.Error<PhysicalFileSystem>("File not found", ex);
}
}
public bool FileExists(string path)
@@ -188,7 +198,7 @@ namespace Umbraco.Core.IO
protected string EnsureTrailingSeparator(string path)
{
if (!path.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal))
if (!path.EndsWith(Path.DirectorySeparatorChar.ToString(CultureInfo.InvariantCulture), StringComparison.Ordinal))
path = path + Path.DirectorySeparatorChar;
return path;
+9
View File
@@ -69,6 +69,15 @@ namespace Umbraco.Core.IO
}
}
public static string AppPlugins
{
get
{
//NOTE: this is not configurable and shouldn't need to be
return "~/App_Plugins";
}
}
public static string MvcViews
{
get
+55 -26
View File
@@ -60,49 +60,77 @@ namespace Umbraco.Core.Logging
#region Warn
public static void Warn(Type callingType, string message, params object[] format)
public static void Warn(Type callingType, string message, params Func<object>[] formatItems)
{
var logger = LogManager.GetLogger(callingType);
if (logger != null)
logger.WarnFormat(PrefixThreadId(message), format);
if (logger == null || !logger.IsWarnEnabled) return;
logger.WarnFormat(PrefixThreadId(message), formatItems.Select(x => x.Invoke()).ToArray());
}
public static void Warn(Type callingType, TraceContext trace, string message, params object[] format)
public static void Warn(Type callingType, string message, bool showHttpTrace, params Func<object>[] formatItems)
{
if (trace != null)
Mandate.ParameterNotNull(callingType, "callingType");
Mandate.ParameterNotNullOrEmpty(message, "message");
if (showHttpTrace && HttpContext.Current != null)
{
trace.Warn(string.Format(message, format));
HttpContext.Current.Trace.Warn(callingType.Name, string.Format(message, formatItems.Select(x => x.Invoke()).ToArray()));
}
var logger = LogManager.GetLogger(callingType);
if (logger != null)
logger.WarnFormat(PrefixThreadId(message), format);
if (logger == null || !logger.IsWarnEnabled) return;
logger.WarnFormat(PrefixThreadId(message), formatItems.Select(x => x.Invoke()).ToArray());
}
public static void WarnWithException(Type callingType, string message, Exception e, params Func<object>[] formatItems)
{
WarnWithException(callingType, message, false, e, formatItems);
}
public static void WarnWithException(Type callingType, string message, bool showHttpTrace, Exception e, params Func<object>[] formatItems)
{
Mandate.ParameterNotNull(e, "e");
Mandate.ParameterNotNull(callingType, "callingType");
Mandate.ParameterNotNullOrEmpty(message, "message");
if (showHttpTrace && HttpContext.Current != null)
{
HttpContext.Current.Trace.Warn(
callingType.Name,
string.Format(message, formatItems.Select(x => x.Invoke()).ToArray()),
e);
}
var logger = LogManager.GetLogger(callingType);
if (logger == null || !logger.IsWarnEnabled) return;
var executedParams = formatItems.Select(x => x.Invoke()).ToArray();
logger.WarnFormat(PrefixThreadId(message) + ". Exception: " + e, executedParams);
}
/// <summary>
/// Adds a warn log
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="message"></param>
/// <param name="items"></param>
public static void Warn<T>(string message, params object[] items)
/// <param name="formatItems"></param>
public static void Warn<T>(string message, params Func<object>[] formatItems)
{
var logger = LoggerFor<T>();
if (logger != null)
logger.WarnFormat(PrefixThreadId(message), items);
Warn(typeof(T), message, formatItems);
}
public static void Warn<T>(string message, TraceContext trace, params object[] items)
public static void Warn<T>(string message, bool showHttpTrace, params Func<object>[] formatItems)
{
if (trace != null)
{
trace.Warn(string.Format(message, items));
}
Warn(typeof(T), message, showHttpTrace, formatItems);
}
var logger = LoggerFor<T>();
if (logger != null)
logger.WarnFormat(PrefixThreadId(message), items);
public static void WarnWithException<T>(string message, Exception e, params Func<object>[] formatItems)
{
WarnWithException(typeof(T), message, e, formatItems);
}
public static void WarnWithException<T>(string message, bool showHttpTrace, Exception e, params Func<object>[] formatItems)
{
WarnWithException(typeof(T), message, showHttpTrace, e, formatItems);
}
#endregion
@@ -214,14 +242,15 @@ namespace Umbraco.Core.Logging
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="generateMessageFormat"></param>
/// <param name="trace"></param>
/// <param name="showHttpTrace"></param>
/// <param name="formatItems"></param>
public static void Debug<T>(string generateMessageFormat, TraceContext trace, params Func<object>[] formatItems)
public static void Debug<T>(string generateMessageFormat, bool showHttpTrace, params Func<object>[] formatItems)
{
if (trace != null)
if (showHttpTrace && HttpContext.Current != null)
{
// must .ToArray() here else string.Format sees only one parameter
trace.Write(string.Format(generateMessageFormat, formatItems.Select(x => x()).ToArray()));
HttpContext.Current.Trace.Write(
typeof(T).Name,
string.Format(generateMessageFormat, formatItems.Select(x => x()).ToArray()));
}
Debug(typeof(T), generateMessageFormat, formatItems);
}
+1 -2
View File
@@ -66,8 +66,7 @@ namespace Umbraco.Core.Macros
}
}
var macroAlias = attributes["macroalias"] ?? attributes["alias"];
var macroAlias = attributes.ContainsKey("macroalias") ? attributes["macroalias"] : attributes["alias"];
//call the callback now that we have the macro parsed
macroFoundCallback(macroAlias, attributes);
File diff suppressed because it is too large Load Diff
+289 -257
View File
@@ -8,12 +8,12 @@ using System.Web.Compilation;
using NUnit.Framework;
using SqlCE4Umbraco;
using Umbraco.Core;
using Umbraco.Core.IO;
using Umbraco.Tests.TestHelpers;
using Umbraco.Web;
using umbraco;
using umbraco.DataLayer;
using umbraco.MacroEngines;
using umbraco.MacroEngines.Iron;
using umbraco.businesslogic;
using umbraco.cms.businesslogic;
using umbraco.editorControls;
@@ -24,21 +24,21 @@ using umbraco.cms;
namespace Umbraco.Tests
{
[TestFixture]
public class PluginManagerTests
{
[TestFixture]
public class PluginManagerTests
{
[SetUp]
public void Initialize()
{
TestHelper.SetupLog4NetForTests();
[SetUp]
public void Initialize()
{
TestHelper.SetupLog4NetForTests();
//this ensures its reset
PluginManager.Current = new PluginManager(false);
//this ensures its reset
PluginManager.Current = new PluginManager(false);
//for testing, we'll specify which assemblies are scanned for the PluginTypeResolver
//TODO: Should probably update this so it only searches this assembly and add custom types to be found
PluginManager.Current.AssembliesToScan = new[]
//for testing, we'll specify which assemblies are scanned for the PluginTypeResolver
//TODO: Should probably update this so it only searches this assembly and add custom types to be found
PluginManager.Current.AssembliesToScan = new[]
{
this.GetType().Assembly,
typeof(ApplicationStartupHandler).Assembly,
@@ -54,286 +54,318 @@ namespace Umbraco.Tests
typeof(System.Web.Mvc.ActionResult).Assembly,
typeof(TypeFinder).Assembly,
typeof(ISqlHelper).Assembly,
typeof(DLRScriptingEngine).Assembly,
typeof(ICultureDictionary).Assembly,
typeof(UmbracoContext).Assembly,
typeof(BaseDataType).Assembly
};
}
}
private DirectoryInfo PrepareFolder()
{
var assDir = new FileInfo(Assembly.GetExecutingAssembly().Location).Directory;
var dir = Directory.CreateDirectory(Path.Combine(assDir.FullName, "PluginManager", Guid.NewGuid().ToString("N")));
foreach (var f in dir.GetFiles())
{
f.Delete();
}
return dir;
}
private DirectoryInfo PrepareFolder()
{
var assDir = new FileInfo(Assembly.GetExecutingAssembly().Location).Directory;
var dir = Directory.CreateDirectory(Path.Combine(assDir.FullName, "PluginManager", Guid.NewGuid().ToString("N")));
foreach (var f in dir.GetFiles())
{
f.Delete();
}
return dir;
}
//[Test]
//public void Scan_Vs_Load_Benchmark()
//{
// var pluginManager = new PluginManager(false);
// var watch = new Stopwatch();
// watch.Start();
// for (var i = 0; i < 1000; i++)
// {
// var type2 = Type.GetType("umbraco.macroCacheRefresh, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null");
// var type3 = Type.GetType("umbraco.templateCacheRefresh, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null");
// var type4 = Type.GetType("umbraco.presentation.cache.MediaLibraryRefreshers, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null");
// var type5 = Type.GetType("umbraco.presentation.cache.pageRefresher, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null");
// }
// watch.Stop();
// Debug.WriteLine("TOTAL TIME (1st round): " + watch.ElapsedMilliseconds);
// watch.Start();
// for (var i = 0; i < 1000; i++)
// {
// var type2 = BuildManager.GetType("umbraco.macroCacheRefresh, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null", true);
// var type3 = BuildManager.GetType("umbraco.templateCacheRefresh, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null", true);
// var type4 = BuildManager.GetType("umbraco.presentation.cache.MediaLibraryRefreshers, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null", true);
// var type5 = BuildManager.GetType("umbraco.presentation.cache.pageRefresher, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null", true);
// }
// watch.Stop();
// Debug.WriteLine("TOTAL TIME (1st round): " + watch.ElapsedMilliseconds);
// watch.Reset();
// watch.Start();
// for (var i = 0; i < 1000; i++)
// {
// var refreshers = pluginManager.ResolveTypes<ICacheRefresher>(false);
// }
// watch.Stop();
// Debug.WriteLine("TOTAL TIME (2nd round): " + watch.ElapsedMilliseconds);
//}
//[Test]
//public void Scan_Vs_Load_Benchmark()
//{
// var pluginManager = new PluginManager(false);
// var watch = new Stopwatch();
// watch.Start();
// for (var i = 0; i < 1000; i++)
// {
// var type2 = Type.GetType("umbraco.macroCacheRefresh, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null");
// var type3 = Type.GetType("umbraco.templateCacheRefresh, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null");
// var type4 = Type.GetType("umbraco.presentation.cache.MediaLibraryRefreshers, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null");
// var type5 = Type.GetType("umbraco.presentation.cache.pageRefresher, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null");
// }
// watch.Stop();
// Debug.WriteLine("TOTAL TIME (1st round): " + watch.ElapsedMilliseconds);
// watch.Start();
// for (var i = 0; i < 1000; i++)
// {
// var type2 = BuildManager.GetType("umbraco.macroCacheRefresh, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null", true);
// var type3 = BuildManager.GetType("umbraco.templateCacheRefresh, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null", true);
// var type4 = BuildManager.GetType("umbraco.presentation.cache.MediaLibraryRefreshers, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null", true);
// var type5 = BuildManager.GetType("umbraco.presentation.cache.pageRefresher, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null", true);
// }
// watch.Stop();
// Debug.WriteLine("TOTAL TIME (1st round): " + watch.ElapsedMilliseconds);
// watch.Reset();
// watch.Start();
// for (var i = 0; i < 1000; i++)
// {
// var refreshers = pluginManager.ResolveTypes<ICacheRefresher>(false);
// }
// watch.Stop();
// Debug.WriteLine("TOTAL TIME (2nd round): " + watch.ElapsedMilliseconds);
//}
////NOTE: This test shows that Type.GetType is 100% faster than Assembly.Load(..).GetType(...) so we'll use that :)
//[Test]
//public void Load_Type_Benchmark()
//{
// var watch = new Stopwatch();
// watch.Start();
// for (var i = 0; i < 1000; i++)
// {
// var type2 = Type.GetType("umbraco.macroCacheRefresh, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null");
// var type3 = Type.GetType("umbraco.templateCacheRefresh, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null");
// var type4 = Type.GetType("umbraco.presentation.cache.MediaLibraryRefreshers, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null");
// var type5 = Type.GetType("umbraco.presentation.cache.pageRefresher, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null");
// }
// watch.Stop();
// Debug.WriteLine("TOTAL TIME (1st round): " + watch.ElapsedMilliseconds);
// watch.Reset();
// watch.Start();
// for (var i = 0; i < 1000; i++)
// {
// var type2 = Assembly.Load("umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null")
// .GetType("umbraco.macroCacheRefresh");
// var type3 = Assembly.Load("umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null")
// .GetType("umbraco.templateCacheRefresh");
// var type4 = Assembly.Load("umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null")
// .GetType("umbraco.presentation.cache.MediaLibraryRefreshers");
// var type5 = Assembly.Load("umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null")
// .GetType("umbraco.presentation.cache.pageRefresher");
// }
// watch.Stop();
// Debug.WriteLine("TOTAL TIME (2nd round): " + watch.ElapsedMilliseconds);
// watch.Reset();
// watch.Start();
// for (var i = 0; i < 1000; i++)
// {
// var type2 = BuildManager.GetType("umbraco.macroCacheRefresh, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null", true);
// var type3 = BuildManager.GetType("umbraco.templateCacheRefresh, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null", true);
// var type4 = BuildManager.GetType("umbraco.presentation.cache.MediaLibraryRefreshers, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null", true);
// var type5 = BuildManager.GetType("umbraco.presentation.cache.pageRefresher, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null", true);
// }
// watch.Stop();
// Debug.WriteLine("TOTAL TIME (1st round): " + watch.ElapsedMilliseconds);
//}
////NOTE: This test shows that Type.GetType is 100% faster than Assembly.Load(..).GetType(...) so we'll use that :)
//[Test]
//public void Load_Type_Benchmark()
//{
// var watch = new Stopwatch();
// watch.Start();
// for (var i = 0; i < 1000; i++)
// {
// var type2 = Type.GetType("umbraco.macroCacheRefresh, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null");
// var type3 = Type.GetType("umbraco.templateCacheRefresh, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null");
// var type4 = Type.GetType("umbraco.presentation.cache.MediaLibraryRefreshers, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null");
// var type5 = Type.GetType("umbraco.presentation.cache.pageRefresher, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null");
// }
// watch.Stop();
// Debug.WriteLine("TOTAL TIME (1st round): " + watch.ElapsedMilliseconds);
// watch.Reset();
// watch.Start();
// for (var i = 0; i < 1000; i++)
// {
// var type2 = Assembly.Load("umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null")
// .GetType("umbraco.macroCacheRefresh");
// var type3 = Assembly.Load("umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null")
// .GetType("umbraco.templateCacheRefresh");
// var type4 = Assembly.Load("umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null")
// .GetType("umbraco.presentation.cache.MediaLibraryRefreshers");
// var type5 = Assembly.Load("umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null")
// .GetType("umbraco.presentation.cache.pageRefresher");
// }
// watch.Stop();
// Debug.WriteLine("TOTAL TIME (2nd round): " + watch.ElapsedMilliseconds);
// watch.Reset();
// watch.Start();
// for (var i = 0; i < 1000; i++)
// {
// var type2 = BuildManager.GetType("umbraco.macroCacheRefresh, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null", true);
// var type3 = BuildManager.GetType("umbraco.templateCacheRefresh, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null", true);
// var type4 = BuildManager.GetType("umbraco.presentation.cache.MediaLibraryRefreshers, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null", true);
// var type5 = BuildManager.GetType("umbraco.presentation.cache.pageRefresher, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null", true);
// }
// watch.Stop();
// Debug.WriteLine("TOTAL TIME (1st round): " + watch.ElapsedMilliseconds);
//}
[Test]
public void Create_Cached_Plugin_File()
{
var types = new[] {typeof (PluginManager), typeof (PluginManagerTests), typeof (UmbracoContext)};
[Test]
public void Detect_Legacy_Plugin_File_List()
{
var tempFolder = IOHelper.MapPath("~/App_Data/TEMP/PluginCache");
var manager = new PluginManager(false);
var filePath = Path.Combine(tempFolder, "umbraco-plugins.list");
File.WriteAllText(filePath, @"<?xml version=""1.0"" encoding=""utf-8""?>
<plugins>
<baseType type=""umbraco.interfaces.ICacheRefresher"">
<add type=""umbraco.macroCacheRefresh, umbraco, Version=6.0.0.0, Culture=neutral, PublicKeyToken=null"" />
</baseType>
</plugins>");
var manager = new PluginManager(false);
//yes this is silly, none of these types inherit from string, but this is just to test the xml file format
manager.UpdateCachedPluginsFile<string>(types);
Assert.IsTrue(manager.DetectLegacyPluginListFile());
var plugins = manager.TryGetCachedPluginsFromFile<string>();
Assert.IsTrue(plugins.Success);
Assert.AreEqual(3, plugins.Result.Count());
var shouldContain = types.Select(x => x.AssemblyQualifiedName);
//ensure they are all found
Assert.IsTrue(plugins.Result.ContainsAll(shouldContain));
}
File.Delete(filePath);
[Test]
public void PluginHash_From_String()
{
var s = "hello my name is someone".GetHashCode().ToString("x", CultureInfo.InvariantCulture);
var output = PluginManager.ConvertPluginsHashFromHex(s);
Assert.AreNotEqual(0, output);
}
//now create a valid one
File.WriteAllText(filePath, @"<?xml version=""1.0"" encoding=""utf-8""?>
<plugins>
<baseType type=""umbraco.interfaces.ICacheRefresher"" resolutionType=""FindAllTypes"">
<add type=""umbraco.macroCacheRefresh, umbraco, Version=6.0.0.0, Culture=neutral, PublicKeyToken=null"" />
</baseType>
</plugins>");
[Test]
public void Get_Plugins_Hash()
{
//Arrange
var dir = PrepareFolder();
var d1 = dir.CreateSubdirectory("1");
var d2 = dir.CreateSubdirectory("2");
var d3 = dir.CreateSubdirectory("3");
var d4 = dir.CreateSubdirectory("4");
var f1 = new FileInfo(Path.Combine(d1.FullName, "test1.dll"));
var f2 = new FileInfo(Path.Combine(d1.FullName, "test2.dll"));
var f3 = new FileInfo(Path.Combine(d2.FullName, "test1.dll"));
var f4 = new FileInfo(Path.Combine(d2.FullName, "test2.dll"));
var f5 = new FileInfo(Path.Combine(d3.FullName, "test1.dll"));
var f6 = new FileInfo(Path.Combine(d3.FullName, "test2.dll"));
var f7 = new FileInfo(Path.Combine(d4.FullName, "test1.dll"));
f1.CreateText().Close();
f2.CreateText().Close();
f3.CreateText().Close();
f4.CreateText().Close();
f5.CreateText().Close();
f6.CreateText().Close();
f7.CreateText().Close();
var list1 = new[] { f1, f2, f3, f4, f5, f6 };
var list2 = new[] { f1, f3, f5 };
var list3 = new[] { f1, f3, f5, f7 };
Assert.IsFalse(manager.DetectLegacyPluginListFile());
}
//Act
var hash1 = PluginManager.GetAssembliesHash(list1);
var hash2 = PluginManager.GetAssembliesHash(list2);
var hash3 = PluginManager.GetAssembliesHash(list3);
[Test]
public void Create_Cached_Plugin_File()
{
var types = new[] { typeof(PluginManager), typeof(PluginManagerTests), typeof(UmbracoContext) };
//Assert
var manager = new PluginManager(false);
//yes this is silly, none of these types inherit from string, but this is just to test the xml file format
manager.UpdateCachedPluginsFile<string>(types, PluginManager.TypeResolutionKind.FindAllTypes);
//both should be the same since we only create the hash based on the unique folder of the list passed in, yet
//all files will exist in those folders still
Assert.AreEqual(hash1, hash2);
Assert.AreNotEqual(hash1, hash3);
}
var plugins = manager.TryGetCachedPluginsFromFile<string>(PluginManager.TypeResolutionKind.FindAllTypes);
var diffType = manager.TryGetCachedPluginsFromFile<string>(PluginManager.TypeResolutionKind.FindAttributedTypes);
[Test]
public void Ensure_Only_One_Type_List_Created()
{
var foundTypes1 = PluginManager.Current.ResolveFindMeTypes();
var foundTypes2 = PluginManager.Current.ResolveFindMeTypes();
Assert.AreEqual(1,
PluginManager.Current.GetTypeLists()
.Count(x => x.IsTypeList<IFindMe>(PluginManager.TypeResolutionKind.FindAllTypes)));
}
Assert.IsTrue(plugins.Success);
//this will be false since there is no cache of that type resolution kind
Assert.IsFalse(diffType.Success);
[Test]
public void Resolves_Types()
{
var foundTypes1 = PluginManager.Current.ResolveFindMeTypes();
Assert.AreEqual(2, foundTypes1.Count());
}
Assert.AreEqual(3, plugins.Result.Count());
var shouldContain = types.Select(x => x.AssemblyQualifiedName);
//ensure they are all found
Assert.IsTrue(plugins.Result.ContainsAll(shouldContain));
}
[Test]
public void Resolves_Attributed_Trees()
{
var trees = PluginManager.Current.ResolveAttributedTrees();
Assert.AreEqual(27, trees.Count());
}
[Test]
public void PluginHash_From_String()
{
var s = "hello my name is someone".GetHashCode().ToString("x", CultureInfo.InvariantCulture);
var output = PluginManager.ConvertPluginsHashFromHex(s);
Assert.AreNotEqual(0, output);
}
[Test]
public void Resolves_Actions()
{
var actions = PluginManager.Current.ResolveActions();
Assert.AreEqual(37, actions.Count());
}
[Test]
public void Get_Plugins_Hash()
{
//Arrange
var dir = PrepareFolder();
var d1 = dir.CreateSubdirectory("1");
var d2 = dir.CreateSubdirectory("2");
var d3 = dir.CreateSubdirectory("3");
var d4 = dir.CreateSubdirectory("4");
var f1 = new FileInfo(Path.Combine(d1.FullName, "test1.dll"));
var f2 = new FileInfo(Path.Combine(d1.FullName, "test2.dll"));
var f3 = new FileInfo(Path.Combine(d2.FullName, "test1.dll"));
var f4 = new FileInfo(Path.Combine(d2.FullName, "test2.dll"));
var f5 = new FileInfo(Path.Combine(d3.FullName, "test1.dll"));
var f6 = new FileInfo(Path.Combine(d3.FullName, "test2.dll"));
var f7 = new FileInfo(Path.Combine(d4.FullName, "test1.dll"));
f1.CreateText().Close();
f2.CreateText().Close();
f3.CreateText().Close();
f4.CreateText().Close();
f5.CreateText().Close();
f6.CreateText().Close();
f7.CreateText().Close();
var list1 = new[] { f1, f2, f3, f4, f5, f6 };
var list2 = new[] { f1, f3, f5 };
var list3 = new[] { f1, f3, f5, f7 };
[Test]
public void Resolves_Trees()
{
var trees = PluginManager.Current.ResolveTrees();
Assert.AreEqual(36, trees.Count());
}
//Act
var hash1 = PluginManager.GetAssembliesHash(list1);
var hash2 = PluginManager.GetAssembliesHash(list2);
var hash3 = PluginManager.GetAssembliesHash(list3);
[Test]
public void Resolves_Applications()
{
var apps = PluginManager.Current.ResolveApplications();
Assert.AreEqual(7, apps.Count());
}
//Assert
Assert.AreNotEqual(hash1, hash2);
Assert.AreNotEqual(hash1, hash3);
Assert.AreNotEqual(hash2, hash3);
[Test]
public void Resolves_Action_Handlers()
{
var types = PluginManager.Current.ResolveActionHandlers();
Assert.AreEqual(1, types.Count());
}
Assert.AreEqual(hash1, PluginManager.GetAssembliesHash(list1));
}
[Test]
public void Resolves_DataTypes()
{
var types = PluginManager.Current.ResolveDataTypes();
Assert.AreEqual(37, types.Count());
}
[Test]
public void Ensure_Only_One_Type_List_Created()
{
var foundTypes1 = PluginManager.Current.ResolveFindMeTypes();
var foundTypes2 = PluginManager.Current.ResolveFindMeTypes();
Assert.AreEqual(1,
PluginManager.Current.GetTypeLists()
.Count(x => x.IsTypeList<IFindMe>(PluginManager.TypeResolutionKind.FindAllTypes)));
}
[Test]
public void Resolves_RazorDataTypeModels()
{
var types = PluginManager.Current.ResolveRazorDataTypeModels();
Assert.AreEqual(2, types.Count());
}
[Test]
public void Resolves_Types()
{
var foundTypes1 = PluginManager.Current.ResolveFindMeTypes();
Assert.AreEqual(2, foundTypes1.Count());
}
[Test]
public void Resolves_RestExtensions()
{
var types = PluginManager.Current.ResolveRestExtensions();
Assert.AreEqual(2, types.Count());
}
[Test]
public void Resolves_Attributed_Trees()
{
var trees = PluginManager.Current.ResolveAttributedTrees();
Assert.AreEqual(27, trees.Count());
}
[Test]
public void Resolves_LegacyRestExtensions()
{
var types = PluginManager.Current.ResolveLegacyRestExtensions();
Assert.AreEqual(1, types.Count());
}
[Test]
public void Resolves_Actions()
{
var actions = PluginManager.Current.ResolveActions();
Assert.AreEqual(37, actions.Count());
}
[Test]
public void Resolves_XsltExtensions()
{
var types = PluginManager.Current.ResolveXsltExtensions();
Assert.AreEqual(1, types.Count());
}
[Test]
public void Resolves_Trees()
{
var trees = PluginManager.Current.ResolveTrees();
Assert.AreEqual(36, trees.Count());
}
[XsltExtension("Blah.Blah")]
public class MyXsltExtension
{
[Test]
public void Resolves_Applications()
{
var apps = PluginManager.Current.ResolveApplications();
Assert.AreEqual(7, apps.Count());
}
}
[Test]
public void Resolves_Action_Handlers()
{
var types = PluginManager.Current.ResolveActionHandlers();
Assert.AreEqual(1, types.Count());
}
[umbraco.presentation.umbracobase.RestExtension("Blah")]
public class MyLegacyRestExtension
{
}
[Test]
public void Resolves_DataTypes()
{
var types = PluginManager.Current.ResolveDataTypes();
Assert.AreEqual(37, types.Count());
}
[Umbraco.Web.BaseRest.RestExtension("Blah")]
public class MyRestExtesion
{
}
[Test]
public void Resolves_RazorDataTypeModels()
{
var types = PluginManager.Current.ResolveRazorDataTypeModels();
Assert.AreEqual(2, types.Count());
}
public interface IFindMe
{
[Test]
public void Resolves_RestExtensions()
{
var types = PluginManager.Current.ResolveRestExtensions();
Assert.AreEqual(2, types.Count());
}
}
[Test]
public void Resolves_LegacyRestExtensions()
{
var types = PluginManager.Current.ResolveLegacyRestExtensions();
Assert.AreEqual(1, types.Count());
}
public class FindMe1 : IFindMe
{
[Test]
public void Resolves_XsltExtensions()
{
var types = PluginManager.Current.ResolveXsltExtensions();
Assert.AreEqual(1, types.Count());
}
}
[XsltExtension("Blah.Blah")]
public class MyXsltExtension
{
public class FindMe2 : IFindMe
{
}
}
[umbraco.presentation.umbracobase.RestExtension("Blah")]
public class MyLegacyRestExtension
{
}
}
[Umbraco.Web.BaseRest.RestExtension("Blah")]
public class MyRestExtesion
{
}
public interface IFindMe
{
}
public class FindMe1 : IFindMe
{
}
public class FindMe2 : IFindMe
{
}
}
}
+18
View File
@@ -288,6 +288,7 @@
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Umbraco\developer\Macros\EditMacro.aspx.cs">
<DependentUpon>editMacro.aspx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="Umbraco\developer\Macros\EditMacro.aspx.designer.cs">
@@ -414,6 +415,7 @@
<DependentUpon>UI.xml</DependentUpon>
</None>
<Content Include="Global.asax" />
<Content Include="Umbraco\config\lang\en_us.xml" />
<Content Include="Umbraco\config\lang\he.xml" />
<Content Include="Umbraco\config\lang\ja.xml" />
<Content Include="Umbraco\config\lang\pl.xml" />
@@ -984,6 +986,10 @@
<Content Include="umbraco_client\tinymce3\plugins\umbracocss\js\dialog.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracocss\langs\en.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracocss\langs\en_dlg.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracocss\langs\en_us.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracocss\langs\en_us_dlg.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracocss\langs\it.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracocss\langs\it_dlg.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracocss\langs\ru.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracocss\langs\ru_dlg.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracocss\langs\zh.js" />
@@ -994,8 +1000,14 @@
<Content Include="umbraco_client\tinymce3\plugins\umbracoembed\img\ajax-loader.gif" />
<Content Include="umbraco_client\tinymce3\plugins\umbracoembed\img\embed.gif" />
<Content Include="umbraco_client\tinymce3\plugins\umbracoembed\js\dialog.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracoembed\langs\de.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracoembed\langs\de_dlg.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracoembed\langs\en.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracoembed\langs\en_dlg.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracoembed\langs\en_us.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracoembed\langs\en_us_dlg.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracoembed\langs\it.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracoembed\langs\it_dlg.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracoembed\langs\ru.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracoembed\langs\ru_dlg.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracoembed\langs\zh.js" />
@@ -1003,6 +1015,7 @@
<Content Include="umbraco_client\tinymce3\plugins\umbracoimg\editor_plugin_src.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracoimg\js\image.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracoimg\langs\en_dlg.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracoimg\langs\en_us_dlg.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracoimg\langs\he_dlg.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracoimg\langs\ja_dlg.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracoimg\langs\ru_dlg.js" />
@@ -1010,6 +1023,7 @@
<Content Include="umbraco_client\tinymce3\plugins\umbracolink\editor_plugin_src.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracolink\js\umbracolink.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracolink\langs\en_dlg.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracolink\langs\en_us_dlg.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracolink\langs\he_dlg.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracolink\langs\ja_dlg.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracolink\langs\ru_dlg.js" />
@@ -1020,6 +1034,8 @@
<Content Include="umbraco_client\tinymce3\plugins\umbracomacro\js\dialog.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracomacro\langs\en.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracomacro\langs\en_dlg.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracomacro\langs\en_us.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracomacro\langs\en_us_dlg.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracomacro\langs\he.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracomacro\langs\he_dlg.js" />
<Content Include="umbraco_client\tinymce3\plugins\umbracomacro\langs\ja.js" />
@@ -1187,6 +1203,8 @@
<Content Include="umbraco_client\tinymce3\themes\umbraco\langs\de_dlg.js" />
<Content Include="umbraco_client\tinymce3\themes\umbraco\langs\en.js" />
<Content Include="umbraco_client\tinymce3\themes\umbraco\langs\en_dlg.js" />
<Content Include="umbraco_client\tinymce3\themes\umbraco\langs\en_us.js" />
<Content Include="umbraco_client\tinymce3\themes\umbraco\langs\en_us_dlg.js" />
<Content Include="umbraco_client\tinymce3\themes\umbraco\langs\es.js" />
<Content Include="umbraco_client\tinymce3\themes\umbraco\langs\es_dlg.js" />
<Content Include="umbraco_client\tinymce3\themes\umbraco\langs\fr.js" />
+15 -15
View File
@@ -2,19 +2,19 @@
<!-- this is the pre-4.10 rest configuration -->
<!-- you should use BaseRestExtensions.config instead -->
<RestExtensions>
<!-- available for backward compatibility only -->
<ext assembly="umbraco" type="umbraco.presentation.umbracobase.library.member" alias="currentMember">
<permission method="login" allowAll="true" />
<permission method="logout" allowAll="true" />
<permission method="id" allowAll="true" />
<permission method="data" allowAll="true" />
<permission method="logout" allowAll="true" />
<permission method="setProperty" allowAll="false" />
</ext>
<!-- here for backward compatibility only -->
<!-- because really, it should not be enabled by default -->
<ext assembly="Runway.Blog" type="Runway.Blog.Library.Base" alias="umbBlog">
<permission method="CreateComment" returnXml="false" allowAll="true" />
<permission method="GetGravatarImage" returnXml="false" allowAll="true" />
</ext>
<!-- available for backward compatibility only -->
<ext assembly="umbraco" type="umbraco.presentation.umbracobase.library.member" alias="currentMember">
<permission method="login" allowAll="true" />
<permission method="logout" allowAll="true" />
<permission method="id" allowAll="true" />
<permission method="data" allowAll="true" />
<permission method="logout" allowAll="true" />
<permission method="setProperty" allowAll="false" />
</ext>
<!-- here for backward compatibility only -->
<!-- because really, it should not be enabled by default -->
<ext assembly="Runway.Blog" type="Runway.Blog.Library.Base" alias="umbBlog">
<permission method="CreateComment" returnXml="false" allowAll="true" />
<permission method="GetGravatarImage" returnXml="false" allowAll="true" />
</ext>
</RestExtensions>
@@ -5,7 +5,7 @@
<!-- what file extension that should cause umbraco to create thumbnails -->
<imageFileTypes>jpeg,jpg,gif,bmp,png,tiff,tif</imageFileTypes>
<!-- what attributes that are allowed in the editor on an img tag -->
<allowedAttributes>alt,border,class,style,align,id,name,onclick,usemap</allowedAttributes>
<allowedAttributes>src,alt,border,class,style,align,id,name,onclick,usemap</allowedAttributes>
<!-- automatically updates dimension, filesize and extension attributes on upload -->
<autoFillImageProperties>
<uploadField alias="umbracoFile">
@@ -5,7 +5,7 @@
<!-- what file extension that should cause umbraco to create thumbnails -->
<imageFileTypes>jpeg,jpg,gif,bmp,png,tiff,tif</imageFileTypes>
<!-- what attributes that are allowed in the editor on an img tag -->
<allowedAttributes>alt,border,class,style,align,id,name,onclick,usemap</allowedAttributes>
<allowedAttributes>src,alt,border,class,style,align,id,name,onclick,usemap</allowedAttributes>
<!-- automatically updates dimension, filesize and extension attributes on upload -->
<autoFillImageProperties>
<uploadField alias="umbracoFile">
+166 -78
View File
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<language alias="en" intName="English (uk)" localName="English" lcid="" culture="en-GB">
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<language alias="en" intName="English (UK)" localName="English (UK)" lcid="" culture="en-GB">
<creator>
<name>umbraco</name>
<link>http://umbraco.org</link>
@@ -23,6 +23,7 @@
<key alias="notify">Notifications</key>
<key alias="protect">Public access</key>
<key alias="publish">Publish</key>
<key alias="unpublish">Unpublish</key>
<key alias="refreshNode">Reload nodes</key>
<key alias="republish">Republish entire site</key>
<key alias="rights">Permissions</key>
@@ -36,11 +37,16 @@
</area>
<area alias="assignDomain">
<key alias="addNew">Add new Domain</key>
<key alias="invalidDomain">Invalid hostname</key>
<key alias="domain">Domain</key>
<key alias="domainCreated">New domain '%0%' has been created</key>
<key alias="domainDeleted">Domain '%0%' is deleted</key>
<key alias="domainExists">Domain '%0%' has already been assigned</key>
<key alias="domainHelp">ei: yourdomain.com, www.yourdomain.com</key>
<key alias="domainHelp">
<![CDATA[eg: example.com, www.example.com, example.com:8080,<br/>
https://www.example.com/, example.com/en, etc. Use * to match<br/>
any domain and just set the culture.]]>
</key>
<key alias="domainUpdated">Domain '%0%' has been updated</key>
<key alias="orEdit">Edit Current Domains</key>
</area>
@@ -69,6 +75,7 @@
<key alias="saveAndPublish">Save and publish</key>
<key alias="saveToPublish">Save and send for approval</key>
<key alias="showPage">Preview</key>
<key alias="showPageDisabled">Preview is disabled because there's no template assigned</key>
<key alias="styleChoose">Choose style</key>
<key alias="styleShow">Show styles</key>
<key alias="tableInsert">Insert table</key>
@@ -88,7 +95,7 @@
<key alias="itemNotPublished">This item is not published</key>
<key alias="lastPublished">Last published</key>
<key alias="mediatype">Media Type</key>
<key alias="mediaLinks">Link to media item(s)</key>
<key alias="mediaLinks">Link to media item(s)</key>
<key alias="membergroup">Member Group</key>
<key alias="memberrole">Role</key>
<key alias="membertype">Member Type</key>
@@ -164,18 +171,24 @@
<key alias="siterepublishHelp">The website cache will be refreshed. All published content will be updated, while unpublished content will stay unpublished.</key>
<key alias="tableColumns">Number of columns</key>
<key alias="tableRows">Number of rows</key>
<key alias="templateContentAreaHelp"><![CDATA[<strong>Set a placeholder id</strong> by setting an ID on your placeholder you can inject content into this template from child templates,
by refering this ID using a <code>&lt;asp:content /&gt;</code> element.]]></key>
<key alias="templateContentPlaceHolderHelp"><![CDATA[<strong>Select a placeholder id</strong> from the list below. You can only
choose Id's from the current template's master.]]></key>
<key alias="templateContentAreaHelp">
<![CDATA[<strong>Set a placeholder id</strong> by setting an ID on your placeholder you can inject content into this template from child templates,
by refering this ID using a <code>&lt;asp:content /&gt;</code> element.]]>
</key>
<key alias="templateContentPlaceHolderHelp">
<![CDATA[<strong>Select a placeholder id</strong> from the list below. You can only
choose Id's from the current template's master.]]>
</key>
<key alias="thumbnailimageclickfororiginal">Click on the image to see full size</key>
<key alias="treepicker">Pick item</key>
<key alias="viewCacheItem">View Cache Item</key>
</area>
<area alias="dictionaryItem">
<key alias="description"><![CDATA[
<key alias="description">
<![CDATA[
Edit the different language versions for the dictionary item '<em>%0%</em>' below<br/>You can add additional languages under the 'languages' in the menu on the left
]]></key>
]]>
</key>
<key alias="displayName">Culture Name</key>
</area>
<area alias="editcontenttype">
@@ -340,34 +353,45 @@
<key alias="databaseErrorWebConfig">Could not save the web.config file. Please modify the connection string manually.</key>
<key alias="databaseFound">Your database has been found and is identified as</key>
<key alias="databaseHeader">Database configuration</key>
<key alias="databaseInstall"><![CDATA[
<key alias="databaseInstall">
<![CDATA[
Press the <strong>install</strong> button to install the Umbraco %0% database
]]></key>
]]>
</key>
<key alias="databaseInstallDone"><![CDATA[Umbraco %0% has now been copied to your database. Press <strong>Next</strong> to proceed.]]></key>
<key alias="databaseNotFound"><![CDATA[<p>Database not found! Please check that the information in the "connection string" of the “web.config” file is correct.</p>
<key alias="databaseNotFound">
<![CDATA[<p>Database not found! Please check that the information in the "connection string" of the “web.config” file is correct.</p>
<p>To proceed, please edit the "web.config" file (using Visual Studio or your favourite text editor), scroll to the bottom, add the connection string for your database in the key named "umbracoDbDSN" and save the file. </p>
<p>
Click the <strong>retry</strong> button when
done.<br /><a href="http://umbraco.org/redir/installWebConfig" target="_blank">
More information on editing web.config here.</a></p>]]></key>
<key alias="databaseText"><![CDATA[To complete this step, you must know some information regarding your database server ("connection string").<br />
More information on editing web.config here.</a></p>]]>
</key>
<key alias="databaseText">
<![CDATA[To complete this step, you must know some information regarding your database server ("connection string").<br />
Please contact your ISP if necessary.
If you're installing on a local machine or server you might need information from your system administrator.]]></key>
<key alias="databaseUpgrade"><![CDATA[
If you're installing on a local machine or server you might need information from your system administrator.]]>
</key>
<key alias="databaseUpgrade">
<![CDATA[
<p>
Press the <strong>upgrade</strong> button to upgrade your database to Umbraco %0%</p>
<p>
Don't worry - no content will be deleted and everything will continue working afterwards!
</p>
]]></key>
<key alias="databaseUpgradeDone"><![CDATA[Your database has been upgraded to the final version %0%.<br />Press <strong>Next</strong> to
proceed. ]]></key>
]]>
</key>
<key alias="databaseUpgradeDone">
<![CDATA[Your database has been upgraded to the final version %0%.<br />Press <strong>Next</strong> to
proceed. ]]>
</key>
<key alias="databaseUpToDate"><![CDATA[Your current database is up-to-date!. Click <strong>next</strong> to continue the configuration wizard]]></key>
<key alias="defaultUserChangePass"><![CDATA[<strong>The Default users password needs to be changed!</strong>]]></key>
<key alias="defaultUserDisabled"><![CDATA[<strong>The Default user has been disabled or has no access to umbraco!</strong></p><p>No further actions needs to be taken. Click <b>Next</b> to proceed.]]></key>
<key alias="defaultUserPassChanged"><![CDATA[<strong>The Default user's password has been successfully changed since the installation!</strong></p><p>No further actions needs to be taken. Click <strong>Next</strong> to proceed.]]></key>
<key alias="defaultUserPasswordChanged">The password is changed!</key>
<key alias="defaultUserText"><![CDATA[
<key alias="defaultUserText">
<![CDATA[
<p>
umbraco creates a default user with a login <strong>('admin')</strong> and password <strong>('default')</strong>. It's <strong>important</strong> that the password is
changed to something unique.
@@ -375,48 +399,64 @@
<p>
This step will check the default user's password and suggest if it needs to be changed.
</p>
]]></key>
]]>
</key>
<key alias="greatStart">Get a great start, watch our introduction videos</key>
<key alias="licenseText">By clicking the next button (or modifying the umbracoConfigurationStatus in web.config), you accept the license for this software as specified in the box below. Notice that this umbraco distribution consists of two different licenses, the open source MIT license for the framework and the umbraco freeware license that covers the UI.</key>
<key alias="None">Not installed yet.</key>
<key alias="permissionsAffectedFolders">Affected files and folders</key>
<key alias="permissionsAffectedFoldersMoreInfo">More information on setting up permissions for umbraco here</key>
<key alias="permissionsAffectedFoldersText">You need to grant ASP.NET modify permissions to the following files/folders</key>
<key alias="permissionsAlmostPerfect"><![CDATA[<strong>Your permission settings are almost perfect!</strong><br /><br />
You can run umbraco without problems, but you will not be able to install packages which are recommended to take full advantage of umbraco.]]></key>
<key alias="permissionsAlmostPerfect">
<![CDATA[<strong>Your permission settings are almost perfect!</strong><br /><br />
You can run umbraco without problems, but you will not be able to install packages which are recommended to take full advantage of umbraco.]]>
</key>
<key alias="permissionsHowtoResolve">How to Resolve</key>
<key alias="permissionsHowtoResolveLink">Click here to read the text version</key>
<key alias="permissionsHowtoResolveText"><![CDATA[Watch our <strong>video tutorial</strong> on setting up folder permissions for umbraco or read the text version.]]></key>
<key alias="permissionsMaybeAnIssue"><![CDATA[<strong>Your permission settings might be an issue!</strong>
<key alias="permissionsMaybeAnIssue">
<![CDATA[<strong>Your permission settings might be an issue!</strong>
<br/><br />
You can run umbraco without problems, but you will not be able to create folders or install packages which are recommended to take full advantage of umbraco.]]></key>
<key alias="permissionsNotReady"><![CDATA[<strong>Your permission settings are not ready for umbraco!</strong>
You can run umbraco without problems, but you will not be able to create folders or install packages which are recommended to take full advantage of umbraco.]]>
</key>
<key alias="permissionsNotReady">
<![CDATA[<strong>Your permission settings are not ready for umbraco!</strong>
<br /><br />
In order to run umbraco, you'll need to update your permission settings.]]></key>
<key alias="permissionsPerfect"><![CDATA[<strong>Your permission settings are perfect!</strong><br /><br />
You are ready to run umbraco and install packages!]]></key>
In order to run umbraco, you'll need to update your permission settings.]]>
</key>
<key alias="permissionsPerfect">
<![CDATA[<strong>Your permission settings are perfect!</strong><br /><br />
You are ready to run umbraco and install packages!]]>
</key>
<key alias="permissionsResolveFolderIssues">Resolving folder issue</key>
<key alias="permissionsResolveFolderIssuesLink">Follow this link for more information on problems with ASP.NET and creating folders</key>
<key alias="permissionsSettingUpPermissions">Setting up folder permissions</key>
<key alias="permissionsText"><![CDATA[
<key alias="permissionsText">
<![CDATA[
umbraco needs write/modify access to certain directories in order to store files like pictures and PDF's.
It also stores temporary data (aka: cache) for enhancing the performance of your website.
]]></key>
]]>
</key>
<key alias="runwayFromScratch">I want to start from scratch</key>
<key alias="runwayFromScratchText"><![CDATA[
<key alias="runwayFromScratchText">
<![CDATA[
Your website is completely empty at the moment, so thats perfect if you want to start from scratch and create your own document types and templates.
(<a href="http://umbraco.tv/documentation/videos/for-site-builders/foundation/document-types">learn how</a>)
You can still choose to install Runway later on. Please go to the Developer section and choose Packages.
]]></key>
]]>
</key>
<key alias="runwayHeader">Youve just set up a clean Umbraco platform. What do you want to do next?</key>
<key alias="runwayInstalled">Runway is installed</key>
<key alias="runwayInstalledText"><![CDATA[
<key alias="runwayInstalledText">
<![CDATA[
You have the foundation in place. Select what modules you wish to install on top of it.<br />
This is our list of recommended modules, check off the ones you would like to install, or view the <a href="#" onclick="toggleModules(); return false;" id="toggleModuleList">full list of modules</a>
]]></key>
]]>
</key>
<key alias="runwayOnlyProUsers">Only recommended for experienced users</key>
<key alias="runwaySimpleSite">I want to start with a simple website</key>
<key alias="runwaySimpleSiteText"><![CDATA[
<key alias="runwaySimpleSiteText">
<![CDATA[
<p>
"Runway" is a simple website providing some basic document types and templates. The installer can set up Runway for you automatically,
but you can easily edit, extend or remove it. Its not necessary and you can perfectly use Umbraco without it. However,
@@ -427,7 +467,8 @@
<em>Included with Runway:</em> Home page, Getting Started page, Installing Modules page.<br />
<em>Optional Modules:</em> Top Navigation, Sitemap, Contact, Gallery.
</small>
]]></key>
]]>
</key>
<key alias="runwayWhatIsRunway">What is Runway</key>
<key alias="step1">Step 1/5 Accept license</key>
<key alias="step2">Step 2/5: Database configuration</key>
@@ -435,24 +476,36 @@
<key alias="step4">Step 4/5: Check umbraco security</key>
<key alias="step5">Step 5/5: Umbraco is ready to get you started</key>
<key alias="thankYou">Thank you for choosing umbraco</key>
<key alias="theEndBrowseSite"><![CDATA[<h3>Browse your new site</h3>
You installed Runway, so why not see how your new website looks.]]></key>
<key alias="theEndFurtherHelp"><![CDATA[<h3>Further help and information</h3>
Get help from our award winning community, browse the documentation or watch some free videos on how to build a simple site, how to use packages and a quick guide to the umbraco terminology]]></key>
<key alias="theEndBrowseSite">
<![CDATA[<h3>Browse your new site</h3>
You installed Runway, so why not see how your new website looks.]]>
</key>
<key alias="theEndFurtherHelp">
<![CDATA[<h3>Further help and information</h3>
Get help from our award winning community, browse the documentation or watch some free videos on how to build a simple site, how to use packages and a quick guide to the umbraco terminology]]>
</key>
<key alias="theEndHeader">Umbraco %0% is installed and ready for use</key>
<key alias="theEndInstallFailed"><![CDATA[To finish the installation, you'll need to
manually edit the <strong>/web.config file</strong> and update the AppSetting key <strong>umbracoConfigurationStatus</strong> in the bottom to the value of <strong>'%0%'</strong>.]]></key>
<key alias="theEndInstallSuccess"><![CDATA[You can get <strong>started instantly</strong> by clicking the "Launch Umbraco" button below. <br />If you are <strong>new to umbraco</strong>,
you can find plenty of resources on our getting started pages.]]></key>
<key alias="theEndOpenUmbraco"><![CDATA[<h3>Launch Umbraco</h3>
To manage your website, simply open the umbraco back office and start adding content, updating the templates and stylesheets or add new functionality]]></key>
<key alias="theEndInstallFailed">
<![CDATA[To finish the installation, you'll need to
manually edit the <strong>/web.config file</strong> and update the AppSetting key <strong>umbracoConfigurationStatus</strong> in the bottom to the value of <strong>'%0%'</strong>.]]>
</key>
<key alias="theEndInstallSuccess">
<![CDATA[You can get <strong>started instantly</strong> by clicking the "Launch Umbraco" button below. <br />If you are <strong>new to umbraco</strong>,
you can find plenty of resources on our getting started pages.]]>
</key>
<key alias="theEndOpenUmbraco">
<![CDATA[<h3>Launch Umbraco</h3>
To manage your website, simply open the umbraco back office and start adding content, updating the templates and stylesheets or add new functionality]]>
</key>
<key alias="Unavailable">Connection to database failed.</key>
<key alias="Version3">Umbraco Version 3</key>
<key alias="Version4">Umbraco Version 4</key>
<key alias="watch">Watch</key>
<key alias="welcomeIntro"><![CDATA[This wizard will guide you through the process of configuring <strong>umbraco %0%</strong> for a fresh install or upgrading from version 3.0.
<key alias="welcomeIntro">
<![CDATA[This wizard will guide you through the process of configuring <strong>umbraco %0%</strong> for a fresh install or upgrading from version 3.0.
<br /><br />
Press <strong>"next"</strong> to start the wizard.]]></key>
Press <strong>"next"</strong> to start the wizard.]]>
</key>
</area>
<area alias="language">
<key alias="cultureCode">Culture Code</key>
@@ -486,7 +539,8 @@ To manage your website, simply open the umbraco back office and start adding con
</area>
<area alias="notifications">
<key alias="editNotifications">Edit your notification for %0%</key>
<key alias="mailBody"><![CDATA[
<key alias="mailBody">
<![CDATA[
Hi %0%
This is an automated mail to inform you that the task '%1%'
@@ -498,8 +552,10 @@ To manage your website, simply open the umbraco back office and start adding con
Have a nice day!
Cheers from the umbraco robot
]]></key>
<key alias="mailBodyHtml"><![CDATA[<p>Hi %0%</p>
]]>
</key>
<key alias="mailBodyHtml">
<![CDATA[<p>Hi %0%</p>
<p>This is an automated mail to inform you that the task <strong>'%1%'</strong>
has been performed on the page <a href="%7%"><strong>'%2%'</strong></a>
@@ -529,23 +585,28 @@ To manage your website, simply open the umbraco back office and start adding con
<p>Have a nice day!<br /><br />
Cheers from the umbraco robot
</p>]]></key>
</p>]]>
</key>
<key alias="mailSubject">[%0%] Notification about %1% performed on %2%</key>
<key alias="notifications">Notifications</key>
</area>
<area alias="packager">
<key alias="chooseLocalPackageText"><![CDATA[
<key alias="chooseLocalPackageText">
<![CDATA[
Choose Package from your machine, by clicking the Browse<br />
button and locating the package. umbraco packages usually have a ".umb" or ".zip" extension.
]]></key>
]]>
</key>
<key alias="packageAuthor">Author</key>
<key alias="packageDemonstration">Demonstration</key>
<key alias="packageDocumentation">Documentation</key>
<key alias="packageMetaData">Package meta data</key>
<key alias="packageName">Package name</key>
<key alias="packageNoItemsHeader">Package doesn't contain any items</key>
<key alias="packageNoItemsText"><![CDATA[This package file doesn't contain any items to uninstall.<br/><br/>
You can safely remove this from the system by clicking "uninstall package" below.]]></key>
<key alias="packageNoItemsText">
<![CDATA[This package file doesn't contain any items to uninstall.<br/><br/>
You can safely remove this from the system by clicking "uninstall package" below.]]>
</key>
<key alias="packageNoUpgrades">No upgrades available</key>
<key alias="packageOptions">Package options</key>
<key alias="packageReadme">Package readme</key>
@@ -554,9 +615,11 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="packageUninstalledHeader">Package was uninstalled</key>
<key alias="packageUninstalledText">The package was successfully uninstalled</key>
<key alias="packageUninstallHeader">Uninstall package</key>
<key alias="packageUninstallText"><![CDATA[You can unselect items you do not wish to remove, at this time, below. When you click "confirm uninstall" all checked-off items will be removed.<br />
<key alias="packageUninstallText">
<![CDATA[You can unselect items you do not wish to remove, at this time, below. When you click "confirm uninstall" all checked-off items will be removed.<br />
<span style="color: Red; font-weight: bold;">Notice:</span> any documents, media etc depending on the items you remove, will stop working, and could lead to system instability,
so uninstall with caution. If in doubt, contact the package author.]]></key>
so uninstall with caution. If in doubt, contact the package author.]]>
</key>
<key alias="packageUpgradeDownload">Download update from the repository</key>
<key alias="packageUpgradeHeader">Upgrade package</key>
<key alias="packageUpgradeInstructions">Upgrade instructions</key>
@@ -589,18 +652,27 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="paSimpleHelp">If you just want to setup simple protection using a single login and password</key>
</area>
<area alias="publish">
<key alias="contentPublishedFailedByEvent"><![CDATA[
<key alias="contentPublishedFailedByEvent">
<![CDATA[
%0% could not be published, due to a 3rd party extension cancelling the action.
]]></key>
]]>
</key>
<key alias="contentPublishedFailedByParent">
<![CDATA[
%0% can not be published, because a parent page is not published.
]]>
</key>
<key alias="includeUnpublished">Include unpublished child pages</key>
<key alias="inProgress">Publishing in progress - please wait...</key>
<key alias="inProgressCounter">%0% out of %1% pages have been published...</key>
<key alias="nodePublish">%0% has been published</key>
<key alias="nodePublishAll">%0% and subpages have been published</key>
<key alias="publishAll">Publish %0% and all its subpages</key>
<key alias="publishHelp"><![CDATA[Click <em>ok</em> to publish <strong>%0%</strong> and thereby making it's content publicly available.<br/><br />
<key alias="publishHelp">
<![CDATA[Click <em>ok</em> to publish <strong>%0%</strong> and thereby making it's content publicly available.<br/><br />
You can publish this page and all it's sub-pages by checking <em>publish all children</em> below.
]]></key>
]]>
</key>
</area>
<area alias="relatedlinks">
<key alias="addExternal">Add external link</key>
@@ -652,6 +724,9 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="tab">Tab</key>
<key alias="tabname">Tab Title</key>
<key alias="tabs">Tabs</key>
<key alias="contentTypeEnabled">Master Content Type enabled</key>
<key alias="contentTypeUses">This Content Type uses</key>
<key alias="asAContentMasterType">as a Master Content Type. Tabs from Master Content Types are not shown and can only be edited on the Master Content Type itself</key>
</area>
<area alias="sort">
<key alias="sortDone">Sorting complete.</key>
@@ -686,7 +761,7 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="editTemplateSaved">Template saved</key>
<key alias="editUserError">Error saving user (check log)</key>
<key alias="editUserSaved">User Saved</key>
<key alias="editUserTypeSaved">User type saved</key>
<key alias="editUserTypeSaved">User type saved</key>
<key alias="fileErrorHeader">File not saved</key>
<key alias="fileErrorText">file could not be saved. Please check file permissions</key>
<key alias="fileSavedHeader">File saved</key>
@@ -705,6 +780,11 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="xsltPermissionErrorText">Xslt could not be saved, check file permissions</key>
<key alias="xsltSavedHeader">Xslt saved</key>
<key alias="xsltSavedText">No errors in xslt</key>
<key alias="contentUnpublished">Content unpublished</key>
<key alias="partialViewSavedHeader">Partial view saved</key>
<key alias="partialViewSavedText">Partial view saved without any errors!</key>
<key alias="partialViewErrorHeader">Partial view not saved</key>
<key alias="partialViewErrorText">An error occurred saving the file.</key>
</area>
<area alias="stylesheet">
<key alias="aliasHelp">Uses CSS syntax ex: h1, .redHeader, .blueTex</key>
@@ -732,7 +812,7 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="chooseField">Choose field</key>
<key alias="convertLineBreaks">Convert Linebreaks</key>
<key alias="convertLineBreaksHelp">Replaces linebreaks with html-tag &amp;lt;br&amp;gt;</key>
<key alias="customFields">Custom Fields</key>
<key alias="customFields">Custom Fields</key>
<key alias="dateOnly">Yes, Date only</key>
<key alias="formatAsDate">Format as date</key>
<key alias="htmlEncode">HTML encode</key>
@@ -746,7 +826,7 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="recursive">Recursive</key>
<key alias="removeParagraph">Remove Paragraph tags</key>
<key alias="removeParagraphHelp">Will remove any &amp;lt;P&amp;gt; in the beginning and end of the text</key>
<key alias="standardFields">Standard Fields</key>
<key alias="standardFields">Standard Fields</key>
<key alias="uppercase">Uppercase</key>
<key alias="urlEncode">URL encode</key>
<key alias="urlEncodeHelp">Will format special characters in URLs</key>
@@ -756,10 +836,12 @@ To manage your website, simply open the umbraco back office and start adding con
</area>
<area alias="translation">
<key alias="assignedTasks">Tasks assigned to you</key>
<key alias="assignedTasksHelp"><![CDATA[ The list below shows translation tasks <strong>assigned to you</strong>. To see a detailed view including comments, click on "Details" or just the page name.
<key alias="assignedTasksHelp">
<![CDATA[ The list below shows translation tasks <strong>assigned to you</strong>. To see a detailed view including comments, click on "Details" or just the page name.
You can also download the page as XML directly by clicking the "Download Xml" link. <br/>
To close a translation task, please go to the Details view and click the "Close" button.
]]></key>
]]>
</key>
<key alias="closeTask">close task</key>
<key alias="details">Translation details</key>
<key alias="downloadAllAsXml">Download all translation tasks as xml</key>
@@ -767,7 +849,8 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="DownloadXmlDTD">Download xml DTD</key>
<key alias="fields">Fields</key>
<key alias="includeSubpages">Include subpages</key>
<key alias="mailBody"><![CDATA[
<key alias="mailBody">
<![CDATA[
Hi %0%
This is an automated mail to inform you that the document '%1%'
@@ -781,14 +864,17 @@ To manage your website, simply open the umbraco back office and start adding con
Have a nice day!
Cheers from the umbraco robot
]]></key>
]]>
</key>
<key alias="mailSubject">[%0%] Translation task for %1%</key>
<key alias="noTranslators">No translator users found. Please create a translator user before you start sending content to translation</key>
<key alias="ownedTasks">Tasks created by you</key>
<key alias="ownedTasksHelp"><![CDATA[ The list below shows pages <strong>created by you</strong>. To see a detailed view including comments,
<key alias="ownedTasksHelp">
<![CDATA[ The list below shows pages <strong>created by you</strong>. To see a detailed view including comments,
click on "Details" or just the page name. You can also download the page as XML directly by clicking the "Download Xml" link.
To close a translation task, please go to the Details view and click the "Close" button.
]]></key>
]]>
</key>
<key alias="pageHasBeenSendToTranslation">The page '%0%' has been send to translation</key>
<key alias="sendToTranslate">Send the page '%0%' to translation</key>
<key alias="taskAssignedBy">Assigned by</key>
@@ -821,7 +907,7 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="memberType">Member Types</key>
<key alias="nodeTypes">Document Types</key>
<key alias="packager">Packages</key>
<key alias="packages">Packages</key>
<key alias="packages">Packages</key>
<key alias="python">Python Files</key>
<key alias="repositories">Install from repository</key>
<key alias="runway">Install Runway</key>
@@ -842,6 +928,8 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="administrators">Administrator</key>
<key alias="categoryField">Category field</key>
<key alias="changePassword">Change Your Password</key>
<key alias="newPassword">Change Your Password</key>
<key alias="confirmNewPassword">Confirm new password</key>
<key alias="changePasswordDescription">You can change your password for accessing the Umbraco Back Office by filling out the form below and click the 'Change Password' button</key>
<key alias="contentChannel">Content Channel</key>
<key alias="defaultToLiveEditing">Redirect to canvas on login</key>
@@ -859,9 +947,9 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="passwordChanged">Your password has been changed!</key>
<key alias="passwordConfirm">Please confirm the new password</key>
<key alias="passwordEnterNew">Enter your new password</key>
<key alias="passwordIsBlank">Your new password cannot be blank!</key>
<key alias="passwordCurrent">Current password</key>
<key alias="passwordInvalid">Invalid current password</key>
<key alias="passwordIsBlank">Your new password cannot be blank!</key>
<key alias="passwordCurrent">Current password</key>
<key alias="passwordInvalid">Invalid current password</key>
<key alias="passwordIsDifferent">There was a difference between the new password and the confirmed password. Please try again!</key>
<key alias="passwordMismatch">The confirmed password doesn't match the new password!</key>
<key alias="permissionReplaceChildren">Replace child node permssions</key>
@@ -875,4 +963,4 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="userTypes">User types</key>
<key alias="writer">Writer</key>
</area>
</language>
</language>
@@ -0,0 +1,964 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<language alias="en_us" intName="English (US)" localName="English (US)" lcid="" culture="en-US">
<creator>
<name>umbraco</name>
<link>http://umbraco.org</link>
</creator>
<area alias="actions">
<key alias="assignDomain">Manage hostnames</key>
<key alias="auditTrail">Audit Trail</key>
<key alias="browse">Browse Node</key>
<key alias="copy">Copy</key>
<key alias="create">Create</key>
<key alias="createPackage">Create Package</key>
<key alias="delete">Delete</key>
<key alias="disable">Disable</key>
<key alias="emptyTrashcan">Empty recycle bin</key>
<key alias="exportDocumentType">Export Document Type</key>
<key alias="importDocumentType">Import Document Type</key>
<key alias="importPackage">Import Package</key>
<key alias="liveEdit">Edit in Canvas</key>
<key alias="logout">Exit</key>
<key alias="move">Move</key>
<key alias="notify">Notifications</key>
<key alias="protect">Public access</key>
<key alias="publish">Publish</key>
<key alias="refreshNode">Reload nodes</key>
<key alias="republish">Republish entire site</key>
<key alias="rights">Permissions</key>
<key alias="rollback">Rollback</key>
<key alias="sendtopublish">Send To Publish</key>
<key alias="sendToTranslate">Send To Translation</key>
<key alias="sort">Sort</key>
<key alias="toPublish">Send to publication</key>
<key alias="translate">Translate</key>
<key alias="update">Update</key>
</area>
<area alias="assignDomain">
<key alias="addNew">Add new Domain</key>
<key alias="invalidDomain">Invalid hostname</key>
<key alias="domain">Domain</key>
<key alias="domainCreated">New domain '%0%' has been created</key>
<key alias="domainDeleted">Domain '%0%' is deleted</key>
<key alias="domainExists">Domain '%0%' has already been assigned</key>
<key alias="domainHelp">
<![CDATA[eg: example.com, www.example.com, example.com:8080,<br/>
https://www.example.com/, example.com/en, etc. Use * to match<br/>
any domain and just set the culture.]]>
</key>
<key alias="domainUpdated">Domain '%0%' has been updated</key>
<key alias="orEdit">Edit Current Domains</key>
</area>
<area alias="auditTrails">
<key alias="atViewingFor">Viewing for</key>
</area>
<area alias="buttons">
<key alias="bold">Bold</key>
<key alias="deindent">Cancel Paragraph Indent</key>
<key alias="formFieldInsert">Insert form field</key>
<key alias="graphicHeadline">Insert graphic headline</key>
<key alias="htmlEdit">Edit Html</key>
<key alias="indent">Indent Paragraph</key>
<key alias="italic">Italic</key>
<key alias="justifyCenter">Center</key>
<key alias="justifyLeft">Justify Left</key>
<key alias="justifyRight">Justify Right</key>
<key alias="linkInsert">Insert Link</key>
<key alias="linkLocal">Insert local link (anchor)</key>
<key alias="listBullet">Bullet List</key>
<key alias="listNumeric">Numeric List</key>
<key alias="macroInsert">Insert macro</key>
<key alias="pictureInsert">Insert picture</key>
<key alias="relations">Edit relations</key>
<key alias="save">Save</key>
<key alias="saveAndPublish">Save and publish</key>
<key alias="saveToPublish">Save and send for approval</key>
<key alias="showPage">Preview</key>
<key alias="showPageDisabled">Preview is disabled because there's no template assigned</key>
<key alias="styleChoose">Choose style</key>
<key alias="styleShow">Show styles</key>
<key alias="tableInsert">Insert table</key>
</area>
<area alias="content">
<key alias="about">About this page</key>
<key alias="alias">Alias</key>
<key alias="alternativeTextHelp">(how would you describe the picture over the phone)</key>
<key alias="alternativeUrls">Alternative Links</key>
<key alias="clickToEdit">Click to edit this item</key>
<key alias="createBy">Created by</key>
<key alias="createDate">Created</key>
<key alias="documentType">Document Type</key>
<key alias="editing">Editing</key>
<key alias="expireDate">Remove at</key>
<key alias="itemChanged">This item has been changed after publication</key>
<key alias="itemNotPublished">This item is not published</key>
<key alias="lastPublished">Last published</key>
<key alias="mediatype">Media Type</key>
<key alias="mediaLinks">Link to media item(s)</key>
<key alias="membergroup">Member Group</key>
<key alias="memberrole">Role</key>
<key alias="membertype">Member Type</key>
<key alias="noDate">No date chosen</key>
<key alias="nodeName">Page Title</key>
<key alias="otherElements">Properties</key>
<key alias="parentNotPublished">This document is published but is not visible because the parent '%0%' is unpublished</key>
<key alias="publish">Publish</key>
<key alias="publishStatus">Publication Status</key>
<key alias="releaseDate">Publish at</key>
<key alias="removeDate">Clear Date</key>
<key alias="sortDone">Sortorder is updated</key>
<key alias="sortHelp">To sort the nodes, simply drag the nodes or click one of the column headers. You can select multiple nodes by holding the "shift" or "control" key while selecting</key>
<key alias="statistics">Statistics</key>
<key alias="titleOptional">Title (optional)</key>
<key alias="type">Type</key>
<key alias="unPublish">Unpublish</key>
<key alias="updateDate">Last edited</key>
<key alias="uploadClear">Remove file</key>
<key alias="urls">Link to document</key>
</area>
<area alias="create">
<key alias="chooseNode">Where do you want to create the new %0%</key>
<key alias="createUnder">Create at</key>
<key alias="updateData">Choose a type and a title</key>
</area>
<area alias="dashboard">
<key alias="browser">Browse your website</key>
<key alias="dontShowAgain">- Hide</key>
<key alias="nothinghappens">If umbraco isn't opening, you might need to allow popups from this site</key>
<key alias="openinnew">has opened in a new window</key>
<key alias="restart">Restart</key>
<key alias="visit">Visit</key>
<key alias="welcome">Welcome</key>
</area>
<area alias="defaultdialogs">
<key alias="anchorInsert">Name</key>
<key alias="assignDomain">Manage hostnames</key>
<key alias="closeThisWindow">Close this window</key>
<key alias="confirmdelete">Are you sure you want to delete</key>
<key alias="confirmdisable">Are you sure you want to disable</key>
<key alias="confirmEmptyTrashcan">Please check this box to confirm deletion of %0% item(s)</key>
<key alias="confirmlogout">Are you sure?</key>
<key alias="confirmSure">Are you sure?</key>
<key alias="cut">Cut</key>
<key alias="editdictionary">Edit Dictionary Item</key>
<key alias="editlanguage">Edit Language</key>
<key alias="insertAnchor">Insert local link</key>
<key alias="insertCharacter">Insert character</key>
<key alias="insertgraphicheadline">Insert graphic headline</key>
<key alias="insertimage">Insert picture</key>
<key alias="insertlink">Insert link</key>
<key alias="insertMacro">Click to add a Macro</key>
<key alias="inserttable">Insert table</key>
<key alias="lastEdited">Last Edited</key>
<key alias="link">Link</key>
<key alias="linkinternal">Internal link:</key>
<key alias="linklocaltip">When using local links, insert "#" infront of link</key>
<key alias="linknewwindow">Open in new window?</key>
<key alias="macroContainerSettings">Macro Settings</key>
<key alias="macroDoesNotHaveProperties">This macro does not contain any properties you can edit</key>
<key alias="paste">Paste</key>
<key alias="permissionsEdit">Edit Permissions for</key>
<key alias="recycleBinDeleting">The items in the recycle bin is now being deleted. Please do not close this window while this operation takes place</key>
<key alias="recycleBinIsEmpty">The recycle bin is now empty</key>
<key alias="recycleBinWarning">When items are deleted from the recycle bin, they will be gone forever</key>
<key alias="regexSearchError"><![CDATA[<a target='_blank' href='http://regexlib.com'>regexlib.com</a>'s webservice is currently experiencing some problems, which we have no control over. We are very sorry for this inconvenience.]]></key>
<key alias="regexSearchHelp">Search for a regular expression to add validation to a form field. Exemple: 'email, 'zip-code' 'url'</key>
<key alias="removeMacro">Remove Macro</key>
<key alias="requiredField">Required Field</key>
<key alias="sitereindexed">Site is reindexed</key>
<key alias="siterepublished">The website cache has been refreshed. All publish content is now uptodate. While all unpublished content is still unpublished</key>
<key alias="siterepublishHelp">The website cache will be refreshed. All published content will be updated, while unpublished content will stay unpublished.</key>
<key alias="tableColumns">Number of columns</key>
<key alias="tableRows">Number of rows</key>
<key alias="templateContentAreaHelp">
<![CDATA[<strong>Set a placeholder id</strong> by setting an ID on your placeholder you can inject content into this template from child templates,
by refering this ID using a <code>&lt;asp:content /&gt;</code> element.]]>
</key>
<key alias="templateContentPlaceHolderHelp">
<![CDATA[<strong>Select a placeholder id</strong> from the list below. You can only
choose Id's from the current template's master.]]>
</key>
<key alias="thumbnailimageclickfororiginal">Click on the image to see full size</key>
<key alias="treepicker">Pick item</key>
<key alias="viewCacheItem">View Cache Item</key>
</area>
<area alias="dictionaryItem">
<key alias="description">
<![CDATA[
Edit the different language versions for the dictionary item '<em>%0%</em>' below<br/>You can add additional languages under the 'languages' in the menu on the left
]]>
</key>
<key alias="displayName">Culture Name</key>
</area>
<area alias="editcontenttype">
<key alias="allowedchildnodetypes">Allowed child nodetypes</key>
<key alias="create">Create</key>
<key alias="deletetab">Delete tab</key>
<key alias="description">Description</key>
<key alias="newtab">New tab</key>
<key alias="tab">Tab</key>
<key alias="thumbnail">Thumbnail</key>
</area>
<area alias="editdatatype">
<key alias="addPrevalue">Add prevalue</key>
<key alias="dataBaseDatatype">Database datatype</key>
<key alias="guid">Data Editor GUID</key>
<key alias="renderControl">Render control</key>
<key alias="rteButtons">Buttons</key>
<key alias="rteEnableAdvancedSettings">Enable advanced settings for</key>
<key alias="rteEnableContextMenu">Enable context menu</key>
<key alias="rteMaximumDefaultImgSize">Maximum default size of inserted images</key>
<key alias="rteRelatedStylesheets">Related stylesheets</key>
<key alias="rteShowLabel">Show label</key>
<key alias="rteWidthAndHeight">Width and height</key>
</area>
<area alias="errorHandling">
<key alias="errorButDataWasSaved">Your data has been saved, but before you can publish this page there are some errors you need to fix first:</key>
<key alias="errorChangingProviderPassword">The current MemberShip Provider does not support changing password (EnablePasswordRetrieval need to be true)</key>
<key alias="errorExistsWithoutTab">%0% already exists</key>
<key alias="errorHeader">There were errors:</key>
<key alias="errorHeaderWithoutTab">There were errors:</key>
<key alias="errorInPasswordFormat">The password should be a minimum of %0% characters long and contain at least %1% non-alpha numeric character(s)</key>
<key alias="errorIntegerWithoutTab">%0% must be an integer</key>
<key alias="errorMandatory">The %0% field in the %1% tab is mandatory</key>
<key alias="errorMandatoryWithoutTab">%0% is a mandatory field</key>
<key alias="errorRegExp">%0% at %1% is not in a correct format</key>
<key alias="errorRegExpWithoutTab">%0% is not in a correct format</key>
</area>
<area alias="errors">
<key alias="codemirroriewarning">NOTE! Even though CodeMirror is enabled by configuration, it is disabled in Internet Explorer because it's not stable enough.</key>
<key alias="contentTypeAliasAndNameNotNull">Please fill both alias and name on the new propertytype!</key>
<key alias="filePermissionsError">There is a problem with read/write access to a specific file or folder</key>
<key alias="missingTitle">Please enter a title</key>
<key alias="missingType">Please choose a type</key>
<key alias="pictureResizeBiggerThanOrg">You're about to make the picture larger than the original size. Are you sure that you want to proceed?</key>
<key alias="pythonErrorHeader">Error in python script</key>
<key alias="pythonErrorText">The python script has not been saved, because it contained error(s)</key>
<key alias="startNodeDoesNotExists">Startnode deleted, please contact your administrator</key>
<key alias="stylesMustMarkBeforeSelect">Please mark content before changing style</key>
<key alias="stylesNoStylesOnPage">No active styles available</key>
<key alias="tableColMergeLeft">Please place cursor at the left of the two cells you wish to merge</key>
<key alias="tableSplitNotSplittable">You cannot split a cell that hasn't been merged.</key>
<key alias="xsltErrorHeader">Error in xslt source</key>
<key alias="xsltErrorText">The XSLT has not been saved, because it contained error(s)</key>
</area>
<area alias="general">
<key alias="about">About</key>
<key alias="action">Action</key>
<key alias="add">Add</key>
<key alias="alias">Alias</key>
<key alias="areyousure">Are you sure?</key>
<key alias="border">Border</key>
<key alias="by">or</key>
<key alias="cancel">Cancel</key>
<key alias="cellMargin">Cell margin</key>
<key alias="choose">Choose</key>
<key alias="close">Close</key>
<key alias="closewindow">Close Window</key>
<key alias="comment">Comment</key>
<key alias="confirm">Confirm</key>
<key alias="constrainProportions">Constrain proportions</key>
<key alias="continue">Continue</key>
<key alias="copy">Copy</key>
<key alias="create">Create</key>
<key alias="database">Database</key>
<key alias="date">Date</key>
<key alias="default">Default</key>
<key alias="delete">Delete</key>
<key alias="deleted">Deleted</key>
<key alias="deleting">Deleting...</key>
<key alias="design">Design</key>
<key alias="dimensions">Dimensions</key>
<key alias="down">Down</key>
<key alias="download">Download</key>
<key alias="edit">Edit</key>
<key alias="edited">Edited</key>
<key alias="elements">Elements</key>
<key alias="email">Email</key>
<key alias="error">Error</key>
<key alias="findDocument">Find</key>
<key alias="height">Height</key>
<key alias="help">Help</key>
<key alias="icon">Icon</key>
<key alias="import">Import</key>
<key alias="innerMargin">Inner margin</key>
<key alias="insert">Insert</key>
<key alias="install">Install</key>
<key alias="justify">Justify</key>
<key alias="language">Language</key>
<key alias="layout">Layout</key>
<key alias="loading">Loading</key>
<key alias="locked">Locked</key>
<key alias="login">Login</key>
<key alias="logoff">Log off</key>
<key alias="logout">Logout</key>
<key alias="macro">Macro</key>
<key alias="move">Move</key>
<key alias="name">Name</key>
<key alias="new">New</key>
<key alias="next">Next</key>
<key alias="no">No</key>
<key alias="of">of</key>
<key alias="ok">OK</key>
<key alias="open">Open</key>
<key alias="or">or</key>
<key alias="password">Password</key>
<key alias="path">Path</key>
<key alias="placeHolderID">Placeholder ID</key>
<key alias="pleasewait">One moment please...</key>
<key alias="previous">Previous</key>
<key alias="properties">Properties</key>
<key alias="reciept">Email to receive form data</key>
<key alias="recycleBin">Recycle Bin</key>
<key alias="remaining">Remaining</key>
<key alias="rename">Rename</key>
<key alias="renew">Renew</key>
<key alias="retry">Retry</key>
<key alias="rights">Permissions</key>
<key alias="search">Search</key>
<key alias="server">Server</key>
<key alias="show">Show</key>
<key alias="showPageOnSend">Show page on Send</key>
<key alias="size">Size</key>
<key alias="sort">Sort</key>
<key alias="type">Type</key>
<key alias="typeToSearch">Type to search...</key>
<key alias="up">Up</key>
<key alias="update">Update</key>
<key alias="upgrade">Upgrade</key>
<key alias="upload">Upload</key>
<key alias="url">Url</key>
<key alias="user">User</key>
<key alias="username">Username</key>
<key alias="value">Value</key>
<key alias="view">View</key>
<key alias="welcome">Welcome...</key>
<key alias="width">Width</key>
<key alias="yes">Yes</key>
<key alias="folder">Folder</key>
</area>
<area alias="graphicheadline">
<key alias="backgroundcolor">Background color</key>
<key alias="bold">Bold</key>
<key alias="color">Text color</key>
<key alias="font">Font</key>
<key alias="text">Text</key>
</area>
<area alias="headers">
<key alias="page">Page</key>
</area>
<area alias="installer">
<key alias="databaseErrorCannotConnect">The installer cannot connect to the database.</key>
<key alias="databaseErrorWebConfig">Could not save the web.config file. Please modify the connection string manually.</key>
<key alias="databaseFound">Your database has been found and is identified as</key>
<key alias="databaseHeader">Database configuration</key>
<key alias="databaseInstall">
<![CDATA[
Press the <strong>install</strong> button to install the Umbraco %0% database
]]>
</key>
<key alias="databaseInstallDone"><![CDATA[Umbraco %0% has now been copied to your database. Press <strong>Next</strong> to proceed.]]></key>
<key alias="databaseNotFound">
<![CDATA[<p>Database not found! Please check that the information in the "connection string" of the “web.config” file is correct.</p>
<p>To proceed, please edit the "web.config" file (using Visual Studio or your favourite text editor), scroll to the bottom, add the connection string for your database in the key named "umbracoDbDSN" and save the file. </p>
<p>
Click the <strong>retry</strong> button when
done.<br /><a href="http://umbraco.org/redir/installWebConfig" target="_blank">
More information on editing web.config here.</a></p>]]>
</key>
<key alias="databaseText">
<![CDATA[To complete this step, you must know some information regarding your database server ("connection string").<br />
Please contact your ISP if necessary.
If you're installing on a local machine or server you might need information from your system administrator.]]>
</key>
<key alias="databaseUpgrade">
<![CDATA[
<p>
Press the <strong>upgrade</strong> button to upgrade your database to Umbraco %0%</p>
<p>
Don't worry - no content will be deleted and everything will continue working afterwards!
</p>
]]>
</key>
<key alias="databaseUpgradeDone">
<![CDATA[Your database has been upgraded to the final version %0%.<br />Press <strong>Next</strong> to
proceed. ]]>
</key>
<key alias="databaseUpToDate"><![CDATA[Your current database is up-to-date!. Click <strong>next</strong> to continue the configuration wizard]]></key>
<key alias="defaultUserChangePass"><![CDATA[<strong>The Default users password needs to be changed!</strong>]]></key>
<key alias="defaultUserDisabled"><![CDATA[<strong>The Default user has been disabled or has no access to umbraco!</strong></p><p>No further actions needs to be taken. Click <b>Next</b> to proceed.]]></key>
<key alias="defaultUserPassChanged"><![CDATA[<strong>The Default user's password has been successfully changed since the installation!</strong></p><p>No further actions needs to be taken. Click <strong>Next</strong> to proceed.]]></key>
<key alias="defaultUserPasswordChanged">The password is changed!</key>
<key alias="defaultUserText">
<![CDATA[
<p>
umbraco creates a default user with a login <strong>('admin')</strong> and password <strong>('default')</strong>. It's <strong>important</strong> that the password is
changed to something unique.
</p>
<p>
This step will check the default user's password and suggest if it needs to be changed.
</p>
]]>
</key>
<key alias="greatStart">Get a great start, watch our introduction videos</key>
<key alias="licenseText">By clicking the next button (or modifying the umbracoConfigurationStatus in web.config), you accept the license for this software as specified in the box below. Notice that this umbraco distribution consists of two different licenses, the open source MIT license for the framework and the umbraco freeware license that covers the UI.</key>
<key alias="None">Not installed yet.</key>
<key alias="permissionsAffectedFolders">Affected files and folders</key>
<key alias="permissionsAffectedFoldersMoreInfo">More information on setting up permissions for umbraco here</key>
<key alias="permissionsAffectedFoldersText">You need to grant ASP.NET modify permissions to the following files/folders</key>
<key alias="permissionsAlmostPerfect">
<![CDATA[<strong>Your permission settings are almost perfect!</strong><br /><br />
You can run umbraco without problems, but you will not be able to install packages which are recommended to take full advantage of umbraco.]]>
</key>
<key alias="permissionsHowtoResolve">How to Resolve</key>
<key alias="permissionsHowtoResolveLink">Click here to read the text version</key>
<key alias="permissionsHowtoResolveText"><![CDATA[Watch our <strong>video tutorial</strong> on setting up folder permissions for umbraco or read the text version.]]></key>
<key alias="permissionsMaybeAnIssue">
<![CDATA[<strong>Your permission settings might be an issue!</strong>
<br/><br />
You can run umbraco without problems, but you will not be able to create folders or install packages which are recommended to take full advantage of umbraco.]]>
</key>
<key alias="permissionsNotReady">
<![CDATA[<strong>Your permission settings are not ready for umbraco!</strong>
<br /><br />
In order to run umbraco, you'll need to update your permission settings.]]>
</key>
<key alias="permissionsPerfect">
<![CDATA[<strong>Your permission settings are perfect!</strong><br /><br />
You are ready to run umbraco and install packages!]]>
</key>
<key alias="permissionsResolveFolderIssues">Resolving folder issue</key>
<key alias="permissionsResolveFolderIssuesLink">Follow this link for more information on problems with ASP.NET and creating folders</key>
<key alias="permissionsSettingUpPermissions">Setting up folder permissions</key>
<key alias="permissionsText">
<![CDATA[
umbraco needs write/modify access to certain directories in order to store files like pictures and PDF's.
It also stores temporary data (aka: cache) for enhancing the performance of your website.
]]>
</key>
<key alias="runwayFromScratch">I want to start from scratch</key>
<key alias="runwayFromScratchText">
<![CDATA[
Your website is completely empty at the moment, so thats perfect if you want to start from scratch and create your own document types and templates.
(<a href="http://umbraco.tv/documentation/videos/for-site-builders/foundation/document-types">learn how</a>)
You can still choose to install Runway later on. Please go to the Developer section and choose Packages.
]]>
</key>
<key alias="runwayHeader">Youve just set up a clean Umbraco platform. What do you want to do next?</key>
<key alias="runwayInstalled">Runway is installed</key>
<key alias="runwayInstalledText">
<![CDATA[
You have the foundation in place. Select what modules you wish to install on top of it.<br />
This is our list of recommended modules, check off the ones you would like to install, or view the <a href="#" onclick="toggleModules(); return false;" id="toggleModuleList">full list of modules</a>
]]>
</key>
<key alias="runwayOnlyProUsers">Only recommended for experienced users</key>
<key alias="runwaySimpleSite">I want to start with a simple website</key>
<key alias="runwaySimpleSiteText">
<![CDATA[
<p>
"Runway" is a simple website providing some basic document types and templates. The installer can set up Runway for you automatically,
but you can easily edit, extend or remove it. Its not necessary and you can perfectly use Umbraco without it. However,
Runway offers an easy foundation based on best practices to get you started faster than ever.
If you choose to install Runway, you can optionally select basic building blocks called Runway Modules to enhance your Runway pages.
</p>
<small>
<em>Included with Runway:</em> Home page, Getting Started page, Installing Modules page.<br />
<em>Optional Modules:</em> Top Navigation, Sitemap, Contact, Gallery.
</small>
]]>
</key>
<key alias="runwayWhatIsRunway">What is Runway</key>
<key alias="step1">Step 1/5 Accept license</key>
<key alias="step2">Step 2/5: Database configuration</key>
<key alias="step3">Step 3/5: Validating File Permissions</key>
<key alias="step4">Step 4/5: Check umbraco security</key>
<key alias="step5">Step 5/5: Umbraco is ready to get you started</key>
<key alias="thankYou">Thank you for choosing umbraco</key>
<key alias="theEndBrowseSite">
<![CDATA[<h3>Browse your new site</h3>
You installed Runway, so why not see how your new website looks.]]>
</key>
<key alias="theEndFurtherHelp">
<![CDATA[<h3>Further help and information</h3>
Get help from our award winning community, browse the documentation or watch some free videos on how to build a simple site, how to use packages and a quick guide to the umbraco terminology]]>
</key>
<key alias="theEndHeader">Umbraco %0% is installed and ready for use</key>
<key alias="theEndInstallFailed">
<![CDATA[To finish the installation, you'll need to
manually edit the <strong>/web.config file</strong> and update the AppSetting key <strong>umbracoConfigurationStatus</strong> in the bottom to the value of <strong>'%0%'</strong>.]]>
</key>
<key alias="theEndInstallSuccess">
<![CDATA[You can get <strong>started instantly</strong> by clicking the "Launch Umbraco" button below. <br />If you are <strong>new to umbraco</strong>,
you can find plenty of resources on our getting started pages.]]>
</key>
<key alias="theEndOpenUmbraco">
<![CDATA[<h3>Launch Umbraco</h3>
To manage your website, simply open the umbraco back office and start adding content, updating the templates and stylesheets or add new functionality]]>
</key>
<key alias="Unavailable">Connection to database failed.</key>
<key alias="Version3">Umbraco Version 3</key>
<key alias="Version4">Umbraco Version 4</key>
<key alias="watch">Watch</key>
<key alias="welcomeIntro">
<![CDATA[This wizard will guide you through the process of configuring <strong>umbraco %0%</strong> for a fresh install or upgrading from version 3.0.
<br /><br />
Press <strong>"next"</strong> to start the wizard.]]>
</key>
</area>
<area alias="language">
<key alias="cultureCode">Culture Code</key>
<key alias="displayName">Culture Name</key>
</area>
<area alias="lockout">
<key alias="lockoutWillOccur">You've been idle and logout will automatically occur in</key>
<key alias="renewSession">Renew now to save your work</key>
</area>
<area alias="login">
<key alias="bottomText"><![CDATA[<p style="text-align:right;">&copy; 2001 - %0% <br /><a href="http://umbraco.org" style="text-decoration: none" target="_blank">umbraco.org</a></p> ]]></key>
<key alias="topText">Welcome to umbraco, type your username and password in the boxes below:</key>
</area>
<area alias="main">
<key alias="dashboard">Dashboard</key>
<key alias="sections">Sections</key>
<key alias="tree">Content</key>
</area>
<area alias="moveOrCopy">
<key alias="choose">Choose page above...</key>
<key alias="copyDone">%0% has been copied to %1%</key>
<key alias="copyTo">Select where the document %0% should be copied to below</key>
<key alias="moveDone">%0% has been moved to %1%</key>
<key alias="moveTo">Select where the document %0% should be moved to below</key>
<key alias="nodeSelected">has been selected as the root of your new content, click 'ok' below.</key>
<key alias="noNodeSelected">No node selected yet, please select a node in the list above before clicking 'ok'</key>
<key alias="notAllowedByContentType">The current node is not allowed under the chosen node because of its type</key>
<key alias="notAllowedByPath">The current node cannot be moved to one of its subpages</key>
<key alias="notValid">The action isn't allowed since you have insufficient permissions on 1 or more child documents.</key>
<key alias="relateToOriginal">Relate copied items to original</key>
</area>
<area alias="notifications">
<key alias="editNotifications">Edit your notification for %0%</key>
<key alias="mailBody">
<![CDATA[
Hi %0%
This is an automated mail to inform you that the task '%1%'
has been performed on the page '%2%'
by the user '%3%'
Go to http://%4%/actions/editContent.aspx?id=%5% to edit.
Have a nice day!
Cheers from the umbraco robot
]]>
</key>
<key alias="mailBodyHtml">
<![CDATA[<p>Hi %0%</p>
<p>This is an automated mail to inform you that the task <strong>'%1%'</strong>
has been performed on the page <a href="%7%"><strong>'%2%'</strong></a>
by the user <strong>'%3%'</strong>
</p>
<div style="margin: 8px 0; padding: 8px; display: block;">
<br />
<a style="color: white; font-weight: bold; background-color: #66cc66; text-decoration : none; margin-right: 20px; border: 8px solid #66cc66; width: 150px;" href="http://%4%/actions/publish.aspx?id=%5%">&nbsp;&nbsp;PUBLISH&nbsp;&nbsp;</a> &nbsp;
<a style="color: white; font-weight: bold; background-color: #5372c3; text-decoration : none; margin-right: 20px; border: 8px solid #5372c3; width: 150px;" href="http://%4%/actions/editContent.aspx?id=%5%">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EDIT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</a> &nbsp;
<a style="color: white; font-weight: bold; background-color: #ca4a4a; text-decoration : none; margin-right: 20px; border: 8px solid #ca4a4a; width: 150px;" href="http://%4%/actions/delete.aspx?id=%5%">&nbsp;&nbsp;&nbsp;&nbsp;DELETE&nbsp;&nbsp;&nbsp;&nbsp;</a>
<br />
</div>
<p>
<h3>Update summary:</h3>
<table style="width: 100%;">
%6%
</table>
</p>
<div style="margin: 8px 0; padding: 8px; display: block;">
<br />
<a style="color: white; font-weight: bold; background-color: #66cc66; text-decoration : none; margin-right: 20px; border: 8px solid #66cc66; width: 150px;" href="http://%4%/actions/publish.aspx?id=%5%">&nbsp;&nbsp;PUBLISH&nbsp;&nbsp;</a> &nbsp;
<a style="color: white; font-weight: bold; background-color: #5372c3; text-decoration : none; margin-right: 20px; border: 8px solid #5372c3; width: 150px;" href="http://%4%/actions/editContent.aspx?id=%5%">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EDIT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</a> &nbsp;
<a style="color: white; font-weight: bold; background-color: #ca4a4a; text-decoration : none; margin-right: 20px; border: 8px solid #ca4a4a; width: 150px;" href="http://%4%/actions/delete.aspx?id=%5%">&nbsp;&nbsp;&nbsp;&nbsp;DELETE&nbsp;&nbsp;&nbsp;&nbsp;</a>
<br />
</div>
<p>Have a nice day!<br /><br />
Cheers from the umbraco robot
</p>]]>
</key>
<key alias="mailSubject">[%0%] Notification about %1% performed on %2%</key>
<key alias="notifications">Notifications</key>
</area>
<area alias="packager">
<key alias="chooseLocalPackageText">
<![CDATA[
Choose Package from your machine, by clicking the Browse<br />
button and locating the package. umbraco packages usually have a ".umb" or ".zip" extension.
]]>
</key>
<key alias="packageAuthor">Author</key>
<key alias="packageDemonstration">Demonstration</key>
<key alias="packageDocumentation">Documentation</key>
<key alias="packageMetaData">Package meta data</key>
<key alias="packageName">Package name</key>
<key alias="packageNoItemsHeader">Package doesn't contain any items</key>
<key alias="packageNoItemsText">
<![CDATA[This package file doesn't contain any items to uninstall.<br/><br/>
You can safely remove this from the system by clicking "uninstall package" below.]]>
</key>
<key alias="packageNoUpgrades">No upgrades available</key>
<key alias="packageOptions">Package options</key>
<key alias="packageReadme">Package readme</key>
<key alias="packageRepository">Package repository</key>
<key alias="packageUninstallConfirm">Confirm uninstall</key>
<key alias="packageUninstalledHeader">Package was uninstalled</key>
<key alias="packageUninstalledText">The package was successfully uninstalled</key>
<key alias="packageUninstallHeader">Uninstall package</key>
<key alias="packageUninstallText">
<![CDATA[You can unselect items you do not wish to remove, at this time, below. When you click "confirm uninstall" all checked-off items will be removed.<br />
<span style="color: Red; font-weight: bold;">Notice:</span> any documents, media etc depending on the items you remove, will stop working, and could lead to system instability,
so uninstall with caution. If in doubt, contact the package author.]]>
</key>
<key alias="packageUpgradeDownload">Download update from the repository</key>
<key alias="packageUpgradeHeader">Upgrade package</key>
<key alias="packageUpgradeInstructions">Upgrade instructions</key>
<key alias="packageUpgradeText"> There's an upgrade available for this package. You can download it directly from the umbraco package repository.</key>
<key alias="packageVersion">Package version</key>
<key alias="viewPackageWebsite">View package website</key>
</area>
<area alias="paste">
<key alias="doNothing">Paste with full formatting (Not recommended)</key>
<key alias="errorMessage">The text you're trying to paste contains special characters or formatting. This could be caused by copying text from Microsoft Word. umbraco can remove special characters or formatting automatically, so the pasted content will be more suitable for the web.</key>
<key alias="removeAll">Paste as raw text without any formatting at all</key>
<key alias="removeSpecialFormattering">Paste, but remove formatting (Recommended)</key>
</area>
<area alias="publicAccess">
<key alias="paAdvanced">Role based protection</key>
<key alias="paAdvancedHelp"><![CDATA[If you wish to control access to the page using role-based authentication,<br /> using umbraco's member groups.]]></key>
<key alias="paAdvancedNoGroups"><![CDATA[You need to create a membergroup before you can use <br />role-based authentication.]]></key>
<key alias="paErrorPage">Error Page</key>
<key alias="paErrorPageHelp">Used when people are logged on, but do not have access</key>
<key alias="paHowWould">Choose how to restict access to this page</key>
<key alias="paIsProtected">%0% is now protected</key>
<key alias="paIsRemoved">Protection removed from %0%</key>
<key alias="paLoginPage">Login Page</key>
<key alias="paLoginPageHelp">Choose the page that has the login formular</key>
<key alias="paRemoveProtection">Remove Protection</key>
<key alias="paSelectPages">Select the pages that contain login form and error messages</key>
<key alias="paSelectRoles">Pick the roles who have access to this page</key>
<key alias="paSetLogin">Set the login and password for this page</key>
<key alias="paSimple">Single user protection</key>
<key alias="paSimpleHelp">If you just want to setup simple protection using a single login and password</key>
</area>
<area alias="publish">
<key alias="contentPublishedFailedByEvent">
<![CDATA[
%0% could not be published, due to a 3rd party extension cancelling the action.
]]>
</key>
<key alias="contentPublishedFailedByParent">
<![CDATA[
%0% can not be published, because a parent page is not published.
]]>
</key>
<key alias="includeUnpublished">Include unpublished child pages</key>
<key alias="inProgress">Publishing in progress - please wait...</key>
<key alias="inProgressCounter">%0% out of %1% pages have been published...</key>
<key alias="nodePublish">%0% has been published</key>
<key alias="nodePublishAll">%0% and subpages have been published</key>
<key alias="publishAll">Publish %0% and all its subpages</key>
<key alias="publishHelp">
<![CDATA[Click <em>ok</em> to publish <strong>%0%</strong> and thereby making it's content publicly available.<br/><br />
You can publish this page and all it's sub-pages by checking <em>publish all children</em> below.
]]>
</key>
</area>
<area alias="relatedlinks">
<key alias="addExternal">Add external link</key>
<key alias="addInternal">Add internal link</key>
<key alias="addlink">Add</key>
<key alias="caption">Caption</key>
<key alias="internalPage">Internal page</key>
<key alias="linkurl">URL</key>
<key alias="modeDown">Move Down</key>
<key alias="modeUp">Move Up</key>
<key alias="newWindow">Open in new window</key>
<key alias="removeLink">Remove link</key>
</area>
<area alias="rollback">
<key alias="currentVersion">Current version</key>
<key alias="diffHelp"><![CDATA[This shows the differences between the current version and the selected version<br /><del>Red</del> text will not be shown in the selected version. , <ins>green means added</ins>]]></key>
<key alias="documentRolledBack">Document has been rolled back</key>
<key alias="htmlHelp">This displays the selected version as html, if you wish to see the difference between 2 versions at the same time, use the diff view</key>
<key alias="rollbackTo">Rollback to</key>
<key alias="selectVersion">Select version</key>
<key alias="view">View</key>
</area>
<area alias="scripts">
<key alias="editscript">Edit script file</key>
</area>
<area alias="sections">
<key alias="concierge">Concierge</key>
<key alias="content">Content</key>
<key alias="courier">Courier</key>
<key alias="developer">Developer</key>
<key alias="installer">Umbraco Configuration Wizard</key>
<key alias="media">Media</key>
<key alias="member">Members</key>
<key alias="newsletters">Newsletters</key>
<key alias="settings">Settings</key>
<key alias="statistics">Statistics</key>
<key alias="translation">Translation</key>
<key alias="users">Users</key>
</area>
<area alias="settings">
<key alias="defaulttemplate">Default template</key>
<key alias="dictionary editor egenskab">Dictionary Key</key>
<key alias="importDocumentTypeHelp">To import a document type, find the ".udt" file on your computer by clicking the "Browse" button and click "Import" (you'll be asked for confirmation on the next screen)</key>
<key alias="newtabname">New Tab Title</key>
<key alias="nodetype">Nodetype</key>
<key alias="objecttype">Type</key>
<key alias="stylesheet">Stylesheet</key>
<key alias="stylesheet editor egenskab">Stylesheet property</key>
<key alias="tab">Tab</key>
<key alias="tabname">Tab Title</key>
<key alias="tabs">Tabs</key>
<key alias="contentTypeEnabled">Master Content Type enabled</key>
<key alias="contentTypeUses">This Content Type uses</key>
<key alias="asAContentMasterType">as a Master Content Type. Tabs from Master Content Types are not shown and can only be edited on the Master Content Type itself</key>
</area>
<area alias="sort">
<key alias="sortDone">Sorting complete.</key>
<key alias="sortHelp">Drag the different items up or down below to set how they should be arranged. Or click the column headers to sort the entire collection of items</key>
<key alias="sortPleaseWait"><![CDATA[ Please wait. Items are being sorted, this can take a while.<br/> <br/> Do not close this window during sorting]]></key>
</area>
<area alias="speechBubbles">
<key alias="contentPublishedFailedByEvent">Publising was cancelled by a 3rd party add-in</key>
<key alias="contentTypeDublicatePropertyType">Property type already exists</key>
<key alias="contentTypePropertyTypeCreated">Property type created</key>
<key alias="contentTypePropertyTypeCreatedText"><![CDATA[Name: %0% <br /> DataType: %1%]]></key>
<key alias="contentTypePropertyTypeDeleted">Propertytype deleted</key>
<key alias="contentTypeSavedHeader">Document Type saved</key>
<key alias="contentTypeTabCreated">Tab created</key>
<key alias="contentTypeTabDeleted">Tab deleted</key>
<key alias="contentTypeTabDeletedText">Tab with id: %0% deleted</key>
<key alias="cssErrorHeader">Stylesheet not saved</key>
<key alias="cssSavedHeader">Stylesheet saved</key>
<key alias="cssSavedText">Stylesheet saved without any errors</key>
<key alias="dataTypeSaved">Datatype saved</key>
<key alias="dictionaryItemSaved">Dictionary item saved</key>
<key alias="editContentPublishedFailedByParent">Publising failed because the parent page isn't published</key>
<key alias="editContentPublishedHeader">Content published</key>
<key alias="editContentPublishedText">and visible at the website</key>
<key alias="editContentSavedHeader">Content saved</key>
<key alias="editContentSavedText">Remember to publish to make changes visible</key>
<key alias="editContentSendToPublish">Sent For Approval</key>
<key alias="editContentSendToPublishText">Changes have been sent for approval</key>
<key alias="editMemberSaved">Member saved</key>
<key alias="editStylesheetPropertySaved">Stylesheet Property Saved</key>
<key alias="editStylesheetSaved">Stylesheet saved</key>
<key alias="editTemplateSaved">Template saved</key>
<key alias="editUserError">Error saving user (check log)</key>
<key alias="editUserSaved">User Saved</key>
<key alias="editUserTypeSaved">User type saved</key>
<key alias="fileErrorHeader">File not saved</key>
<key alias="fileErrorText">file could not be saved. Please check file permissions</key>
<key alias="fileSavedHeader">File saved</key>
<key alias="fileSavedText">File saved without any errors</key>
<key alias="languageSaved">Language saved</key>
<key alias="pythonErrorHeader">Python script not saved</key>
<key alias="pythonErrorText">Python script could not be saved due to error</key>
<key alias="pythonSavedHeader">Python script saved</key>
<key alias="pythonSavedText">No errors in python script</key>
<key alias="templateErrorHeader">Template not saved</key>
<key alias="templateErrorText">Please make sure that you do not have 2 templates with the same alias</key>
<key alias="templateSavedHeader">Template saved</key>
<key alias="templateSavedText">Template saved without any errors!</key>
<key alias="xsltErrorHeader">Xslt not saved</key>
<key alias="xsltErrorText">Xslt contained an error</key>
<key alias="xsltPermissionErrorText">Xslt could not be saved, check file permissions</key>
<key alias="xsltSavedHeader">Xslt saved</key>
<key alias="xsltSavedText">No errors in xslt</key>
<key alias="partialViewSavedHeader">Partial view saved</key>
<key alias="partialViewSavedText">Partial view saved without any errors!</key>
<key alias="partialViewErrorHeader">Partial view not saved</key>
<key alias="partialViewErrorText">An error occurred saving the file.</key>
</area>
<area alias="stylesheet">
<key alias="aliasHelp">Uses CSS syntax ex: h1, .redHeader, .blueTex</key>
<key alias="editstylesheet">Edit stylesheet</key>
<key alias="editstylesheetproperty">Edit stylesheet property</key>
<key alias="nameHelp">Name to identify the style property in the rich text editor </key>
<key alias="preview">Preview</key>
<key alias="styles">Styles</key>
</area>
<area alias="template">
<key alias="edittemplate">Edit template</key>
<key alias="insertContentArea">Insert content area</key>
<key alias="insertContentAreaPlaceHolder">Insert content area placeholder</key>
<key alias="insertDictionaryItem">Insert dictionary item</key>
<key alias="insertMacro">Insert Macro</key>
<key alias="insertPageField">Insert umbraco page field</key>
<key alias="mastertemplate">Master template</key>
<key alias="quickGuide">Quick Guide to umbraco template tags</key>
<key alias="template">Template</key>
</area>
<area alias="templateEditor">
<key alias="alternativeField">Alternative field</key>
<key alias="alternativeText">Alternative Text</key>
<key alias="casing">Casing</key>
<key alias="chooseField">Choose field</key>
<key alias="convertLineBreaks">Convert Linebreaks</key>
<key alias="convertLineBreaksHelp">Replaces linebreaks with html-tag &amp;lt;br&amp;gt;</key>
<key alias="customFields">Custom Fields</key>
<key alias="dateOnly">Yes, Date only</key>
<key alias="formatAsDate">Format as date</key>
<key alias="htmlEncode">HTML encode</key>
<key alias="htmlEncodeHelp">Will replace special characters by their HTML equivalent.</key>
<key alias="insertedAfter">Will be inserted after the field value</key>
<key alias="insertedBefore">Will be inserted before the field value</key>
<key alias="lowercase">Lowercase</key>
<key alias="none">None</key>
<key alias="postContent">Insert after field</key>
<key alias="preContent">Insert before field</key>
<key alias="recursive">Recursive</key>
<key alias="removeParagraph">Remove Paragraph tags</key>
<key alias="removeParagraphHelp">Will remove any &amp;lt;P&amp;gt; in the beginning and end of the text</key>
<key alias="standardFields">Standard Fields</key>
<key alias="uppercase">Uppercase</key>
<key alias="urlEncode">URL encode</key>
<key alias="urlEncodeHelp">Will format special characters in URLs</key>
<key alias="usedIfAllEmpty">Will only be used when the field values above are empty</key>
<key alias="usedIfEmpty">This field will only be used if the primary field is empty</key>
<key alias="withTime">Yes, with time. Seperator: </key>
</area>
<area alias="translation">
<key alias="assignedTasks">Tasks assigned to you</key>
<key alias="assignedTasksHelp">
<![CDATA[ The list below shows translation tasks <strong>assigned to you</strong>. To see a detailed view including comments, click on "Details" or just the page name.
You can also download the page as XML directly by clicking the "Download Xml" link. <br/>
To close a translation task, please go to the Details view and click the "Close" button.
]]>
</key>
<key alias="closeTask">close task</key>
<key alias="details">Translation details</key>
<key alias="downloadAllAsXml">Download all translation tasks as xml</key>
<key alias="downloadTaskAsXml">Download xml</key>
<key alias="DownloadXmlDTD">Download xml DTD</key>
<key alias="fields">Fields</key>
<key alias="includeSubpages">Include subpages</key>
<key alias="mailBody">
<![CDATA[
Hi %0%
This is an automated mail to inform you that the document '%1%'
has been requested for translation into '%5%' by %2%.
Go to http://%3%/translation/details.aspx?id=%4% to edit.
Or log into umbraco to get an overview of your translation tasks
http://%3%/umbraco.aspx
Have a nice day!
Cheers from the umbraco robot
]]>
</key>
<key alias="mailSubject">[%0%] Translation task for %1%</key>
<key alias="noTranslators">No translator users found. Please create a translator user before you start sending content to translation</key>
<key alias="ownedTasks">Tasks created by you</key>
<key alias="ownedTasksHelp">
<![CDATA[ The list below shows pages <strong>created by you</strong>. To see a detailed view including comments,
click on "Details" or just the page name. You can also download the page as XML directly by clicking the "Download Xml" link.
To close a translation task, please go to the Details view and click the "Close" button.
]]>
</key>
<key alias="pageHasBeenSendToTranslation">The page '%0%' has been send to translation</key>
<key alias="sendToTranslate">Send the page '%0%' to translation</key>
<key alias="taskAssignedBy">Assigned by</key>
<key alias="taskOpened">Task opened</key>
<key alias="totalWords">Total words</key>
<key alias="translateTo">Translate to</key>
<key alias="translationDone">Translation completed.</key>
<key alias="translationDoneHelp">You can preview the pages, you've just translated, by clicking below. If the original page is found, you will get a comparison of the 2 pages.</key>
<key alias="translationFailed">Translation failed, the xml file might be corrupt</key>
<key alias="translationOptions">Translation options</key>
<key alias="translator">Translator</key>
<key alias="uploadTranslationXml">Upload translation xml</key>
</area>
<area alias="treeHeaders">
<key alias="cacheBrowser">Cache Browser</key>
<key alias="contentRecycleBin">Recycle Bin</key>
<key alias="createdPackages">Created packages</key>
<key alias="datatype">Data Types</key>
<key alias="dictionary">Dictionary</key>
<key alias="installedPackages">Installed packages</key>
<key alias="installSkin">Install skin</key>
<key alias="installStarterKit">Install starter kit</key>
<key alias="languages">Languages</key>
<key alias="localPackage">Install local package</key>
<key alias="macros">Macros</key>
<key alias="mediaTypes">Media Types</key>
<key alias="member">Members</key>
<key alias="memberGroup">Member Groups</key>
<key alias="memberRoles">Roles</key>
<key alias="memberType">Member Types</key>
<key alias="nodeTypes">Document Types</key>
<key alias="packager">Packages</key>
<key alias="packages">Packages</key>
<key alias="python">Python Files</key>
<key alias="repositories">Install from repository</key>
<key alias="runway">Install Runway</key>
<key alias="runwayModules">Runway modules</key>
<key alias="scripting">Scripting Files</key>
<key alias="scripts">Scripts</key>
<key alias="stylesheets">Stylesheets</key>
<key alias="templates">Templates</key>
<key alias="xslt">XSLT Files</key>
</area>
<area alias="update">
<key alias="updateAvailable">New update ready</key>
<key alias="updateDownloadText">%0% is ready, click here for download</key>
<key alias="updateNoServer">No connection to server</key>
<key alias="updateNoServerError">Error checking for update. Please review trace-stack for further information</key>
</area>
<area alias="user">
<key alias="administrators">Administrator</key>
<key alias="categoryField">Category field</key>
<key alias="changePassword">Change Your Password</key>
<key alias="newPassword">Change Your Password</key>
<key alias="confirmNewPassword">Confirm new password</key>
<key alias="changePasswordDescription">You can change your password for accessing the Umbraco Back Office by filling out the form below and click the 'Change Password' button</key>
<key alias="contentChannel">Content Channel</key>
<key alias="defaultToLiveEditing">Redirect to canvas on login</key>
<key alias="descriptionField">Description field</key>
<key alias="disabled">Disable User</key>
<key alias="documentType">Document Type</key>
<key alias="editors">Editor</key>
<key alias="excerptField">Excerpt field</key>
<key alias="language">Language</key>
<key alias="loginname">Login</key>
<key alias="mediastartnode">Start Node in Media Library</key>
<key alias="modules">Sections</key>
<key alias="noConsole">Disable Umbraco Access</key>
<key alias="password">Password</key>
<key alias="passwordChanged">Your password has been changed!</key>
<key alias="passwordConfirm">Please confirm the new password</key>
<key alias="passwordEnterNew">Enter your new password</key>
<key alias="passwordIsBlank">Your new password cannot be blank!</key>
<key alias="passwordCurrent">Current password</key>
<key alias="passwordInvalid">Invalid current password</key>
<key alias="passwordIsDifferent">There was a difference between the new password and the confirmed password. Please try again!</key>
<key alias="passwordMismatch">The confirmed password doesn't match the new password!</key>
<key alias="permissionReplaceChildren">Replace child node permssions</key>
<key alias="permissionSelectedPages">You are currently modifying permissions for the pages:</key>
<key alias="permissionSelectPages">Select pages to modify their permissions</key>
<key alias="searchAllChildren">Search all children</key>
<key alias="startnode">Start Node in Content</key>
<key alias="username">Username</key>
<key alias="userPermissions">User permissions</key>
<key alias="usertype">User type</key>
<key alias="userTypes">User types</key>
<key alias="writer">Writer</key>
</area>
</language>
+12 -2
View File
@@ -32,6 +32,7 @@
<key alias="sort">Ordina</key>
<key alias="toPublish">Invia la pubblicazione</key>
<key alias="translate">Traduci</key>
<key alias="unpublish">Annulla pubblicazione</key>
<key alias="update">Aggiorna</key>
</area>
<area alias="assignDomain">
@@ -40,8 +41,9 @@
<key alias="domainCreated"><![CDATA[Il dominio '%0%' è stato creato]]></key>
<key alias="domainDeleted"><![CDATA[Il dominio '%0%' è stato cancellato]]></key>
<key alias="domainExists"><![CDATA[Il dominio '%0%' è già stato assegnato]]></key>
<key alias="domainHelp">per esempio: yourdomain.com, www.yourdomain.com</key>
<key alias="domainHelp"><![CDATA[per esempio: yourdomain.com, www.yourdomain.com]]></key>
<key alias="domainUpdated"><![CDATA[Il dominio '%0%' è stato aggiornato]]></key>
<key alias="invalidDomain">Hostname non valido</key>
<key alias="orEdit">Modifica il dominio corrente</key>
</area>
<area alias="auditTrails">
@@ -69,6 +71,7 @@
<key alias="saveAndPublish">Salva e pubblica</key>
<key alias="saveToPublish">Salva e invia per approvazione</key>
<key alias="showPage">Anteprima</key>
<key alias="showPageDisabled"><![CDATA[L'anteprima è disabilitata dato che non è stato assegnato alcun template]]></key>
<key alias="styleChoose">Scegli lo stile</key>
<key alias="styleShow">Mostra gli stili</key>
<key alias="tableInsert">Inserisci tabella</key>
@@ -553,6 +556,7 @@ Per gestire il tuo sito web, è sufficiente aprire il back office di Umbraco e i
</area>
<area alias="publish">
<key alias="contentPublishedFailedByEvent"><![CDATA[%0% non può esser pubblicato a causa di una estensione di terze parti che causa l'annullamento dell'operazione]]></key>
<key alias="contentPublishedFailedByParent"><![CDATA[%0% non può essere pubblicato perchè una pagina padre non è pubblicata.]]></key>
<key alias="includeUnpublished"><![CDATA[Includi tutte le pagine figlio non pubblicate]]></key>
<key alias="inProgress"><![CDATA[Pubblicazione in corso - attendere...]]></key>
<key alias="inProgressCounter"><![CDATA[%0% su di %1% pagine sono state pubblicate...]]></key>
@@ -600,6 +604,9 @@ Per gestire il tuo sito web, è sufficiente aprire il back office di Umbraco e i
<key alias="users">Utenti</key>
</area>
<area alias="settings">
<key alias="asAContentMasterType"><![CDATA[come tipo di contenuto master. Le tab del tipo di contenuto master non sono mostrate e possono essere modificate solo direttamente dal tipo di contenuto master.]]></key>
<key alias="contentTypeEnabled">Tipo di contenuto master abilitato</key>
<key alias="contentTypeUses">Questo tipo di contenuto usa</key>
<key alias="defaulttemplate"><![CDATA[Template di base]]></key>
<key alias="dictionary editor egenskab"><![CDATA[Dictionary Key]]></key>
<key alias="importDocumentTypeHelp"><![CDATA[Importa un tipo di documento, trova il file con estensione ".udt" sul tuo computer dopo aver cliccato il pulsante "Sfoglia" e poi clicca "Importa" (potrebbe chiederti una conferma nella prossima schermata)]]></key>
@@ -627,6 +634,7 @@ Per gestire il tuo sito web, è sufficiente aprire il back office di Umbraco e i
<key alias="contentTypeTabCreated">Tab creata</key>
<key alias="contentTypeTabDeleted">Tab eliminata</key>
<key alias="contentTypeTabDeletedText">Tab con id: %0% eliminata</key>
<key alias="contentUnpublished">Contenuto non pubblicato</key>
<key alias="cssErrorHeader"><![CDATA[Foglio di stile non salvato]]></key>
<key alias="cssSavedHeader"><![CDATA[Foglio di stile salvato]]></key>
<key alias="cssSavedText"><![CDATA[Foglio di stile salvato correttamente]]></key>
@@ -802,6 +810,7 @@ Per gestire il tuo sito web, è sufficiente aprire il back office di Umbraco e i
<key alias="categoryField">Campo Categoria</key>
<key alias="changePassword">Cambia la tua password</key>
<key alias="changePasswordDescription"><![CDATA[È possibile modificare la password di accesso al Back Office Umbraco compilando il modulo sottostante e clicca sul pulsante 'Modifica password']]></key>
<key alias="confirmNewPassword">Conferma la nuova password</key>
<key alias="contentChannel">Contenuto del canale</key>
<key alias="defaultToLiveEditing">Ridireziona al canvas al login</key>
<key alias="descriptionField">Campo Descrizione</key>
@@ -813,6 +822,7 @@ Per gestire il tuo sito web, è sufficiente aprire il back office di Umbraco e i
<key alias="loginname">Login</key>
<key alias="mediastartnode"><![CDATA[Nodo di inizio nella sezione Media]]></key>
<key alias="modules">Sezioni</key>
<key alias="newPassword">Modifica la tua password</key>
<key alias="noConsole"><![CDATA[Disabilita l'accesso ad Umbraco]]></key>
<key alias="password">Password</key>
<key alias="passwordChanged"><![CDATA[La tua password è stata cambiata!]]></key>
@@ -834,4 +844,4 @@ Per gestire il tuo sito web, è sufficiente aprire il back office di Umbraco e i
<key alias="userTypes"><![CDATA[Tipi Utente]]></key>
<key alias="writer">Writer</key>
</area>
</language>
</language>
+20 -3
View File
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<language alias="ru" intName="Russian" localName="русский" lcid="" culture="ru-RU">
<creator>
<name>Alexander Bryukhov (Unico Design company)</name>
@@ -40,8 +40,13 @@
<key alias="domainCreated">Создан новый домен '%0%'</key>
<key alias="domainDeleted">Домен '%0%' удален</key>
<key alias="domainExists">Домен с именем '%0%' уже существует</key>
<key alias="domainHelp">Например: yourdomain.com, www.yourdomain.com</key>
<key alias="domainHelp">
<![CDATA[Например: example.com, www.example.com, example.com:8080,<br/>
https://www.example.com/, example.com/en, и т.п. Используйте символ '*'<br/>
если домен не важен, а нужно просто установить язык.]]>
</key>
<key alias="domainUpdated">Домен '%0%' обновлен</key>
<key alias="invalidDomain">Неверное имя домена</key>
<key alias="orEdit">Править существующие домены</key>
</area>
<area alias="auditTrails">
@@ -69,6 +74,7 @@
<key alias="saveAndPublish">Сохранить и опубликовать</key>
<key alias="saveToPublish">Сохранить и направить на публикацию</key>
<key alias="showPage">Предварительный просмотр</key>
<key alias="showPageDisabled">Предварительный просмотр запрещен, так как документу не сопоставлен шаблон</key>
<key alias="styleShow">Показать стили</key>
<key alias="styleChoose">Выбрать стиль</key>
<key alias="tableInsert">Вставить таблицу</key>
@@ -265,6 +271,7 @@
<key alias="email">Email адрес</key>
<key alias="error">Ошибка</key>
<key alias="findDocument">Найти</key>
<key alias="folder">Папка</key>
<key alias="height">Высота</key>
<key alias="help">Справка</key>
<key alias="icon">Иконка</key>
@@ -591,6 +598,11 @@
<key alias="contentPublishedFailedByEvent"><![CDATA[
Документ %0% не может быть опубликован. Операцию отменил установленный в системе пакет дополнений.
]]></key>
<key alias="contentPublishedFailedByParent">
<![CDATA[
Документ %0% не может быть опубликован, так как не опубликован его родительский документ.
]]>
</key>
<key alias="includeUnpublished">Включая неопубликованные дочерние документы</key>
<key alias="inProgress">Идет публикация. Пожалуйста, подождите...</key>
<key alias="inProgressCounter">%0% из %1% документов опубликованы...</key>
@@ -640,6 +652,9 @@
<key alias="users">Пользователи</key>
</area>
<area alias="settings">
<key alias="contentTypeEnabled">Родительский тип контента разрешен</key>
<key alias="contentTypeUses">Данный тип контента использует</key>
<key alias="asAContentMasterType">в качестве родительского типа. Вкладки родительского типа не показаны и могут быть изменены непосредственно в родительском типе</key>
<key alias="defaulttemplate">Шаблон по-умолчанию</key>
<key alias="dictionary editor egenskab">Словарная статья</key>
<key alias="importDocumentTypeHelp">Чтобы импортировать тип документа, найдите файл ".udt" на своем компьютере, нажав на кнопку "Обзор", затем нажмите "Импортировать" (на следующем экране будет запрошено подтверждение для этой операции).</key>
@@ -842,6 +857,7 @@
<key alias="categoryField">Поле категории</key>
<key alias="changePassword">Изменить пароль</key>
<key alias="changePasswordDescription">Вы можете сменить свой пароль для доступа к административной панели Umbraco, заполнив нижеследующие поля и нажав на кнопку 'Изменить пароль'</key>
<key alias="confirmNewPassword">Подтверждение нового пароля</key>
<key alias="contentChannel">Канал содержимого</key>
<key alias="defaultToLiveEditing">При входе перевести в режим редактирования "на месте"</key>
<key alias="descriptionField">Поле описания</key>
@@ -853,6 +869,7 @@
<key alias="loginname">Имя входа (логин)</key>
<key alias="mediastartnode">Начальный узел в Медиа-библиотеке</key>
<key alias="modules">Разделы</key>
<key alias="newPassword">Сменить пароль</key>
<key alias="noConsole">Отключить доступ к административной панели Umbraco</key>
<key alias="password">Пароль</key>
<key alias="passwordChanged">Ваш пароль доступа изменен!</key>
@@ -875,4 +892,4 @@
<key alias="userTypes">Типы пользователей</key>
<key alias="writer">Автор</key>
</area>
</language>
</language>
+20 -2
View File
@@ -32,6 +32,7 @@
<key alias="sort">排序</key>
<key alias="toPublish">提交至发布者</key>
<key alias="translate">翻译</key>
<key alias="unpublish">取消发布</key>
<key alias="update">更新</key>
</area>
<area alias="assignDomain">
@@ -40,8 +41,13 @@
<key alias="domainCreated">新域名 '%0%' 已创建</key>
<key alias="domainDeleted">域名 '%0%' 已删除</key>
<key alias="domainExists">域名 '%0%' 已使用</key>
<key alias="domainHelp">例如:yourdomain.com、www.yourdomain.com</key>
<key alias="domainHelp">
<![CDATA[例如:example.com、www.example.com、example.com:8080、<br/>
https://www.example.com/、example.com/en、……使用 * 代表任意域名,<br/>
只需要设置语言部分即可。]]>
</key>
<key alias="domainUpdated">域名 '%0%' 已更新</key>
<key alias="invalidDomain">域名错误</key>
<key alias="orEdit">编辑当前域名</key>
</area>
<area alias="auditTrails">
@@ -69,6 +75,7 @@
<key alias="saveAndPublish">保存并发布</key>
<key alias="saveToPublish">保存并提交审核</key>
<key alias="showPage">预览</key>
<key alias="showPageDisabled">因未设置模板无法预览</key>
<key alias="styleChoose">选择样式</key>
<key alias="styleShow">显示样式</key>
<key alias="tableInsert">插入表格</key>
@@ -580,6 +587,11 @@
<area alias="publish">
<key alias="contentPublishedFailedByEvent"><![CDATA[%0% 无法发布,第三方组件造成失败。
]]></key>
<key alias="contentPublishedFailedByParent">
<![CDATA[
%0% 不能发布,因为上级页面没有发布。
]]>
</key>
<key alias="includeUnpublished">包含未发布的子项</key>
<key alias="inProgress">正在发布,请稍候…</key>
<key alias="inProgressCounter">%0% 中的 %1% 页面已发布…</key>
@@ -629,6 +641,9 @@
<key alias="users">用户</key>
</area>
<area alias="settings">
<key alias="asAContentMasterType">作为主控文档类型. 主控文档类型的标签只能在主控文档类型里修改。</key>
<key alias="contentTypeEnabled">主控文档类型激活</key>
<key alias="contentTypeUses">该文档类型使用</key>
<key alias="defaulttemplate">默认模板</key>
<key alias="dictionary editor egenskab">字典键</key>
<key alias="importDocumentTypeHelp">要导入文档类型,请点击“浏览”按钮,再点击“导入”,然后在您电脑上查找 ".udt"文件导入(下一页中需要您再次确认)</key>
@@ -656,6 +671,7 @@
<key alias="contentTypeTabCreated">选项卡已创建</key>
<key alias="contentTypeTabDeleted">选项卡已删除</key>
<key alias="contentTypeTabDeletedText">id为%0%的选项卡已删除</key>
<key alias="contentUnpublished">内容已取消发布</key>
<key alias="cssErrorHeader">样式表未保存</key>
<key alias="cssSavedHeader">样式表已保存</key>
<key alias="cssSavedText">样式表保存,无错误。</key>
@@ -828,6 +844,7 @@
<key alias="categoryField">分类字段</key>
<key alias="changePassword">更改密码</key>
<key alias="changePasswordDescription">要改变密码,请在框中输入新密码,然后单击“更改密码”。</key>
<key alias="confirmNewPassword">确认新密码</key>
<key alias="contentChannel">内容频道</key>
<key alias="defaultToLiveEditing">登录后进入实时编辑模式</key>
<key alias="descriptionField">描述字段</key>
@@ -839,6 +856,7 @@
<key alias="loginname">登录</key>
<key alias="mediastartnode">默认打开媒体项</key>
<key alias="modules">区域</key>
<key alias="newPassword">更改密码</key>
<key alias="noConsole">禁用后台管理界面</key>
<key alias="password">密码</key>
<key alias="passwordChanged">您的密码已更改!</key>
@@ -860,4 +878,4 @@
<key alias="userTypes">用户类型</key>
<key alias="writer">撰稿人</key>
</area>
</language>
</language>
@@ -1,11 +1,121 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.UI.WebControls;
using Umbraco.Core.IO;
using Umbraco.Core;
using umbraco.cms.businesslogic.macro;
namespace Umbraco.Web.UI.Umbraco.Developer.Macros
{
public partial class EditMacro : global::umbraco.cms.presentation.developer.editMacro
{
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
PopulatePartialViewFiles();
}
/// <summary>
/// This ensures that the SelectedPartialView txt box value is set correctly when the m_macro object's
/// ScriptingFile property contains a full virtual path beginning with the MacroPartials path
/// </summary>
/// <param name="macro"> </param>
/// <param name="macroAssemblyValue"></param>
/// <param name="macroTypeValue"></param>
protected override void PopulateFieldsOnLoad(Macro macro, string macroAssemblyValue, string macroTypeValue)
{
base.PopulateFieldsOnLoad(macro, macroAssemblyValue, macroTypeValue);
//check if the ScriptingFile property contains the MacroPartials path
if (macro.ScriptingFile.StartsWith(SystemDirectories.MvcViews + "/MacroPartials/")
|| (Regex.IsMatch(macro.ScriptingFile, "~/App_Plugins/.+?/Views/MacroPartials", RegexOptions.Compiled)))
{
macroPython.Text = "";
SelectedPartialView.Text = macro.ScriptingFile;
}
}
/// <summary>
/// This changes the macro type to a PartialViewMacro if the SelectedPartialView txt box has a value.
/// This then also updates the file path saved for the partial view to be the full virtual path, not just the file name.
/// </summary>
/// <param name="macro"> </param>
/// <param name="macroCachePeriod"></param>
/// <param name="macroAssemblyValue"></param>
/// <param name="macroTypeValue"></param>
protected override void SetMacroValuesFromPostBack(Macro macro, int macroCachePeriod, string macroAssemblyValue, string macroTypeValue)
{
base.SetMacroValuesFromPostBack(macro, macroCachePeriod, macroAssemblyValue, macroTypeValue);
if (!SelectedPartialView.Text.IsNullOrWhiteSpace())
{
macro.ScriptingFile = SelectedPartialView.Text;
}
}
/// <summary>
/// Populate the drop down list for partial view files
/// </summary>
private void PopulatePartialViewFiles()
{
var partialsDir = IOHelper.MapPath(SystemDirectories.MvcViews + "/MacroPartials");
//get all the partials in the normal /MacroPartials folder
var foundMacroPartials = GetPartialViewFiles(partialsDir, partialsDir, SystemDirectories.MvcViews + "/MacroPartials");
//now try to find all of them int he App_Plugins/[PackageName]/Views/MacroPartials folder
var partialPluginsDir = new DirectoryInfo(IOHelper.MapPath(SystemDirectories.AppPlugins));
foreach(var d in partialPluginsDir.GetDirectories())
{
var viewsFolder = d.GetDirectories("Views");
if (viewsFolder.Any())
{
var macroPartials = viewsFolder.First().GetDirectories("MacroPartials");
if (macroPartials.Any())
{
foundMacroPartials = foundMacroPartials.Concat(
GetPartialViewFiles(macroPartials.First().FullName, macroPartials.First().FullName, SystemDirectories.AppPlugins + "/" + d.Name + "/Views/MacroPartials"));
}
}
}
PartialViewList.DataSource = foundMacroPartials;
PartialViewList.DataBind();
PartialViewList.Items.Insert(0, new ListItem("Browse partial view files on server...", string.Empty));
}
/// <summary>
/// Get the list of partial view files in the ~/Views/MacroPartials folder and in all
/// folders of ~/App_Plugins/[PackageName]/Views/MacroPartials
/// </summary>
/// <param name="orgPath"></param>
/// <param name="path"></param>
/// <param name="prefixVirtualPath"> </param>
/// <returns></returns>
private IEnumerable<string> GetPartialViewFiles(string orgPath, string path, string prefixVirtualPath)
{
var files = new List<string>();
var dirInfo = new DirectoryInfo(path);
// Populate subdirectories
var dirInfos = dirInfo.GetDirectories();
foreach (var dir in dirInfos)
{
files.AddRange(GetPartialViewFiles(orgPath, path + "/" + dir.Name, prefixVirtualPath));
}
var fileInfo = dirInfo.GetFiles("*.*");
files.AddRange(
fileInfo.Select(file =>
prefixVirtualPath.TrimEnd('/') + "/" + (path.Replace(orgPath, string.Empty).Trim('/') + "/" + file.Name).Trim('/')));
return files;
}
}
}
@@ -11,5 +11,23 @@ namespace Umbraco.Web.UI.Umbraco.Developer.Macros {
public partial class EditMacro {
/// <summary>
/// SelectedPartialView control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.TextBox SelectedPartialView;
/// <summary>
/// PartialViewList control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.DropDownList PartialViewList;
}
}
@@ -3,10 +3,27 @@
<%@ Register TagPrefix="cc1" Namespace="umbraco.uicontrols" Assembly="controls" %>
<asp:Content ContentPlaceHolderID="head" runat="server">
<script language="javascript">
<script type="text/javascript">
function doSubmit() {
document.forms.aspnetForm.submit();
}
//handles the change selection of the drop downs to populate the text box
(function($) {
$(document).ready(function () {
//on drop down change, update the text box and clear other text boxes
$("#Table2 td.propertyContent select").change(function() {
//update the txt box
var txt = $(this).prev("input[type='text']");
txt.val($(this).val());
//clear other text boxes
$("#Table2 td.propertyContent input[type='text']").not(txt).val("");
//reset other drop downs
$("#Table2 td.propertyContent select").not($(this)).val("");
});
});
})(jQuery);
</script>
</asp:Content>
<asp:Content ContentPlaceHolderID="body" runat="server">
@@ -32,11 +49,22 @@
</table>
</cc1:Pane>
<cc1:Pane ID="Pane1_2" BackColor="mediumaquamarine" runat="server">
<table id="Table2" cellspacing="0" cellpadding="4" width="98%" border="0" runat="server">
<table id="Table2" cellspacing="0" cellpadding="4" width="98%" border="0">
<tr>
<td class="propertyHeader" width="30%">
<img alt="Xslt Icon" src="../../images/umbraco/developerXslt.gif" align="absMiddle">
Use XSLT file
<img alt="python Icon" src="../../images/umbraco/developerScript.gif" align="absMiddle" />
Use MVC Partial View
</td>
<td class="propertyContent">
<asp:TextBox ID="SelectedPartialView" runat="server" Width="230px" CssClass="guiInputText"></asp:TextBox>
<asp:DropDownList ID="PartialViewList" runat="server" >
</asp:DropDownList>
</td>
</tr>
<tr>
<td class="propertyHeader" width="30%">
<img alt="Xslt Icon" src="../../images/umbraco/developerXslt.gif" align="absMiddle"/>
or XSLT file
</td>
<td class="propertyContent">
<asp:TextBox ID="macroXslt" runat="server" Width="230px" CssClass="guiInputText"></asp:TextBox>
@@ -46,7 +74,7 @@
</tr>
<tr>
<td class="propertyHeader" width="30%">
<img alt="User control Icon" src="../../images/developer/userControlIcon.png" align="absMiddle">
<img alt="User control Icon" src="../../images/developer/userControlIcon.png" align="absMiddle"/>
or .NET User Control
</td>
<td class="propertyContent">
@@ -58,8 +86,7 @@
</tr>
<tr>
<td class="propertyHeader" valign="top" width="30%">
<img alt="Custom Control Icon" src="../../images/developer/customControlIcon.png"
align="absMiddle">
<img alt="Custom Control Icon" src="../../images/developer/customControlIcon.png" align="absMiddle"/>
or .NET Custom Control
</td>
<td class="propertyContent">
@@ -72,7 +99,7 @@
</tr>
<tr>
<td class="propertyHeader" width="30%">
<img alt="python Icon" src="../../images/umbraco/developerScript.gif" align="absMiddle">
<img alt="python Icon" src="../../images/umbraco/developerScript.gif" align="absMiddle"/>
or script file
</td>
<td class="propertyContent">
@@ -22,6 +22,7 @@
<cc1:PropertyPanel runat="server" ID="prop_domain" Text="Domain">
<asp:TextBox ID="DomainName" runat="server" Width="252px"></asp:TextBox>
<asp:RequiredFieldValidator ControlToValidate="DomainName" ErrorMessage="*" ID="DomainValidator" runat="server" Display="Dynamic" />
<asp:RegularExpressionValidator ControlToValidate="DomainName" ErrorMessage="*" ID="DomainValidator2" runat="server" Display="Dynamic" />
<br /><small><%= umbraco.ui.Text("assignDomain", "domainHelp") %></small>
</cc1:PropertyPanel>
@@ -0,0 +1,3 @@
tinyMCE.addI18n('en_us.example',{
desc : 'This is just a template button'
});
@@ -0,0 +1,3 @@
tinyMCE.addI18n('en_us.example_dlg',{
title : 'This is just a example title'
});
@@ -0,0 +1,3 @@
tinyMCE.addI18n('it.example',{
desc : 'Esempio di pulsante'
});
@@ -0,0 +1,3 @@
tinyMCE.addI18n('it.example_dlg',{
title : 'Esempio di titolo'
});
@@ -0,0 +1,10 @@
tinyMCE.addI18n('de.embed_dlg', {
title: 'Medien von Drittanbietern einbetten',
general: 'Allgemein',
url: 'Url:',
size: 'Abmessungen:',
constrain_proportions: 'Proportionen beibehalten',
preview: 'Vorschau',
source: 'Quellcode'
});
@@ -0,0 +1,10 @@
tinyMCE.addI18n('de.embed_dlg', {
title: 'Medien von Drittanbietern einbetten',
general: 'Allgemein',
url: 'Url:',
size: 'Abmessungen:',
constrain_proportions: 'Proportionen beibehalten',
preview: 'Vorschau',
source: 'Quellcode'
});
@@ -0,0 +1,10 @@
tinyMCE.addI18n('en_us.embed_dlg', {
title: 'Embed third party media',
general: 'General',
url: 'Url:',
size: 'Size:',
constrain_proportions: 'Constrain',
preview: 'Preview',
source: 'Source'
});
@@ -0,0 +1,10 @@
tinyMCE.addI18n('en_us.embed_dlg', {
title: 'Embed third party media',
general: 'General',
url: 'Url:',
size: 'Size:',
constrain_proportions: 'Constrain',
preview: 'Preview',
source: 'Source'
});
@@ -0,0 +1,9 @@
tinyMCE.addI18n('en.embed_dlg', {
title: 'Integra media di terze parti',
general: 'Generale',
url: 'Url:',
size: 'Dimensione:',
constrain_proportions: 'Vincolo',
preview: 'Anteprima',
source: 'Sorgente'
});
@@ -0,0 +1,9 @@
tinyMCE.addI18n('it.embed_dlg', {
title: 'Integra media di terze parti',
general: 'Generale',
url: 'Url:',
size: 'Dimensione:',
constrain_proportions: 'Vincolo',
preview: 'Anteprima',
source: 'Sorgente'
});
@@ -0,0 +1,43 @@
tinyMCE.addI18n('en_us.umbimage_dlg', {
tab_general: 'General',
tab_appearance: 'Appearance',
tab_advanced: 'Advanced',
general: 'General',
title: 'Title',
preview: 'Preview',
constrain_proportions: 'Constrain proportions',
langdir: 'Language direction',
langcode: 'Language code',
long_desc: 'Long description link',
style: 'Style',
classes: 'Classes',
ltr: 'Left to right',
rtl: 'Right to left',
id: 'Id',
map: 'Image map',
swap_image: 'Swap image',
alt_image: 'Alternative image',
mouseover: 'for mouse over',
mouseout: 'for mouse out',
misc: 'Miscellaneous',
example_img: 'Appearance preview image',
missing_alt: 'Are you sure you want to continue without including an Image Description? Without it the image may not be accessible to some users with disabilities, or to those using a text browser, or browsing the Web with images turned off.',
dialog_title: 'Insert/edit image',
src: 'Image URL',
alt: 'Image description',
list: 'Image list',
border: 'Border',
dimensions: 'Dimensions',
vspace: 'Vertical space',
hspace: 'Horizontal space',
align: 'Alignment',
align_baseline: 'Baseline',
align_top: 'Top',
align_middle: 'Middle',
align_bottom: 'Bottom',
align_texttop: 'Text top',
align_textbottom: 'Text bottom',
align_left: 'Left',
align_right: 'Right',
image_list: 'Image list'
});
@@ -0,0 +1 @@
tinyMCE.addI18n('en_us.advlink_dlg', { "target_name": "Target Name", classes: "Classes", style: "Style", id: "ID", "popup_position": "Position (X/Y)", langdir: "Language Direction", "popup_size": "Size", "popup_dependent": "Dependent (Mozilla/Firefox Only)", "popup_resizable": "Make Window Resizable", "popup_location": "Show Location Bar", "popup_menubar": "Show Menu Bar", "popup_toolbar": "Show Toolbars", "popup_statusbar": "Show Status Bar", "popup_scrollbars": "Show Scrollbars", "popup_return": "Insert \'return false\'", "popup_name": "Window Name", "popup_url": "Popup URL", popup: "JavaScript Popup", "target_blank": "Open in New Window", "target_top": "Open in Top Frame (Replaces All Frames)", "target_parent": "Open in Parent Window/Frame", "target_same": "Open in This Window/Frame", "anchor_names": "Anchors", "popup_opts": "Options", "advanced_props": "Advanced Properties", "event_props": "Events", "popup_props": "Popup Properties", "general_props": "General Properties", "advanced_tab": "Advanced", "events_tab": "Events", "popup_tab": "Popup", "general_tab": "General", list: "Link List", "is_external": "The URL you entered seems to be an external link. Do you want to add the required http:// prefix?", "is_email": "The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?", titlefield: "Title", target: "Target", url: "Link URL", title: "Insert/Edit Link", "link_list": "Link List", rtl: "Right to Left", ltr: "Left to Right", accesskey: "AccessKey", tabindex: "TabIndex", rev: "Relationship Target to Page", rel: "Relationship Page to Target", mime: "Target MIME Type", encoding: "Target Character Encoding", langcode: "Language Code", "target_langcode": "Target Language", width: "Width", height: "Height" });
@@ -0,0 +1,3 @@
tinyMCE.addI18n('en_us.umbracomacro',{
desc : 'Insert macro'
});
@@ -0,0 +1,3 @@
tinyMCE.addI18n('en_us.example_dlg',{
title : 'This is just a example title'
});
@@ -0,0 +1,74 @@
tinyMCE.addI18n('en_us.umbraco',{"underline_desc":"Underline (Ctrl+U)",
"italic_desc":"Italic (Ctrl+I)",
"bold_desc":"Bold (Ctrl+B)",
dd:"Definition Description",
dt:"Definition Term ",
samp:"Code Sample",
code:"Code",
blockquote:"Block Quote",
h6:"Heading 6",
h5:"Heading 5",
h4:"Heading 4",
h3:"Heading 3",
h2:"Heading 2",
h1:"Heading 1",
pre:"Preformatted",
address:"Address",
div:"DIV",
paragraph:"Paragraph",
block:"Format",
fontdefault:"Font Family",
"font_size":"Font Size",
"style_select":"Styles",
"anchor_delta_height":"",
"anchor_delta_width":"",
"charmap_delta_height":"",
"charmap_delta_width":"",
"colorpicker_delta_height":"",
"colorpicker_delta_width":"",
"link_delta_height":"",
"link_delta_width":"",
"image_delta_height":"",
"image_delta_width":"",
"more_colors":"More Colors...",
"toolbar_focus":"Jump to tool buttons - Alt+Q, Jump to editor - Alt-Z, Jump to element path - Alt-X",
newdocument:"Are you sure you want clear all contents?",
path:"Path",
"clipboard_msg":"Copy/Cut/Paste is not available in Mozilla and Firefox.\nDo you want more information about this issue?",
"blockquote_desc":"Block Quote",
"help_desc":"Help",
"newdocument_desc":"New Document",
"image_props_desc":"Image Properties",
"paste_desc":"Paste (Ctrl+V)",
"copy_desc":"Copy (Ctrl+C)",
"cut_desc":"Cut (Ctrl+X)",
"anchor_desc":"Insert/Edit Anchor",
"visualaid_desc":"show/Hide Guidelines/Invisible Elements",
"charmap_desc":"Insert Special Character",
"backcolor_desc":"Select Background Color",
"forecolor_desc":"Select Text Color",
"custom1_desc":"Your Custom Description Here",
"removeformat_desc":"Remove Formatting",
"hr_desc":"Insert Horizontal Line",
"sup_desc":"Superscript",
"sub_desc":"Subscript",
"code_desc":"Edit HTML Source",
"cleanup_desc":"Cleanup Messy Code",
"image_desc":"Insert/Edit Image",
"unlink_desc":"Unlink",
"link_desc":"Insert/Edit Link",
"redo_desc":"Redo (Ctrl+Y)",
"undo_desc":"Undo (Ctrl+Z)",
"indent_desc":"Increase Indent",
"outdent_desc":"Decrease Indent",
"numlist_desc":"Insert/Remove Numbered List",
"bullist_desc":"Insert/Remove Bulleted List",
"justifyfull_desc":"Align Full",
"justifyright_desc":"Align Right",
"justifycenter_desc":"Align Center",
"justifyleft_desc":"Align Left",
"striketrough_desc":"Strikethrough",
"help_shortcut":"Press ALT-F10 for toolbar. Press ALT-0 for help",
"rich_text_area":"Rich Text Area",
"shortcuts_desc":"Accessability Help",
toolbar:"Toolbar"});
@@ -0,0 +1,55 @@
tinyMCE.addI18n('en_us.umbraco_dlg', {"link_list":"Link List",
"link_is_external":"The URL you entered seems to be an external link. Do you want to add the required http:// prefix?",
"link_is_email":"The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?",
"link_titlefield":"Title",
"link_target_blank":"Open Link in a New Window",
"link_target_same":"Open Link in the Same Window",
"link_target":"Target",
"link_url":"Link URL",
"link_title":"Insert/Edit Link",
"image_align_right":"Right",
"image_align_left":"Left",
"image_align_textbottom":"Text Bottom",
"image_align_texttop":"Text Top",
"image_align_bottom":"Bottom",
"image_align_middle":"Middle",
"image_align_top":"Top",
"image_align_baseline":"Baseline",
"image_align":"Alignment",
"image_hspace":"Horizontal Space",
"image_vspace":"Vertical Space",
"image_dimensions":"Dimensions",
"image_alt":"Image Description",
"image_list":"Image List",
"image_border":"Border",
"image_src":"Image URL",
"image_title":"Insert/Edit Image",
"charmap_title":"Insert Character",
"charmap_usage":"Use left and right arrows to navigate.",
"colorpicker_name":"Name:",
"colorpicker_color":"Color:",
"colorpicker_named_title":"Named Colors",
"colorpicker_named_tab":"Named",
"colorpicker_palette_title":"Palette Colors",
"colorpicker_palette_tab":"Palette",
"colorpicker_picker_title":"Color Picker",
"colorpicker_picker_tab":"Picker",
"colorpicker_title":"Select a Color",
"code_wordwrap":"Word Wrap",
"code_title":"View Source",
"anchor_name":"Name",
"anchor_title":"Insert/Edit Anchor",
"about_loaded":"Loaded Plugins",
"about_version":"Version",
"about_author":"Author",
"about_plugin":"Plugin",
"about_plugins":"Plugins",
"about_license":"License",
"about_help":"Help",
"about_general":"About",
"about_title":"About TinyMCE",
"anchor_invalid":"Please specify a valid anchor name.",
"accessibility_help":"Accessibility Help",
"accessibility_usage_title":"General Usage",
"invalid_color_value":"Invalid color value",
"":""});
@@ -1,6 +1,16 @@
tinyMCE.addI18n('it.umbraco',{
style_select:"Stili",
font_size:"Grandezza carattere",
"style_select":"Stili",
"anchor_delta_height":"",
"anchor_delta_width":"",
"charmap_delta_height":"",
"charmap_delta_width":"",
"colorpicker_delta_height":"",
"colorpicker_delta_width":"",
"link_delta_height":"",
"link_delta_width":"",
"image_delta_height":"",
"image_delta_width":"",
"font_size":"Grandezza carattere",
fontdefault:"Famiglia carattere",
block:"Formato",
paragraph:"Paragrafo",
@@ -18,9 +28,9 @@ code:"Codice",
samp:"Esempio codice",
dt:"Termine definizione",
dd:"Descrizione definizione",
bold_desc:"Grassetto (Ctrl+B)",
italic_desc:"Corsivo (Ctrl+I)",
underline_desc:"Sottolineato (Ctrl+U)",
"bold_desc":"Grassetto (Ctrl+B)",
"italic_desc":"Corsivo (Ctrl+I)",
"underline_desc":"Sottolineato (Ctrl+U)",
striketrough_desc:"Barrato",
justifyleft_desc:"Allinea a sinistra",
justifycenter_desc:"Centra",
@@ -52,11 +62,15 @@ copy_desc:"Copia",
paste_desc:"Incolla",
image_props_desc:"Propriet\u00E0 immagine",
newdocument_desc:"Nuovo documento",
help_desc:"Aiuto",
blockquote_desc:"Testo quotato",
clipboard_msg:"Copia/Taglia/Incolla non \u00E8 disponibile in Mozilla e Firefox..\r\nSi desidera avere maggiori informazioni su questo problema?",
"help_desc":"Aiuto",
"blockquote_desc":"Testo quotato",
"clipboard_msg":"Copia/Taglia/Incolla non \u00E8 disponibile in Mozilla e Firefox..\r\nSi desidera avere maggiori informazioni su questo problema?",
path:"Percorso",
newdocument:"Sei sicuro di voler cancellare tutti i contenuti?",
toolbar_focus:"Vai ai pulsanti strumento - Alt+Q, Vai all'editor - Alt-Z, Vai al percorso dell'elemento - Alt-X",
more_colors:"Colori aggiuntivi"
});
"toolbar_focus":"Vai ai pulsanti strumento - Alt+Q, Vai all'editor - Alt-Z, Vai al percorso dell'elemento - Alt-X",
"more_colors":"Colori aggiuntivi",
"rich_text_area":"Rich Text Area",
"help_shortcut":"Premere ALT-F10 per la barra degli strumenti. Premere ALT-0 per aiuto",
"shortcuts_desc":"Guida accessibilit\u00E0",
toolbar:"Barra degli strumenti"
});
@@ -1,51 +1,52 @@
tinyMCE.addI18n('it.umbraco_dlg',{
about_title:"Informazioni su TinyMCE",
about_general:"Informazioni",
about_help:"Aiuto",
about_license:"Licenza",
about_plugins:"Plugins",
about_plugin:"Plugin",
about_author:"Autore",
about_version:"Versione",
about_loaded:"Plugin caricati",
anchor_title:"Inserisci/modifica ancora",
anchor_name:"Nome ancora",
code_title:"Editor sorgente HTML",
code_wordwrap:"A capo automatico",
colorpicker_title:"Seleziona un colore",
colorpicker_picker_tab:"Selettore",
colorpicker_picker_title:"Selettore colori",
colorpicker_palette_tab:"Tavolozza",
colorpicker_palette_title:"Tavolozza dei colori",
colorpicker_named_tab:"Per nome",
colorpicker_named_title:"Colori per nome",
colorpicker_color:"Colore:",
colorpicker_name:"Nome:",
charmap_title:"Seleziona carattere speciale",
image_title:"Inserisci/modifica immagine",
image_src:"URL immagine",
image_alt:"Descrizione immagine",
image_list:"Lista immagini",
image_border:"Bordo",
image_dimensions:"Dimensioni",
image_vspace:"Spaziatura verticale",
image_hspace:"Spaziatura orizzontale",
image_align:"Allineamentot",
image_align_baseline:"Alla base",
image_align_top:"In alto",
image_align_middle:"In mezzo",
image_align_bottom:"In basso",
image_align_texttop:"In alto al testo",
image_align_textbottom:"In basso al testo",
image_align_left:"A sinistra",
image_align_right:"A destra",
link_title:"Inserisci/modifica collegamento",
link_url:"URL collegamento",
link_target:"Target",
link_target_same:"Apri link nella stessa finestra",
link_target_blank:"Apri link in una nuova finestra",
link_titlefield:"Titolo",
link_is_email:"L'URL inserito sembra essere un indirizzo email. Aggiungere il necessario prefisso mailto: ?",
link_is_external:"L'URL inserito sembra essere un link esterno. Aggiungere il necessario prefisso http:// ?",
link_list:"Lista collegamenti"
});
"about_title":"Informazioni su TinyMCE",
"about_general":"Informazioni",
"about_help":"Aiuto",
"about_license":"Licenza",
"about_plugins":"Plugins",
"about_plugin":"Plugin",
"about_author":"Autore",
"about_version":"Versione",
"about_loaded":"Plugin caricati",
"anchor_title":"Inserisci/modifica ancora",
"anchor_name":"Nome ancora",
"code_title":"Editor sorgente HTML",
"code_wordwrap":"A capo automatico",
"colorpicker_title":"Seleziona un colore",
"colorpicker_picker_tab":"Selettore",
"colorpicker_picker_title":"Selettore colori",
"colorpicker_palette_tab":"Tavolozza",
"colorpicker_palette_title":"Tavolozza dei colori",
"colorpicker_named_tab":"Per nome",
"colorpicker_named_title":"Colori per nome",
"colorpicker_color":"Colore:",
"colorpicker_name":"Nome:",
"charmap_title":"Seleziona carattere speciale",
"charmap_usage":"Usa le frecce sinistra e destra per navigare.",
"image_title":"Inserisci/modifica immagine",
"image_src":"URL immagine",
"image_alt":"Descrizione immagine",
"image_list":"Lista immagini",
"image_border":"Bordo",
"image_dimensions":"Dimensioni",
"image_vspace":"Spaziatura verticale",
"image_hspace":"Spaziatura orizzontale",
"image_align":"Allineamento",
"image_align_baseline":"Alla base",
"image_align_top":"In alto",
"image_align_middle":"In mezzo",
"image_align_bottom":"In basso",
"image_align_texttop":"In alto al testo",
"image_align_textbottom":"In basso al testo",
"image_align_left":"A sinistra",
"image_align_right":"A destra",
"link_title":"Inserisci/modifica collegamento",
"link_url":"URL collegamento",
"link_target":"Target",
"link_target_same":"Apri link nella stessa finestra",
"link_target_blank":"Apri link in una nuova finestra",
"link_titlefield":"Titolo",
"link_is_email":"L'URL inserito sembra essere un indirizzo email. Aggiungere il necessario prefisso mailto: ?",
"link_is_external":"L'URL inserito sembra essere un link esterno. Aggiungere il necessario prefisso http:// ?",
"link_list":"Lista collegamenti"
});
@@ -42,7 +42,7 @@ namespace Umbraco.Web
DescendantDocumentById = "//node [@id={0}]";
DescendantDocumentByAlias = "//node[("
+ "contains(concat(',',translate(data [@alias='umbracoUrlAlias'], ' ', ''),','),',{0},')"
+ " or contains(concat(',',translate(data [@alias='umbracoUrlAlias'], ' ', ''),','),',/{0},'"
+ " or contains(concat(',',translate(data [@alias='umbracoUrlAlias'], ' ', ''),','),',/{0},')"
+ ")]";
ChildDocumentByUrlName = "/node [@urlName='{0}']";
RootDocumentWithLowestSortOrder = "/root/node [not(@sortOrder > ../node/@sortOrder)][1]";
@@ -26,8 +26,7 @@ namespace Umbraco.Web.Dictionary
}
catch (Exception e)
{
var trace = UmbracoContext.Current != null ? UmbracoContext.Current.HttpContext.Trace : null;
LogHelper.Warn<DefaultCultureDictionary>("Error returning dictionary item '" + key + "'", trace, e);
LogHelper.WarnWithException<DefaultCultureDictionary>("Error returning dictionary item '" + key + "'", true, e);
return string.Empty;
}
}
@@ -0,0 +1,39 @@
using System.Collections.Generic;
using System.Web.Mvc;
using Umbraco.Web.Models;
using umbraco.cms.businesslogic.macro;
using umbraco.interfaces;
using System.Linq;
namespace Umbraco.Web.Macros
{
/// <summary>
/// Controller to render macro content for Parital View Macros
/// </summary>
internal class PartialViewMacroController : Controller
{
private readonly UmbracoContext _umbracoContext;
private readonly MacroModel _macro;
private readonly INode _currentPage;
public PartialViewMacroController(UmbracoContext umbracoContext, MacroModel macro, INode currentPage)
{
_umbracoContext = umbracoContext;
_macro = macro;
_currentPage = currentPage;
}
/// <summary>
/// Child action to render a macro
/// </summary>
/// <returns></returns>
[ChildActionOnly]
public PartialViewResult Index()
{
var model = new PartialViewMacroModel(_currentPage.ConvertFromNode(),
_macro.Properties.ToDictionary(x => x.Key, x => (object)x.Value));
return PartialView(_macro.ScriptName, model);
}
}
}
@@ -0,0 +1,166 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.WebPages;
using Umbraco.Core.IO;
using umbraco.cms.businesslogic.macro;
using umbraco.interfaces;
using Umbraco.Web.Mvc;
namespace Umbraco.Web.Macros
{
/// <summary>
/// A macro engine using MVC Partial Views to execute
/// </summary>
public class PartialViewMacroEngine : IMacroEngine
{
private readonly Func<HttpContextBase> _getHttpContext;
private readonly Func<UmbracoContext> _getUmbracoContext;
public const string EngineName = "Partial View Macro Engine";
public PartialViewMacroEngine()
{
_getHttpContext = () =>
{
if (HttpContext.Current == null)
throw new InvalidOperationException("The " + this.GetType() + " cannot execute with a null HttpContext.Current reference");
return new HttpContextWrapper(HttpContext.Current);
};
_getUmbracoContext = () =>
{
if (UmbracoContext.Current == null)
throw new InvalidOperationException("The " + this.GetType() + " cannot execute with a null UmbracoContext.Current reference");
return UmbracoContext.Current;
};
}
/// <summary>
/// Constructor generally used for unit testing
/// </summary>
/// <param name="httpContext"></param>
/// <param name="umbracoContext"> </param>
internal PartialViewMacroEngine(HttpContextBase httpContext, UmbracoContext umbracoContext)
{
_getHttpContext = () => httpContext;
_getUmbracoContext = () => umbracoContext;
}
public string Name
{
get { return EngineName; }
}
//NOTE: We do not return any supported extensions because we don't want the MacroEngineFactory to return this
// macro engine when searching for engines via extension. Those types of engines are reserved for files that are
// stored in the ~/macroScripts folder and each engine must support unique extensions. This is a total Hack until
// we rewrite how macro engines work.
public IEnumerable<string> SupportedExtensions
{
get { return Enumerable.Empty<string>(); }
//get { return new[] {"cshtml", "vbhtml"}; }
}
//NOTE: We do not return any supported extensions because we don't want the MacroEngineFactory to return this
// macro engine when searching for engines via extension. Those types of engines are reserved for files that are
// stored in the ~/macroScripts folder and each engine must support unique extensions. This is a total Hack until
// we rewrite how macro engines work.
public IEnumerable<string> SupportedUIExtensions
{
get { return Enumerable.Empty<string>(); }
//get { return new[] { "cshtml", "vbhtml" }; }
}
public Dictionary<string, IMacroGuiRendering> SupportedProperties
{
get { throw new NotSupportedException(); }
}
public bool Validate(string code, string tempFileName, INode currentPage, out string errorMessage)
{
var temp = GetVirtualPathFromPhysicalPath(tempFileName);
try
{
CompileAndInstantiate(temp);
}
catch (Exception exception)
{
errorMessage = exception.Message;
return false;
}
errorMessage = string.Empty;
return true;
}
public string Execute(MacroModel macro, INode currentPage)
{
if (macro == null) throw new ArgumentNullException("macro");
if (currentPage == null) throw new ArgumentNullException("currentPage");
if (!macro.ScriptName.StartsWith(SystemDirectories.MvcViews + "/MacroPartials/")
&& (!Regex.IsMatch(macro.ScriptName, "~/App_Plugins/.+?/Views/MacroPartials", RegexOptions.Compiled)))
{
throw new InvalidOperationException("Cannot render the Partial View Macro with file: " + macro.ScriptName + ". All Partial View Macros must exist in the " + SystemDirectories.MvcViews + "/MacroPartials/ folder");
}
var http = _getHttpContext();
var umbCtx = _getUmbracoContext();
var routeVals = new RouteData();
routeVals.Values.Add("controller", "PartialViewMacro");
routeVals.Values.Add("action", "Index");
routeVals.DataTokens.Add("umbraco-context", umbCtx); //required for UmbracoViewPage
////lets render this controller as a child action if we are currently executing using MVC
////(otherwise don't do this since we're using webforms)
//var mvcHandler = http.CurrentHandler as MvcHandler;
//if (mvcHandler != null)
//{
// routeVals.DataTokens.Add("ParentActionViewContext",
// //If we could get access to the currently executing controller we could do this but this is nearly
// //impossible. The only way to do that would be to store the controller instance in the route values
// //in the base class of the UmbracoController.... but not sure the reprocussions of that, i think it could
// //work but is a bit nasty.
// new ViewContext());
//}
var request = new RequestContext(http, routeVals);
string output;
using (var controller = new PartialViewMacroController(umbCtx, macro, currentPage))
{
controller.ControllerContext = new ControllerContext(request, controller);
var result = controller.Index();
output = controller.RenderViewResultAsString(result);
}
return output;
}
private string GetVirtualPathFromPhysicalPath(string physicalPath)
{
string rootpath = _getHttpContext().Server.MapPath("~/");
physicalPath = physicalPath.Replace(rootpath, "");
physicalPath = physicalPath.Replace("\\", "/");
return "~/" + physicalPath;
}
private static PartialViewMacroPage CompileAndInstantiate(string virtualPath)
{
//Compile Razor - We Will Leave This To ASP.NET Compilation Engine & ASP.NET WebPages
//Security in medium trust is strict around here, so we can only pass a virtual file path
//ASP.NET Compilation Engine caches returned types
//Changed From BuildManager As Other Properties Are Attached Like Context Path/
var webPageBase = WebPageBase.CreateInstanceFromVirtualPath(virtualPath);
var webPage = webPageBase as PartialViewMacroPage;
if (webPage == null)
throw new InvalidCastException("All Partial View Macro views must inherit from " + typeof(PartialViewMacroPage).FullName);
return webPage;
}
}
}
@@ -0,0 +1,14 @@
using System.Web.Mvc;
using Umbraco.Web.Models;
using Umbraco.Web.Mvc;
namespace Umbraco.Web.Macros
{
/// <summary>
/// The base view class that PartialViewMacro views need to inherit from
/// </summary>
public abstract class PartialViewMacroPage : UmbracoViewPage<PartialViewMacroModel>
{
}
}
@@ -0,0 +1,23 @@
using System.Collections.Generic;
using Umbraco.Core.Models;
namespace Umbraco.Web.Models
{
/// <summary>
/// The model used when rendering Partial View Macros
/// </summary>
public class PartialViewMacroModel
{
public PartialViewMacroModel(IPublishedContent page, IDictionary<string, object> macroParams)
{
CurrentPage = page;
MacroParameters = macroParams;
}
public IPublishedContent CurrentPage { get; private set; }
public IDictionary<string, object> MacroParameters { get; private set; }
}
}
-1
View File
@@ -3,6 +3,5 @@ namespace Umbraco.Web.Mvc
internal static class Constants
{
public const string ViewLocation = "~/Views";
public const string PluginsLocation = "~/App_Plugins";
}
}
+1 -1
View File
@@ -92,7 +92,7 @@ namespace Umbraco.Web.Mvc
: ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName);
var viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw);
viewResult.View.Render(viewContext, sw);
viewResult.ViewEngine.ReleaseView(controller.ControllerContext, viewResult.View);
return sw.GetStringBuilder().ToString();
}
}
+12 -12
View File
@@ -33,16 +33,16 @@ namespace Umbraco.Web.Mvc
var viewLocationsArray = new[]
{
string.Concat(Constants.PluginsLocation, "/{2}/Views/{1}/{0}.cshtml"),
string.Concat(Constants.PluginsLocation, "/{2}/Views/{1}/{0}.vbhtml")
string.Concat(SystemDirectories.AppPlugins, "/{2}/Views/{1}/{0}.cshtml"),
string.Concat(SystemDirectories.AppPlugins, "/{2}/Views/{1}/{0}.vbhtml")
};
//set all of the area view locations to the plugin folder
AreaViewLocationFormats = viewLocationsArray
.Concat(new[]
{
string.Concat(Constants.PluginsLocation, "/{2}/Views/Shared/{0}.cshtml"),
string.Concat(Constants.PluginsLocation, "/{2}/Views/Shared/{0}.vbhtml")
string.Concat(SystemDirectories.AppPlugins, "/{2}/Views/Shared/{0}.cshtml"),
string.Concat(SystemDirectories.AppPlugins, "/{2}/Views/Shared/{0}.vbhtml")
})
.ToArray();
@@ -51,15 +51,15 @@ namespace Umbraco.Web.Mvc
AreaPartialViewLocationFormats = new[]
{
//will be used when we have partial view and child action macros
string.Concat(Constants.PluginsLocation, "/{2}/Views/Partials/{0}.cshtml"),
string.Concat(Constants.PluginsLocation, "/{2}/Views/Partials/{0}.vbhtml"),
string.Concat(Constants.PluginsLocation, "/{2}/Views/MacroPartials/{0}.cshtml"),
string.Concat(Constants.PluginsLocation, "/{2}/Views/MacroPartials/{0}.vbhtml"),
string.Concat(SystemDirectories.AppPlugins, "/{2}/Views/Partials/{0}.cshtml"),
string.Concat(SystemDirectories.AppPlugins, "/{2}/Views/Partials/{0}.vbhtml"),
string.Concat(SystemDirectories.AppPlugins, "/{2}/Views/MacroPartials/{0}.cshtml"),
string.Concat(SystemDirectories.AppPlugins, "/{2}/Views/MacroPartials/{0}.vbhtml"),
//for partials
string.Concat(Constants.PluginsLocation, "/{2}/Views/{1}/{0}.cshtml"),
string.Concat(Constants.PluginsLocation, "/{2}/Views/{1}/{0}.vbhtml"),
string.Concat(Constants.PluginsLocation, "/{2}/Views/Shared/{0}.cshtml"),
string.Concat(Constants.PluginsLocation, "/{2}/Views/Shared/{0}.vbhtml")
string.Concat(SystemDirectories.AppPlugins, "/{2}/Views/{1}/{0}.cshtml"),
string.Concat(SystemDirectories.AppPlugins, "/{2}/Views/{1}/{0}.vbhtml"),
string.Concat(SystemDirectories.AppPlugins, "/{2}/Views/Shared/{0}.cshtml"),
string.Concat(SystemDirectories.AppPlugins, "/{2}/Views/Shared/{0}.vbhtml")
};
}
+5 -1
View File
@@ -236,7 +236,11 @@ namespace Umbraco.Web.Mvc
}
else
{
LogHelper.Warn<RenderRouteHandler>("The current Document Type {0} matches a locally declared controller of type {1}. Custom Controllers for Umbraco routing must inherit from '{2}'.", publishedContentRequest.PublishedContent.DocumentTypeAlias, controller.GetType().FullName, typeof(RenderMvcController).FullName);
LogHelper.Warn<RenderRouteHandler>(
"The current Document Type {0} matches a locally declared controller of type {1}. Custom Controllers for Umbraco routing must inherit from '{2}'.",
() => publishedContentRequest.PublishedContent.DocumentTypeAlias,
() => controller.GetType().FullName,
() => typeof(RenderMvcController).FullName);
//exit as we cannnot route to the custom controller, just route to the standard one.
return def;
}
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Linq;
using System.Web;
@@ -12,6 +13,7 @@ using umbraco;
using umbraco.cms.businesslogic;
using Umbraco.Core;
using umbraco.cms.businesslogic.template;
using umbraco.interfaces;
namespace Umbraco.Web
{
@@ -24,6 +26,18 @@ namespace Umbraco.Web
/// </remarks>
public static class PublishedContentExtensions
{
/// <summary>
/// Converts an INode to an IPublishedContent item
/// </summary>
/// <param name="node"></param>
/// <returns></returns>
internal static IPublishedContent ConvertFromNode(this INode node)
{
var umbHelper = new UmbracoHelper(UmbracoContext.Current);
return umbHelper.TypedContent(node.Id);
}
/// <summary>
/// Gets the NiceUrl for the content item
/// </summary>
+41 -12
View File
@@ -42,6 +42,31 @@ namespace Umbraco.Web.Routing
}
}
private static bool IsWildcardDomain(Domain d)
{
// supporting null or whitespace for backward compatibility,
// although we should not allow ppl to create them anymore
return string.IsNullOrWhiteSpace(d.Name) || d.Name.StartsWith("*");
}
private static Domain SanitizeForBackwardCompatibility(Domain d)
{
// this is a _really_ nasty one that should be removed in 6.x
// some people were using hostnames such as "/en" which happened to work pre-4.10
// but make _no_ sense at all... and 4.10 throws on them, so here we just try
// to find a way so 4.11 does not throw.
// but, really.
// no.
var context = System.Web.HttpContext.Current;
if (context != null && d.Name.StartsWith("/"))
{
// turn /en into http://whatever.com/en so it becomes a parseable uri
var authority = context.Request.Url.GetLeftPart(UriPartial.Authority);
d.Name = authority + d.Name;
}
return d;
}
/// <summary>
/// Finds the domain that best matches the current uri, into an enumeration of domains.
/// </summary>
@@ -56,7 +81,8 @@ namespace Umbraco.Web.Routing
// we need to order so example.com/foo matches before example.com/
var scheme = current == null ? Uri.UriSchemeHttp : current.Scheme;
var domainsAndUris = domains
.Where(d => !string.IsNullOrEmpty(d.Name) && d.Name != "*")
.Where(d => !IsWildcardDomain(d))
.Select(d => SanitizeForBackwardCompatibility(d))
.Select(d => new { Domain = d, UriString = UriUtility.EndPathWithSlash(UriUtility.StartWithScheme(d.Name, scheme)) })
.OrderByDescending(t => t.UriString)
.Select(t => new DomainAndUri { Domain = t.Domain, Uri = new Uri(t.UriString) });
@@ -96,7 +122,8 @@ namespace Umbraco.Web.Routing
{
var scheme = current == null ? Uri.UriSchemeHttp : current.Scheme;
var domainsAndUris = domains
.Where(d => !string.IsNullOrEmpty(d.Name) && d.Name != "*")
.Where(d => !IsWildcardDomain(d))
.Select(d => SanitizeForBackwardCompatibility(d))
.Select(d => new { Domain = d, UriString = UriUtility.TrimPathEndSlash(UriUtility.StartWithScheme(d.Name, scheme)) })
.OrderByDescending(t => t.UriString)
.Select(t => new DomainAndUri { Domain = t.Domain, Uri = new Uri(t.UriString) });
@@ -112,12 +139,13 @@ namespace Umbraco.Web.Routing
public static bool ExistsDomainInPath(Domain current, string path)
{
var domains = Domain.GetDomains();
var stopNodeId = current == null ? -1 : current.RootNodeId;
return path.Split(',')
.Reverse()
.Select(id => int.Parse(id))
.TakeWhile(id => id != current.RootNodeId)
.Any(id => domains.Any(d => d.RootNodeId == id && !string.IsNullOrEmpty(d.Name) && d.Name != "*"));
.TakeWhile(id => id != stopNodeId)
.Any(id => domains.Any(d => d.RootNodeId == id && !IsWildcardDomain(d)));
}
/// <summary>
@@ -129,20 +157,21 @@ namespace Umbraco.Web.Routing
/// <returns>The deepest wildcard <see cref="Domain"/> in the path, or null.</returns>
public static Domain LookForWildcardDomain(IEnumerable<Domain> domains, string path, int? rootNodeId)
{
var nodeIds = path.Split(',').Select(p => int.Parse(p)).Reverse();
rootNodeId = rootNodeId ?? -1; // every paths begin with -1
var nodeIds = path.Split(',').Select(p => int.Parse(p)).Skip(1).Reverse();
foreach (var nodeId in nodeIds)
{
if (nodeId == rootNodeId) // stop at current domain or root
break;
// supporting null or whitespace for backward compatibility,
// although we should not allow ppl to create them anymore
var domain = domains.Where(d => d.RootNodeId == nodeId && (string.IsNullOrWhiteSpace(d.Name) || d.Name == "*")).FirstOrDefault();
var domain = domains.Where(d => d.RootNodeId == nodeId && IsWildcardDomain(d)).FirstOrDefault();
if (domain != null)
return domain;
// stop at current domain root if any
// "When you perform comparisons with nullable types, if the value of one of the nullable
// types is null and the other is not, all comparisons evaluate to false."
if (nodeId == rootNodeId)
break;
}
return null;
}
+3 -7
View File
@@ -82,13 +82,9 @@ namespace Umbraco.Web.Routing
docreq.PublishedContent = node;
LogHelper.Debug<LookupByNiceUrl>("Query matches, id={0}", () => docreq.DocumentId);
var iscanon = true;
if (docreq.HasDomain)
{
iscanon = !DomainHelper.ExistsDomainInPath(docreq.Domain, node.Path);
if (!iscanon)
LogHelper.Debug<LookupByNiceUrl>("Non canonical url");
}
var iscanon = !DomainHelper.ExistsDomainInPath(docreq.Domain, node.Path);
if (!iscanon)
LogHelper.Debug<LookupByNiceUrl>("Non canonical url");
// do not store if previewing or if non-canonical
if (!docreq.RoutingContext.UmbracoContext.InPreviewMode && iscanon)
+3 -3
View File
@@ -100,7 +100,7 @@ namespace Umbraco.Web.Routing
{
LogHelper.Warn<NiceUrlProvider>(
"Couldn't find any page with nodeId={0}. This is most likely caused by the page not being published.",
nodeId);
() => nodeId);
return NullUrl;
}
@@ -184,7 +184,7 @@ namespace Umbraco.Web.Routing
{
LogHelper.Warn<NiceUrlProvider>(
"Couldn't find any page with nodeId={0}. This is most likely caused by the page not being published.",
nodeId);
() => nodeId);
return new string[] { NullUrl };
}
@@ -278,7 +278,7 @@ namespace Umbraco.Web.Routing
{
// domains were found : return absolute urls
// ignore vdir at that point
uris.AddRange(domainUris.Select(domainUri => new Uri(domainUri.GetLeftPart(UriPartial.Path).TrimEnd('/') + path)));
uris.AddRange(domainUris.Select(domainUri => new Uri(CombinePaths(domainUri.GetLeftPart(UriPartial.Path), path))));
}
// UriFromUmbraco will handle vdir
@@ -203,6 +203,8 @@ namespace Umbraco.Web.Routing
// expected content anymore and the alternate template does not apply.
_publishedContentRequest.AlternateTemplateAlias = _umbracoContext.HttpContext.Request["altTemplate"];
_umbracoContext.HttpContext.Trace.Write(string.Format("test {0}", _publishedContentRequest.AlternateTemplateAlias));
// handle "not found", follow internal redirects, validate access, template
// because these might loop, we have to have some sort of infinite loop detection
int i = 0, j = 0;
+209
View File
@@ -0,0 +1,209 @@
//using System;
//using System.Collections.Generic;
//using System.IO;
//using System.Linq;
//using System.Text;
//using Umbraco.Core.Configuration;
//using Umbraco.Core.IO;
//using umbraco.BusinessLogic.Actions;
//using umbraco.businesslogic;
//using umbraco.cms.presentation.Trees;
//namespace Umbraco.Web.Trees
//{
// [Tree("settings", "partialViews", "Partial Views", sortOrder: 2)]
// public class PartialViewsTree : BaseTree
// {
// public PartialViewsTree(string application) : base(application) { }
// protected override void CreateRootNode(ref XmlTreeNode rootNode)
// {
// rootNode.NodeType = "init" + TreeAlias;
// rootNode.NodeID = "init";
// }
// public override void RenderJS(ref StringBuilder Javascript)
// {
// Javascript.Append(
// @"
// function openView(id) {
// UmbClientMgr.contentFrame('settings/views/editView.aspx?templateID=' + id);
// }
// ");
// }
// public override void Render(ref XmlTree tree)
// {
// string folder = global::umbraco.library.Request("folder");
// string folderPath = umbraco.library.Request("folderPath");
// if (!string.IsNullOrEmpty(folder))
// RenderTemplateFolderItems(folder, folderPath, ref tree);
// else
// {
// if (UmbracoSettings.EnableTemplateFolders)
// RenderTemplateFolders(ref tree);
// RenderTemplates(ref tree);
// }
// }
// private void RenderTemplateFolderItems(string folder, string folderPath, ref XmlTree tree)
// {
// string relPath = SystemDirectories.Masterpages + "/" + folder;
// if (!string.IsNullOrEmpty(folderPath))
// relPath += folderPath;
// string fullPath = IOHelper.MapPath(relPath);
// foreach (string dir in System.IO.Directory.GetDirectories(fullPath))
// {
// System.IO.DirectoryInfo directoryInfo = new DirectoryInfo(dir);
// XmlTreeNode xNode = XmlTreeNode.Create(this);
// xNode.Menu.Clear();
// xNode.Menu.Add(ActionRefresh.Instance);
// xNode.NodeID = "-1";
// xNode.Text = directoryInfo.Name;
// xNode.HasChildren = true;
// xNode.Icon = "folder.gif";
// xNode.OpenIcon = "folder_o.gif";
// xNode.Source = GetTreeServiceUrl(directoryInfo.Name) + "&folder=" + folder + "&folderPath=" + folderPath + "/" + directoryInfo.Name;
// tree.Add(xNode);
// }
// foreach (string file in System.IO.Directory.GetFiles(fullPath))
// {
// System.IO.FileInfo fileinfo = new FileInfo(file);
// string ext = fileinfo.Extension.ToLower().Trim('.');
// XmlTreeNode xNode = XmlTreeNode.Create(this);
// xNode.Menu.Clear();
// xNode.Menu.Add(ActionRefresh.Instance);
// xNode.NodeID = "-1";
// xNode.Text = Path.GetFileName(file);
// xNode.HasChildren = false;
// xNode.Action = "javascript:openScriptEditor('" + relPath + "/" + Path.GetFileName(file) + "');";
// //tree.Add(xNode);
// switch (ext)
// {
// case "master":
// xNode.Icon = "settingTemplate.gif";
// xNode.OpenIcon = "settingTemplate.gif";
// tree.Add(xNode);
// break;
// case "css":
// case "js":
// xNode.Icon = "settingsScript.gif";
// xNode.OpenIcon = "settingsScript.gif";
// tree.Add(xNode);
// break;
// case "xml":
// if (xNode.Text == "skin.xml")
// {
// xNode.Icon = "settingXml.gif";
// xNode.OpenIcon = "settingXml.gif";
// tree.Add(xNode);
// }
// break;
// default:
// break;
// }
// //xNode.Source = GetTreeServiceUrl(s.Alias) + "&skin=" + skin + "&path=" + path;
// }
// }
// private void RenderTemplateFolders(ref XmlTree tree)
// {
// if (base.m_id == -1)
// {
// foreach (string s in Directory.GetDirectories(IO.IOHelper.MapPath(IO.SystemDirectories.Masterpages)))
// {
// var _s = Path.GetFileNameWithoutExtension(s);
// XmlTreeNode xNode = XmlTreeNode.Create(this);
// xNode.NodeID = _s;
// xNode.Text = _s;
// xNode.Icon = "folder.gif";
// xNode.OpenIcon = "folder_o.gif";
// xNode.Source = GetTreeServiceUrl(_s) + "&folder=" + _s;
// xNode.HasChildren = true;
// xNode.Menu.Clear();
// xNode.Menu.Add(ActionRefresh.Instance);
// OnBeforeNodeRender(ref tree, ref xNode, EventArgs.Empty);
// if (xNode != null)
// {
// tree.Add(xNode);
// OnAfterNodeRender(ref tree, ref xNode, EventArgs.Empty);
// }
// }
// }
// }
// private void RenderTemplates(ref XmlTree tree)
// {
// List<Template> templates = null;
// if (base.m_id == -1)
// templates = Template.GetAllAsList().FindAll(delegate(Template t) { return !t.HasMasterTemplate; });
// else
// templates = Template.GetAllAsList().FindAll(delegate(Template t) { return t.MasterTemplate == base.m_id; });
// foreach (Template t in templates)
// {
// XmlTreeNode xNode = XmlTreeNode.Create(this);
// xNode.NodeID = t.Id.ToString();
// xNode.Text = t.Text;
// xNode.Source = GetTreeServiceUrl(t.Id);
// xNode.HasChildren = t.HasChildren;
// if (Umbraco.Core.Configuration.UmbracoSettings.DefaultRenderingEngine == RenderingEngine.Mvc && ViewHelper.ViewExists(t))
// {
// xNode.Action = "javascript:openView(" + t.Id + ");";
// xNode.Icon = "settingView.gif";
// xNode.OpenIcon = "settingView.gif";
// }
// else
// {
// xNode.Action = "javascript:openTemplate(" + t.Id + ");";
// xNode.Icon = "settingTemplate.gif";
// xNode.OpenIcon = "settingTemplate.gif";
// }
// if (t.HasChildren)
// {
// xNode.Icon = "settingMasterTemplate.gif";
// xNode.OpenIcon = "settingMasterTemplate.gif";
// }
// OnBeforeNodeRender(ref tree, ref xNode, EventArgs.Empty);
// if (xNode != null)
// {
// tree.Add(xNode);
// OnAfterNodeRender(ref tree, ref xNode, EventArgs.Empty);
// }
// }
// }
// protected override void CreateAllowedActions(ref List<IAction> actions)
// {
// actions.Clear();
// actions.AddRange(new IAction[] { ActionNew.Instance, ActionDelete.Instance,
// ContextMenuSeperator.Instance, ActionRefresh.Instance });
// }
// }
//}
+12 -1
View File
@@ -249,11 +249,15 @@
<Compile Include="Dynamics\Grouping.cs" />
<Compile Include="Install\InstallPackageController.cs" />
<Compile Include="Install\UmbracoInstallAuthorizeAttribute.cs" />
<Compile Include="Macros\PartialViewMacroController.cs" />
<Compile Include="Macros\PartialViewMacroEngine.cs" />
<Compile Include="Macros\PartialViewMacroPage.cs" />
<Compile Include="Media\ImageUrl.cs" />
<Compile Include="Media\ImageUrlProviderResolver.cs" />
<Compile Include="Media\ImageUrlProviders\ImageUrlProvider.cs" />
<Compile Include="Models\DynamicPublishedContent.cs" />
<Compile Include="Models\DynamicPublishedContentList.cs" />
<Compile Include="Models\PartialViewMacroModel.cs" />
<Compile Include="Mvc\AreaRegistrationExtensions.cs" />
<Compile Include="BaseRest\Configuration\BaseRestSection.cs" />
<Compile Include="BaseRest\BaseRestHandler.cs" />
@@ -318,6 +322,7 @@
<Compile Include="umbraco.presentation\Default.aspx.cs">
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="umbraco.presentation\DLRMacroResult.cs" />
<Compile Include="umbraco.presentation\install\Default.aspx.cs">
<SubType>ASPXCodeBehind</SubType>
</Compile>
@@ -328,6 +333,9 @@
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="umbraco.presentation\LibraryCacheRefresher.cs" />
<Compile Include="umbraco.presentation\MacroCacheContent.cs" />
<Compile Include="umbraco.presentation\macroCacheRefresh.cs" />
<Compile Include="umbraco.presentation\ScriptingMacroResult.cs" />
<Compile Include="umbraco.presentation\umbraco\developer\Macros\editMacro.aspx.cs">
<SubType>ASPXCodeBehind</SubType>
</Compile>
@@ -358,6 +366,7 @@
</Compile>
<Compile Include="umbraco.presentation\umbraco\templateControls\Image.cs" />
<Compile Include="umbraco.presentation\umbraco\uQuery\IGetProperty.cs" />
<Compile Include="umbraco.presentation\XsltExtensionAttribute.cs" />
<Compile Include="UmbracoHelper.cs" />
<Compile Include="Mvc\ViewContextExtensions.cs" />
<Compile Include="Mvc\ViewDataContainerExtensions.cs" />
@@ -1913,7 +1922,9 @@
<Content Include="umbraco.presentation\umbraco\developer\Packages\LoadNitros.ascx" />
<Content Include="umbraco.presentation\umbraco\developer\Packages\SubmitPackage.aspx" />
<Content Include="umbraco.presentation\umbraco\dialogs\about.aspx" />
<Content Include="umbraco.presentation\umbraco\dialogs\AssignDomain.aspx" />
<Content Include="umbraco.presentation\umbraco\dialogs\AssignDomain.aspx">
<SubType>ASPXCodeBehind</SubType>
</Content>
<Content Include="umbraco.presentation\umbraco\dialogs\create.aspx" />
<Content Include="umbraco.presentation\umbraco\dialogs\cruds.aspx" />
<Content Include="umbraco.presentation\umbraco\dialogs\editMacro.aspx" />
@@ -0,0 +1,22 @@
using System;
using System.Web.UI;
namespace umbraco
{
[Obsolete("This has been replaced with ScriptingMacroResult instead")]
public class DLRMacroResult
{
public DLRMacroResult()
{
}
public DLRMacroResult(Control control, Exception resultException)
{
Control = control;
ResultException = resultException;
}
public Control Control { get; set; }
public Exception ResultException { get; set; }
}
}
@@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using umbraco.IO;
using Umbraco.Core.IO;
using umbraco.businesslogic;
using umbraco.interfaces;
@@ -19,8 +19,11 @@ namespace umbraco.presentation
EnsurePathExists(SystemDirectories.Masterpages);
EnsurePathExists(SystemDirectories.Media);
EnsurePathExists(SystemDirectories.Scripts);
EnsurePathExists(SystemDirectories.Usercontrols);
EnsurePathExists(SystemDirectories.UserControls);
EnsurePathExists(SystemDirectories.Xslt);
EnsurePathExists(SystemDirectories.MvcViews);
EnsurePathExists(SystemDirectories.MvcViews + "/Partials");
EnsurePathExists(SystemDirectories.MvcViews + "/MacroPartials");
}
public void EnsurePathExists(string path)
@@ -0,0 +1,26 @@
using System.Web.UI;
namespace umbraco
{
public class MacroCacheContent
{
private readonly Control _control;
private readonly string _id;
public MacroCacheContent(Control control, string ID)
{
_control = control;
_id = ID;
}
public string ID
{
get { return _id; }
}
public Control Content
{
get { return _control; }
}
}
}
@@ -0,0 +1,20 @@
using System;
namespace umbraco
{
public class ScriptingMacroResult
{
public ScriptingMacroResult()
{
}
public ScriptingMacroResult(string result, Exception resultException)
{
Result = result;
ResultException = resultException;
}
public string Result { get; set; }
public Exception ResultException { get; set; }
}
}
@@ -0,0 +1,34 @@
using System;
using System.Security.Permissions;
using System.Web;
namespace umbraco
{
/// <summary>
/// Allows App_Code XSLT extensions to be declared using the [XsltExtension] class attribute.
/// </summary>
/// <remarks>
/// An optional XML namespace can be specified using [XsltExtension("MyNamespace")].
/// </remarks>
[AttributeUsage(AttributeTargets.Class)]
[AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Medium, Unrestricted = false)]
public class XsltExtensionAttribute : Attribute
{
public XsltExtensionAttribute()
{
Namespace = String.Empty;
}
public XsltExtensionAttribute(string ns)
{
Namespace = ns;
}
public string Namespace { get; set; }
public override string ToString()
{
return Namespace;
}
}
}
@@ -213,13 +213,12 @@ namespace umbraco
if (isInitializing)
{
LogHelper.Debug<content>("Initializing content on thread '{0}' (Threadpool? {1})",
HttpContext.Current == null ? null : HttpContext.Current.Trace,
true,
() => Thread.CurrentThread.Name,
() => Thread.CurrentThread.IsThreadPoolThread);
_xmlContent = LoadContent();
LogHelper.Debug<content>("Content initialized (loaded)",
HttpContext.Current == null ? null : HttpContext.Current.Trace);
LogHelper.Debug<content>("Content initialized (loaded)", true);
FireAfterRefreshContent(new RefreshContentEventArgs());
@@ -134,7 +134,7 @@ namespace umbraco
// filter / add preview banner
if (UmbracoContext.Current.InPreviewMode)
{
LogHelper.Debug<UmbracoDefault>("Umbraco is running in preview mode.", Context.Trace);
LogHelper.Debug<UmbracoDefault>("Umbraco is running in preview mode.", true);
if (Response.ContentType.InvariantEquals("text/html")) // ASP.NET default value
{
@@ -1,15 +1,16 @@
using System.IO;
using Umbraco.Core.IO;
using umbraco.BusinessLogic;
using System;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
namespace umbraco.presentation.install.steps
{
using System;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
/// <summary>
/// Summary description for theend.
@@ -34,9 +35,6 @@ namespace umbraco.presentation.install.steps
if (!cms.businesslogic.skinning.Skinning.IsStarterKitInstalled())
customizeSite.Visible = false;
var tempFolder = IOHelper.MapPath("~/App_Data/TEMP/PluginCache");
if(Directory.Exists(tempFolder))
Directory.Delete(tempFolder, true);
}
#region Web Form Designer generated code
+213 -257
View File
@@ -7,7 +7,6 @@ using System.Net;
using System.Net.Security;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
@@ -17,16 +16,17 @@ using System.Web.UI.WebControls;
using System.Xml;
using System.Xml.Xsl;
using Umbraco.Core;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Web;
using Umbraco.Web.Macros;
using Umbraco.Web.Templates;
using umbraco.BusinessLogic;
using umbraco.BusinessLogic.Utils;
using umbraco.cms.businesslogic.macro;
using umbraco.cms.businesslogic.member;
using umbraco.DataLayer;
using umbraco.interfaces;
using umbraco.IO;
using umbraco.NodeFactory;
using umbraco.presentation;
using umbraco.presentation.templateControls;
using umbraco.presentation.xslt.Exslt;
using Content = umbraco.cms.businesslogic.Content;
@@ -296,10 +296,9 @@ namespace umbraco
public Control renderMacro(Hashtable pageElements, int pageId)
{
UmbracoContext.Current.Trace.Write("renderMacro",
string.Format(
"Rendering started (macro: {0}, type: {1}, cacheRate: {2})",
Name, MacroType, Model.CacheDuration));
TraceInfo("renderMacro",
string.Format("Rendering started (macro: {0}, type: {1}, cacheRate: {2})",
Name, MacroType, Model.CacheDuration));
StateHelper.SetContextValue(macrosAddedKey, StateHelper.GetContextValue<int>(macrosAddedKey) + 1);
@@ -326,13 +325,15 @@ namespace umbraco
if (MacroNeedsToBeClearedFromCache(Model, "macroHtml_DateAdded_" + Model.CacheIdentifier))
{
macroHtml = null;
UmbracoContext.Current.Trace.Write("renderMacro",
string.Format("Macro removed from cache due to file change '{0}'.", Model.CacheIdentifier));
TraceInfo("renderMacro",
string.Format("Macro removed from cache due to file change '{0}'.",
Model.CacheIdentifier));
}
else
{
UmbracoContext.Current.Trace.Write("renderMacro",
string.Format("Macro Content loaded from cache '{0}'.", Model.CacheIdentifier));
TraceInfo("renderMacro",
string.Format("Macro Content loaded from cache '{0}'.",
Model.CacheIdentifier));
}
}
@@ -348,14 +349,16 @@ namespace umbraco
if (MacroNeedsToBeClearedFromCache(Model, "macroControl_DateAdded_" + Model.CacheIdentifier))
{
UmbracoContext.Current.Trace.Write("renderMacro",
string.Format("Macro removed from cache due to file change '{0}'.", Model.CacheIdentifier));
TraceInfo("renderMacro",
string.Format("Macro removed from cache due to file change '{0}'.",
Model.CacheIdentifier));
macroControl = null;
}
else
{
UmbracoContext.Current.Trace.Write("renderMacro",
string.Format("Macro Control loaded from cache '{0}'.", Model.CacheIdentifier));
TraceInfo("renderMacro",
string.Format("Macro Control loaded from cache '{0}'.",
Model.CacheIdentifier));
}
}
@@ -369,11 +372,56 @@ namespace umbraco
int macroType = Model.MacroType != MacroTypes.Unknown ? (int)Model.MacroType : MacroType;
switch (macroType)
{
case (int)MacroTypes.PartialView:
TraceInfo("umbracoMacro", "Partial View added (" + Model.TypeName + ")");
try
{
var result = LoadPartialViewMacro(Model);
macroControl = new LiteralControl(result.Result);
if (result.ResultException != null)
{
// we'll throw the error if we run in release mode, show details if we're in release mode!
renderFailed = true;
if (HttpContext.Current != null && !HttpContext.Current.IsDebuggingEnabled)
throw result.ResultException;
}
break;
}
catch (Exception e)
{
renderFailed = true;
Exceptions.Add(e);
LogHelper.WarnWithException<macro>("Error loading MacroEngine script (file: " + ScriptFile + ", Type: '" + Model.TypeName + "'",
true,
e);
var result =
new LiteralControl("Error loading MacroEngine script (file: " + ScriptFile + ")");
/*
string args = "<ul>";
foreach(object key in attributes.Keys)
args += "<li><strong>" + key.ToString() + ": </strong> " + attributes[key] + "</li>";
foreach (object key in pageElements.Keys)
args += "<li><strong>" + key.ToString() + ": </strong> " + pageElements[key] + "</li>";
args += "</ul>";
result.Text += args;
*/
macroControl = result;
break;
}
break;
case (int)MacroTypes.UserControl:
try
{
UmbracoContext.Current.Trace.Write("umbracoMacro",
"Usercontrol added (" + Model.TypeName + ")");
TraceInfo("umbracoMacro","Usercontrol added (" + Model.TypeName + ")");
macroControl = loadUserControl(ScriptType, Model, pageElements);
break;
}
@@ -381,18 +429,17 @@ namespace umbraco
{
renderFailed = true;
Exceptions.Add(e);
UmbracoContext.Current.Trace.Warn("umbracoMacro",
"Error loading userControl (" + Model.TypeName + ")", e);
LogHelper.WarnWithException<macro>("Error loading userControl (" + Model.TypeName + ")", true, e);
macroControl = new LiteralControl("Error loading userControl '" + Model.TypeName + "'");
break;
}
case (int)MacroTypes.CustomControl:
try
{
UmbracoContext.Current.Trace.Write("umbracoMacro",
"Custom control added (" + Model.TypeName + ")");
UmbracoContext.Current.Trace.Write("umbracoMacro",
"ScriptAssembly (" + Model.TypeAssembly + ")");
TraceInfo("umbracoMacro",
"Custom control added (" + Model.TypeName + ")");
TraceInfo("umbracoMacro",
"ScriptAssembly (" + Model.TypeAssembly + ")");
macroControl = loadControl(Model.TypeAssembly, ScriptType, Model, pageElements);
break;
}
@@ -400,10 +447,11 @@ namespace umbraco
{
renderFailed = true;
Exceptions.Add(e);
UmbracoContext.Current.Trace.Warn("umbracoMacro",
"Error loading customControl (Assembly: " +
Model.TypeAssembly +
", Type: '" + Model.TypeName + "'", e);
LogHelper.WarnWithException<macro>("Error loading customControl (Assembly: " +
Model.TypeAssembly +
", Type: '" + Model.TypeName + "'", true, e);
macroControl =
new LiteralControl("Error loading customControl (Assembly: " + Model.TypeAssembly +
", Type: '" +
@@ -416,8 +464,8 @@ namespace umbraco
case (int)MacroTypes.Script:
try
{
UmbracoContext.Current.Trace.Write("umbracoMacro",
"MacroEngine script added (" + ScriptFile + ")");
TraceInfo("umbracoMacro",
"MacroEngine script added (" + ScriptFile + ")");
ScriptingMacroResult result = loadMacroScript(Model);
macroControl = new LiteralControl(result.Result);
if (result.ResultException != null)
@@ -433,9 +481,11 @@ namespace umbraco
{
renderFailed = true;
Exceptions.Add(e);
UmbracoContext.Current.Trace.Warn("umbracoMacro",
"Error loading MacroEngine script (file: " + ScriptFile +
", Type: '" + Model.TypeName + "'", e);
LogHelper.WarnWithException<macro>(
"Error loading MacroEngine script (file: " + ScriptFile + ", Type: '" + Model.TypeName + "'",
true,
e);
var result =
new LiteralControl("Error loading MacroEngine script (file: " + ScriptFile + ")");
@@ -513,8 +563,8 @@ namespace umbraco
if (!(macroControl is LiteralControl))
macroControl = new LiteralControl(outputCacheString);
UmbracoContext.Current.Trace.Write("renderMacro",
string.Format("Macro Content saved to cache '{0}'.", Model.CacheIdentifier));
TraceInfo("renderMacro",
string.Format("Macro Content saved to cache '{0}'.", Model.CacheIdentifier));
}
@@ -535,8 +585,8 @@ namespace umbraco
null);
UmbracoContext.Current.Trace.Write("renderMacro",
string.Format("Macro Control saved to cache '{0}'.", Model.CacheIdentifier));
TraceInfo("renderMacro",
string.Format("Macro Control saved to cache '{0}'.", Model.CacheIdentifier));
}
}
}
@@ -571,8 +621,8 @@ namespace umbraco
if (fileInfo.LastWriteTime.CompareTo(dateMacroAdded) ==1)
{
UmbracoContext.Current.Trace.Write("renderMacro",
string.Format("Macro needs to be removed from cache due to file change '{0}'.", Model.CacheIdentifier));
TraceInfo("renderMacro",
string.Format("Macro needs to be removed from cache due to file change '{0}'.", Model.CacheIdentifier));
return true;
}
@@ -716,7 +766,7 @@ namespace umbraco
return
new LiteralControl("<div style=\"border: 2px solid green; padding: 5px;\"><b>Debug from " +
macro.Name +
"</b><br/><p>" + UmbracoContext.Current.Server.HtmlEncode(macroXML.OuterXml) +
"</b><br/><p>" + HttpContext.Current.Server.HtmlEncode(macroXML.OuterXml) +
"</p></div>");
}
else
@@ -729,19 +779,19 @@ namespace umbraco
{
Control result = CreateControlsFromText(GetXsltTransformResult(macroXML, xsltFile));
UmbracoContext.Current.Trace.Write("umbracoMacro", "After performing transformation");
TraceInfo("umbracoMacro", "After performing transformation");
return result;
}
catch (Exception e)
{
Exceptions.Add(e);
LogHelper.WarnWithException<macro>("Error parsing XSLT file", e);
// inner exception code by Daniel Lindstr?m from SBBS.se
Exception ie = e;
while (ie != null)
{
UmbracoContext.Current.Trace.Warn("umbracoMacro InnerException", ie.Message, ie);
TraceWarn("umbracoMacro InnerException", ie.Message, ie);
ie = ie.InnerException;
}
return new LiteralControl("Error parsing XSLT file: \\xslt\\" + XsltFile);
@@ -750,14 +800,14 @@ namespace umbraco
catch (Exception e)
{
Exceptions.Add(e);
UmbracoContext.Current.Trace.Warn("umbracoMacro", "Error loading XSLT " + Model.Xslt, e);
LogHelper.WarnWithException<macro>("Error loading XSLT " + Model.Xslt, true, e);
return new LiteralControl("Error reading XSLT file: \\xslt\\" + XsltFile);
}
}
}
else
{
UmbracoContext.Current.Trace.Warn("macro", "Xslt is empty");
TraceWarn("macro", "Xslt is empty");
return new LiteralControl(string.Empty);
}
}
@@ -826,12 +876,12 @@ namespace umbraco
{
TextWriter tw = new StringWriter();
UmbracoContext.Current.Trace.Write("umbracoMacro", "Before adding extensions");
TraceInfo("umbracoMacro", "Before adding extensions");
XsltArgumentList xslArgs;
xslArgs = AddXsltExtensions();
var lib = new library();
xslArgs.AddExtensionObject("urn:umbraco.library", lib);
UmbracoContext.Current.Trace.Write("umbracoMacro", "After adding extensions");
TraceInfo("umbracoMacro", "After adding extensions");
// Add parameters
if (parameters == null || !parameters.ContainsKey("currentPage"))
@@ -845,7 +895,7 @@ namespace umbraco
}
// Do transformation
UmbracoContext.Current.Trace.Write("umbracoMacro", "Before performing transformation");
TraceInfo("umbracoMacro", "Before performing transformation");
xslt.Transform(macroXML.CreateNavigator(), xslArgs, tw);
return TemplateUtilities.ResolveUrlsFromTextString(tw.ToString());
}
@@ -992,9 +1042,9 @@ namespace umbraco
{
string extensionNamespace = "urn:" + extension.Key;
xslArgs.AddExtensionObject(extensionNamespace, extension.Value);
UmbracoContext.Current.Trace.Write("umbracoXsltExtension",
String.Format("Extension added: {0}, {1}",
extensionNamespace, extension.Value.GetType().Name));
TraceInfo("umbracoXsltExtension",
String.Format("Extension added: {0}, {1}",
extensionNamespace, extension.Value.GetType().Name));
}
return xslArgs;
@@ -1016,9 +1066,9 @@ namespace umbraco
currentID = umbPage.PageID;
}
UmbracoContext.Current.Trace.Write("umbracoMacro",
"Xslt node adding search start (" + macroPropertyAlias + ",'" +
macroPropertyValue + "')");
TraceInfo("umbracoMacro",
"Xslt node adding search start (" + macroPropertyAlias + ",'" +
macroPropertyValue + "')");
switch (macroPropertyType)
{
case "contentTree":
@@ -1067,34 +1117,34 @@ namespace umbraco
break;
case "contentRandom":
XmlNode source = umbracoXML.GetElementById(macroPropertyValue);
if (source != null)
{
XmlNodeList sourceList = source.SelectNodes("node|*[@isDoc]");
if (sourceList.Count > 0)
{
int rndNumber;
Random r = library.GetRandom();
lock (r)
{
rndNumber = r.Next(sourceList.Count);
}
XmlNode node = macroXML.ImportNode(sourceList[rndNumber], true);
// remove all sub content nodes
foreach (XmlNode n in node.SelectNodes("node|*[@isDoc]"))
node.RemoveChild(n);
if (source != null)
{
XmlNodeList sourceList = source.SelectNodes("node|*[@isDoc]");
if (sourceList.Count > 0)
{
int rndNumber;
Random r = library.GetRandom();
lock (r)
{
rndNumber = r.Next(sourceList.Count);
}
XmlNode node = macroXML.ImportNode(sourceList[rndNumber], true);
// remove all sub content nodes
foreach (XmlNode n in node.SelectNodes("node|*[@isDoc]"))
node.RemoveChild(n);
macroXmlNode.AppendChild(node);
break;
}
else
UmbracoContext.Current.Trace.Warn("umbracoMacro",
"Error adding random node - parent (" + macroPropertyValue +
") doesn't have children!");
}
else
UmbracoContext.Current.Trace.Warn("umbracoMacro",
"Error adding random node - parent (" + macroPropertyValue +
") doesn't exists!");
macroXmlNode.AppendChild(node);
break;
}
else
TraceWarn("umbracoMacro",
"Error adding random node - parent (" + macroPropertyValue +
") doesn't have children!");
}
else
TraceWarn("umbracoMacro",
"Error adding random node - parent (" + macroPropertyValue +
") doesn't exists!");
break;
case "mediaCurrent":
var c = new Content(int.Parse(macroPropertyValue));
@@ -1123,6 +1173,34 @@ namespace umbraco
return string.Empty;
}
/// <summary>
/// Renders a Partial View Macro
/// </summary>
/// <param name="macro"></param>
/// <returns></returns>
internal ScriptingMacroResult LoadPartialViewMacro(MacroModel macro)
{
var retVal = new ScriptingMacroResult();
TraceInfo("umbracoMacro", "Rendering Partial View Macro");
IMacroEngine engine = null;
engine = MacroEngineFactory.GetEngine(PartialViewMacroEngine.EngineName);
var ret = engine.Execute(macro, Node.GetCurrent());
// if the macro engine supports success reporting and executing failed, then return an empty control so it's not cached
if (engine is IMacroEngineResultStatus)
{
var result = engine as IMacroEngineResultStatus;
if (!result.Success)
{
retVal.ResultException = result.ResultException;
}
}
TraceInfo("umbracoMacro", "Rendering Partial View Macro [done]");
retVal.Result = ret;
return retVal;
}
public ScriptingMacroResult loadMacroScript(MacroModel macro)
{
var retVal = new ScriptingMacroResult();
@@ -1225,9 +1303,8 @@ namespace umbraco
if (!File.Exists(currentAss))
return new LiteralControl("Unable to load user control because is does not exist: " + fileName);
asm = Assembly.LoadFrom(currentAss);
if (HttpContext.Current != null)
UmbracoContext.Current.Trace.Write("umbracoMacro", "Assembly file " + currentAss + " LOADED!!");
TraceInfo("umbracoMacro", "Assembly file " + currentAss + " LOADED!!");
}
catch
{
@@ -1236,9 +1313,7 @@ namespace umbraco
".dll")));
}
if (HttpContext.Current != null)
UmbracoContext.Current.Trace.Write("umbracoMacro",
string.Format("Assembly Loaded from ({0}.dll)", fileName));
TraceInfo("umbracoMacro", string.Format("Assembly Loaded from ({0}.dll)", fileName));
type = asm.GetType(controlName);
if (type == null)
return new LiteralControl(string.Format("Unable to get type {0} from assembly {1}",
@@ -1262,13 +1337,8 @@ namespace umbraco
{
PropertyInfo prop = type.GetProperty(mp.Key);
if (prop == null)
{
if (HttpContext.Current != null)
UmbracoContext.Current.Trace.Warn("macro",
string.Format(
"control property '{0}' doesn't exist or aren't accessible (public)",
mp.Key));
{
TraceWarn("macro", string.Format("control property '{0}' doesn't exist or aren't accessible (public)", mp.Key));
continue;
}
@@ -1336,21 +1406,25 @@ namespace umbraco
}*/
}
if (GlobalSettings.DebugMode)
UmbracoContext.Current.Trace.Write("macro.loadControlProperties",
string.Format("Property added '{0}' with value '{1}'",
mp.Key,
propValue));
if (GlobalSettings.DebugMode)
TraceInfo("macro.loadControlProperties",
string.Format("Property added '{0}' with value '{1}'",
mp.Key,
propValue));
}
catch (Exception PropException)
{
Log.Instance.AddException(PropException);
if (GlobalSettings.DebugMode)
LogHelper.WarnWithException<macro>(string.Format(
"Error adding property '{0}' with value '{1}'",
mp.Key, propValue), PropException);
UmbracoContext.Current.Trace.Warn("macro.loadControlProperties",
string.Format(
"Error adding property '{0}' with value '{1}'",
mp.Key, propValue), PropException);
if (GlobalSettings.DebugMode)
{
TraceWarn("macro.loadControlProperties",
string.Format(
"Error adding property '{0}' with value '{1}'",
mp.Key, propValue), PropException);
}
}
}
@@ -1405,21 +1479,30 @@ namespace umbraco
}
}
/// <summary>
/// Loads an usercontrol using reflection into the macro object
/// </summary>
/// <param name="fileName">Filename of the usercontrol - ie. ~wulff.ascx</param>
/// <param name="attributes">The attributes.</param>
/// <param name="pageElements">The page elements.</param>
/// <returns></returns>
public Control loadUserControl(string fileName, MacroModel model, Hashtable pageElements)
/// <summary>
/// Loads an usercontrol using reflection into the macro object
/// </summary>
/// <param name="fileName">Filename of the usercontrol - ie. ~wulff.ascx</param>
/// <param name="model"> </param>
/// <param name="pageElements">The page elements.</param>
/// <returns></returns>
public Control loadUserControl(string fileName, MacroModel model, Hashtable pageElements)
{
Debug.Assert(!string.IsNullOrEmpty(fileName), "fileName cannot be empty");
Debug.Assert(model.Properties != null, "attributes cannot be null");
Debug.Assert(pageElements != null, "pageElements cannot be null");
Mandate.ParameterNotNullOrEmpty(fileName, "fileName");
Mandate.ParameterNotNull(model, "model");
Mandate.ParameterNotNull(pageElements, "pageElements");
try
{
string userControlPath = @"~/" + fileName;
string userControlPath = fileName;
if (!userControlPath.StartsWith("~"))
{
if (userControlPath.StartsWith("/"))
userControlPath = "~" + userControlPath;
else
userControlPath = "~/" + userControlPath;
}
if (!File.Exists(IOHelper.MapPath(userControlPath)))
return new LiteralControl(string.Format("UserControl {0} does not exist.", fileName));
@@ -1440,20 +1523,15 @@ namespace umbraco
TraceInfo(loadUserControlKey, string.Format("Usercontrol added with id '{0}'", oControl.ID));
Type type = oControl.GetType();
if (type == null)
{
TraceWarn(loadUserControlKey, "Unable to retrieve control type: " + fileName);
return oControl;
}
AddCurrentNodeToControl(oControl, type);
AddCurrentNodeToControl(oControl, type);
updateControlProperties(type, oControl, model);
return oControl;
}
catch (Exception e)
{
UmbracoContext.Current.Trace.Warn("macro", string.Format("Error creating usercontrol ({0})", fileName),
e);
LogHelper.WarnWithException<macro>(string.Format("Error creating usercontrol ({0})", fileName), true, e);
return new LiteralControl(
string.Format(
"<div style=\"color: black; padding: 3px; border: 2px solid red\"><b style=\"color:red\">Error creating control ({0}).</b><br/> Maybe file doesn't exists or the usercontrol has a cache directive, which is not allowed! See the tracestack for more information!</div>",
@@ -1477,18 +1555,24 @@ namespace umbraco
}
}
private void TraceInfo(string category, string message)
private static void TraceInfo(string category, string message)
{
if (HttpContext.Current != null)
UmbracoContext.Current.Trace.Write(category, message);
HttpContext.Current.Trace.Write(category, message);
}
private void TraceWarn(string category, string message)
private static void TraceWarn(string category, string message)
{
if (HttpContext.Current != null)
UmbracoContext.Current.Trace.Warn(category, message);
HttpContext.Current.Trace.Warn(category, message);
}
private static void TraceWarn(string category, string message, Exception ex)
{
if (HttpContext.Current != null)
HttpContext.Current.Trace.Warn(category, message, ex);
}
public static string renderMacroStartTag(Hashtable attributes, int pageId, Guid versionId)
{
string div = "<div ";
@@ -1719,132 +1803,4 @@ namespace umbraco
return false;
}
}
public class MacroCacheContent
{
private readonly Control _control;
private readonly string _id;
public MacroCacheContent(Control control, string ID)
{
_control = control;
_id = ID;
}
public string ID
{
get { return _id; }
}
public Control Content
{
get { return _control; }
}
}
public class macroCacheRefresh : ICacheRefresher
{
#region ICacheRefresher Members
public string Name
{
get
{
// TODO: Add templateCacheRefresh.Name getter implementation
return "Macro cache refresher";
}
}
public Guid UniqueIdentifier
{
get
{
// TODO: Add templateCacheRefresh.UniqueIdentifier getter implementation
return new Guid("7B1E683C-5F34-43dd-803D-9699EA1E98CA");
}
}
public void RefreshAll()
{
}
public void Refresh(Guid Id)
{
// Doesn't do anything
}
void ICacheRefresher.Refresh(int Id)
{
macro.GetMacro(Id).removeFromCache();
}
void ICacheRefresher.Remove(int Id)
{
macro.GetMacro(Id).removeFromCache();
}
#endregion
}
/// <summary>
/// Allows App_Code XSLT extensions to be declared using the [XsltExtension] class attribute.
/// </summary>
/// <remarks>
/// An optional XML namespace can be specified using [XsltExtension("MyNamespace")].
/// </remarks>
[AttributeUsage(AttributeTargets.Class)]
[AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Medium, Unrestricted = false)]
public class XsltExtensionAttribute : Attribute
{
public XsltExtensionAttribute()
{
Namespace = String.Empty;
}
public XsltExtensionAttribute(string ns)
{
Namespace = ns;
}
public string Namespace { get; set; }
public override string ToString()
{
return Namespace;
}
}
public class ScriptingMacroResult
{
public ScriptingMacroResult()
{
}
public ScriptingMacroResult(string result, Exception resultException)
{
Result = result;
ResultException = resultException;
}
public string Result { get; set; }
public Exception ResultException { get; set; }
}
[Obsolete("This has been replaced with ScriptingMacroResult instead")]
public class DLRMacroResult
{
public DLRMacroResult()
{
}
public DLRMacroResult(Control control, Exception resultException)
{
Control = control;
ResultException = resultException;
}
public Control Control { get; set; }
public Exception ResultException { get; set; }
}
}
@@ -0,0 +1,49 @@
using System;
using umbraco.interfaces;
namespace umbraco
{
public class macroCacheRefresh : ICacheRefresher
{
#region ICacheRefresher Members
public string Name
{
get
{
// TODO: Add templateCacheRefresh.Name getter implementation
return "Macro cache refresher";
}
}
public Guid UniqueIdentifier
{
get
{
// TODO: Add templateCacheRefresh.UniqueIdentifier getter implementation
return new Guid("7B1E683C-5F34-43dd-803D-9699EA1E98CA");
}
}
public void RefreshAll()
{
}
public void Refresh(Guid Id)
{
// Doesn't do anything
}
void ICacheRefresher.Refresh(int Id)
{
macro.GetMacro(Id).removeFromCache();
}
void ICacheRefresher.Remove(int Id)
{
macro.GetMacro(Id).removeFromCache();
}
#endregion
}
}
+3 -19
View File
@@ -40,23 +40,7 @@ namespace umbraco
readonly Hashtable _elements = new Hashtable();
readonly StringBuilder _pageContent = new StringBuilder();
Control _pageContentControl = new Control();
/// <summary>
/// Returns the trace context to use for debugging, this is for backwards compatibility as people may be execting some of this
/// information in the TraceContext.
/// </summary>
private TraceContext TraceContext
{
get
{
if (HttpContext.Current == null)
{
return null;
}
return HttpContext.Current.Trace;
}
}
Control _pageContentControl = new Control();
#endregion
@@ -292,14 +276,14 @@ namespace umbraco
{
LogHelper.Debug<page>(
string.Format("Aliases must be unique, an element with alias \"{0}\" has already been loaded!", alias),
TraceContext);
true);
}
else
{
_elements[alias] = value;
LogHelper.Debug<page>(
string.Format("Load element \"{0}\"", alias),
TraceContext);
true);
}
}
}
@@ -112,8 +112,13 @@ function openContent(id) {
node.Icon = dd.ContentTypeIcon;
node.OpenIcon = dd.ContentTypeIcon;
}
if (!dd.Published)
node.Style.DimNode();
if (dd.Published == false)
node.Style.DimNode();
if (dd.HasPendingChanges())
node.Style.HighlightNode();
return node;
}
@@ -15,7 +15,6 @@ using umbraco.interfaces;
using umbraco.BusinessLogic.Utils;
using umbraco.BusinessLogic;
using umbraco.BasePages;
using TypeFinder = umbraco.BusinessLogic.Utils.TypeFinder;
namespace umbraco.cms.presentation.Trees
{
@@ -152,12 +151,11 @@ namespace umbraco.cms.presentation.Trees
l.UpgradeToWriteLock();
List<Type> foundITrees = TypeFinder.FindClassesOfType<ITree>();
//var foundITrees = PluginManager.Current.ResolveTrees();
var foundITrees = PluginManager.Current.ResolveTrees();
var objTrees = ApplicationTree.getAll();
List<ApplicationTree> appTrees = new List<ApplicationTree>();
//var appTrees = new List<ApplicationTree>();
var appTrees = new List<ApplicationTree>();
appTrees.AddRange(objTrees);
var apps = Application.getAll();
@@ -339,12 +339,7 @@ namespace umbraco.cms.presentation.Trees
public bool? NotPublished
{
get { return m_notPublished; }
set
{
m_notPublished = value;
if (m_notPublished.HasValue && m_notPublished.Value)
this.Style.HighlightNode();
}
set { m_notPublished = value; }
}
/// <summary>
@@ -1,19 +1,12 @@
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Linq;
using System.Xml;
using umbraco.BasePages;
using umbraco.uicontrols;
using umbraco.cms.businesslogic.datatype;
using umbraco.interfaces;
using umbraco.cms.businesslogic.media;
using Media = umbraco.cms.businesslogic.media.Media;
namespace umbraco.controls.Images
{
@@ -23,7 +16,7 @@ namespace umbraco.controls.Images
/// Includes ability to select where in the media you would like it to upload and also supports client
/// callback methods once complete.
/// </summary>
public partial class UploadMediaImage : System.Web.UI.UserControl
public partial class UploadMediaImage : UserControl
{
public UploadMediaImage()
@@ -42,7 +35,7 @@ namespace umbraco.controls.Images
/// </summary>
public string OnClientUpload { get; set; }
protected IDataType UploadField = new cms.businesslogic.datatype.controls.Factory().GetNewObject(new Guid("5032a6e6-69e3-491d-bb28-cd31cd11086c"));
protected IDataType UploadField = DataTypeDefinition.GetByDataTypeId(new Guid("5032a6e6-69e3-491d-bb28-cd31cd11086c")).DataType;
protected override void OnInit(EventArgs e)
{
@@ -66,39 +59,35 @@ namespace umbraco.controls.Images
protected void SubmitButton_Click(object sender, EventArgs e)
{
int parent = int.Parse(MediaPickerControl.Value);
if (BusinessLogic.User.GetCurrent().StartMediaId != -1 && parent == -1)
parent = BusinessLogic.User.GetCurrent().StartNodeId;
var media = Media.MakeNew(TextBoxTitle.Text, cms.businesslogic.media.MediaType.GetByAlias("image"), BasePage.Current.getUser(), int.Parse(MediaPickerControl.Value));
Media m = Media.MakeNew(TextBoxTitle.Text, cms.businesslogic.media.MediaType.GetByAlias("image"), BasePage.Current.getUser(), int.Parse(MediaPickerControl.Value));
var props = m.getProperties;
foreach (cms.businesslogic.property.Property p in props)
foreach (var property in media.GenericProperties)
{
if (p.PropertyType.DataTypeDefinition.DataType.Id == UploadField.Id)
if (property.PropertyType.DataTypeDefinition.DataType.Id == UploadField.Id)
{
UploadField.DataTypeDefinitionId = p.PropertyType.DataTypeDefinition.Id;
UploadField.Data.PropertyId = p.Id;
UploadField.DataTypeDefinitionId = property.PropertyType.DataTypeDefinition.Id;
UploadField.Data.PropertyId = property.Id;
}
}
UploadField.DataEditor.Save();
// Generate xml on image
m.XmlGenerate(new XmlDocument());
media.XmlGenerate(new XmlDocument());
pane_upload.Visible = false;
//this seems real ugly since we apparently already have the properties above (props)... but this data layer is insane and undecipherable:)
string mainImage = m.getProperty("umbracoFile").Value.ToString();
string mainImage = media.getProperty("umbracoFile").Value.ToString();
string extension = mainImage.Substring(mainImage.LastIndexOf(".") + 1, mainImage.Length - mainImage.LastIndexOf(".") - 1);
var thumbnail = mainImage.Remove(mainImage.Length - extension.Length - 1, extension.Length + 1) + "_thumb.jpg";
string width = m.getProperty("umbracoWidth").Value.ToString();
string height = m.getProperty("umbracoHeight").Value.ToString();
int id = m.Id;
string width = media.getProperty("umbracoWidth").Value.ToString();
string height = media.getProperty("umbracoHeight").Value.ToString();
int id = media.Id;
feedback.Style.Add("margin-top", "8px");
feedback.type = uicontrols.Feedback.feedbacktype.success;
if (mainImage.StartsWith("~")) mainImage = mainImage.Substring(1);
if (thumbnail.StartsWith("~")) thumbnail = thumbnail.Substring(1);
feedback.Text += "<div style=\"text-align: center\"> <a target=\"_blank\" href='" + umbraco.IO.IOHelper.ResolveUrl(umbraco.IO.SystemDirectories.Umbraco) + "/.." + mainImage + "'><img src='" + umbraco.IO.IOHelper.ResolveUrl(umbraco.IO.SystemDirectories.Umbraco) + "/.." + thumbnail + "' style='border: none;'/><br/><br/>";
feedback.Text += "<div style=\"text-align: center\"> <a target=\"_blank\" href='" + mainImage + "'><img src='" + thumbnail + "' style='border: none;'/><br/><br/>";
feedback.Text += ui.Text("thumbnailimageclickfororiginal") + "</a><br/><br/></div>";
if (!string.IsNullOrEmpty(OnClientUpload))
@@ -106,7 +95,7 @@ namespace umbraco.controls.Images
feedback.Text += @"
<script type=""text/javascript"">
jQuery(document).ready(function() {
" + OnClientUpload + @".call(this, {imagePath: '" + mainImage + @"', thumbnailPath: '" + thumbnail + @"', width: " + width + @", height: " + height + @", id: " + id.ToString() + @"});
" + OnClientUpload + @".call(this, {imagePath: '" + mainImage + @"', thumbnailPath: '" + thumbnail + @"', width: " + width + @", height: " + height + @", id: " + id + @"});
});
</script>";
}
@@ -6,14 +6,13 @@ using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.IO;
using Umbraco.Core.IO;
using umbraco.BasePages;
using umbraco.presentation.cache;
using umbraco.uicontrols;
using umbraco.DataLayer;
using umbraco.cms.presentation.Trees;
using umbraco.cms.businesslogic.macro;
using umbraco.IO;
namespace umbraco.cms.presentation.developer
{
@@ -25,7 +24,6 @@ namespace umbraco.cms.presentation.developer
public editMacro()
{
CurrentApp = BusinessLogic.DefaultApps.developer.ToString();
}
protected PlaceHolder buttons;
@@ -46,39 +44,20 @@ namespace umbraco.cms.presentation.developer
.SetActiveTreeType(TreeDefinitionCollection.Instance.FindTree<loadMacros>().Tree.Alias)
.SyncTree("-1,init," + m_macro.Id.ToString(), false);
macroName.Text = m_macro.Name;
macroAlias.Text = m_macro.Alias;
string tempMacroAssembly = m_macro.Assembly == null ? "" : m_macro.Assembly;
string tempMacroType = m_macro.Type == null ? "" : m_macro.Type;
macroXslt.Text = m_macro.Xslt;
macroPython.Text = m_macro.ScriptingFile;
cachePeriod.Text = m_macro.RefreshRate.ToString();
string tempMacroAssembly = m_macro.Assembly ?? "";
string tempMacroType = m_macro.Type ?? "";
macroRenderContent.Checked = m_macro.RenderContent;
macroEditor.Checked = m_macro.UseInEditor;
cacheByPage.Checked = m_macro.CacheByPage;
cachePersonalized.Checked = m_macro.CachePersonalized;
// Populate either user control or custom control
if (tempMacroType != string.Empty && tempMacroAssembly != string.Empty)
{
macroAssembly.Text = tempMacroAssembly;
macroType.Text = tempMacroType;
}
else
{
macroUserControl.Text = tempMacroType;
}
PopulateFieldsOnLoad(m_macro, tempMacroAssembly, tempMacroType);
// Check for assemblyBrowser
if (tempMacroType.IndexOf(".ascx") > 0)
assemblyBrowserUserControl.Controls.Add(
new LiteralControl("<br/><button onClick=\"UmbClientMgr.openModalWindow('" + umbraco.IO.IOHelper.ResolveUrl(umbraco.IO.SystemDirectories.Umbraco) + "/developer/macros/assemblyBrowser.aspx?fileName=" + macroUserControl.Text +
new LiteralControl("<br/><button onClick=\"UmbClientMgr.openModalWindow('" + IOHelper.ResolveUrl(SystemDirectories.Umbraco) + "/developer/macros/assemblyBrowser.aspx?fileName=" + macroUserControl.Text +
"&macroID=" + m_macro.Id.ToString() +
"', 'Browse Properties', true, 475,500); return false;\" class=\"guiInputButton\"><img src=\"../../images/editor/propertiesNew.gif\" align=\"absmiddle\" style=\"width: 18px; height: 17px; padding-right: 5px;\"/> Browse properties</button>"));
else if (tempMacroType != string.Empty && tempMacroAssembly != string.Empty)
assemblyBrowser.Controls.Add(
new LiteralControl("<br/><button onClick=\"UmbClientMgr.openModalWindow('" + umbraco.IO.IOHelper.ResolveUrl(umbraco.IO.SystemDirectories.Umbraco) + "/developer/macros/assemblyBrowser.aspx?fileName=" + macroAssembly.Text +
new LiteralControl("<br/><button onClick=\"UmbClientMgr.openModalWindow('" + IOHelper.ResolveUrl(SystemDirectories.Umbraco) + "/developer/macros/assemblyBrowser.aspx?fileName=" + macroAssembly.Text +
"&macroID=" + m_macro.Id.ToString() + "&type=" + macroType.Text +
"', 'Browse Properties', true, 475,500); return false\" class=\"guiInputButton\"><img src=\"../../images/editor/propertiesNew.gif\" align=\"absmiddle\" style=\"width: 18px; height: 17px; padding-right: 5px;\"/> Browse properties</button>"));
@@ -86,46 +65,32 @@ namespace umbraco.cms.presentation.developer
macroPropertyBind();
// Load xslt files from default dir
populateXsltFiles();
PopulateXsltFiles();
// Load python files from default dir
populatePythonFiles();
PopulatePythonFiles();
// Load usercontrols
populateUserControls(IOHelper.MapPath(SystemDirectories.Usercontrols));
PopulateUserControls(IOHelper.MapPath(SystemDirectories.UserControls));
userControlList.Items.Insert(0, new ListItem("Browse usercontrols on server...", string.Empty));
userControlList.Attributes.Add("onChange",
"document.getElementById('" + macroUserControl.ClientID + "').value = this[this.selectedIndex].value;");
}
else
{
int macroID = Convert.ToInt32(Request.QueryString["macroID"]);
string tempMacroAssembly = macroAssembly.Text;
string tempMacroType = macroType.Text;
string tempCachePeriod = cachePeriod.Text;
if (tempCachePeriod == string.Empty)
tempCachePeriod = "0";
if (tempMacroAssembly == string.Empty && macroUserControl.Text != string.Empty)
tempMacroType = macroUserControl.Text;
// Save macro
m_macro.UseInEditor = macroEditor.Checked;
m_macro.RenderContent = macroRenderContent.Checked;
m_macro.CacheByPage = cacheByPage.Checked;
m_macro.CachePersonalized = cachePersonalized.Checked;
m_macro.RefreshRate = Convert.ToInt32(tempCachePeriod);
m_macro.Alias = macroAlias.Text;
m_macro.Name = macroName.Text;
m_macro.Assembly = tempMacroAssembly;
m_macro.Type = tempMacroType;
m_macro.Xslt = macroXslt.Text;
m_macro.ScriptingFile = macroPython.Text;
m_macro.Save();
SetMacroValuesFromPostBack(m_macro, Convert.ToInt32(tempCachePeriod), tempMacroAssembly, tempMacroType);
m_macro.Save();
// Save elements
foreach (RepeaterItem item in macroProperties.Items)
{
@@ -167,14 +132,62 @@ namespace umbraco.cms.presentation.developer
}
}
private void getXsltFilesFromDir(string orgPath, string path, ArrayList files)
/// <summary>
/// Populates the control (textbox) values on page load
/// </summary>
/// <param name="macro"></param>
/// <param name="macroAssemblyValue"></param>
/// <param name="macroTypeValue"></param>
protected virtual void PopulateFieldsOnLoad(Macro macro, string macroAssemblyValue, string macroTypeValue)
{
macroName.Text = macro.Name;
macroAlias.Text = macro.Alias;
macroXslt.Text = macro.Xslt;
macroPython.Text = macro.ScriptingFile;
cachePeriod.Text = macro.RefreshRate.ToString();
macroRenderContent.Checked = macro.RenderContent;
macroEditor.Checked = macro.UseInEditor;
cacheByPage.Checked = macro.CacheByPage;
cachePersonalized.Checked = macro.CachePersonalized;
// Populate either user control or custom control
if (macroTypeValue != string.Empty && macroAssemblyValue != string.Empty)
{
macroAssembly.Text = macroAssemblyValue;
macroType.Text = macroTypeValue;
}
else
{
macroUserControl.Text = macroTypeValue;
}
}
/// <summary>
/// Sets the values on the Macro object from the values posted back before saving the macro
/// </summary>
protected virtual void SetMacroValuesFromPostBack(Macro macro, int macroCachePeriod, string macroAssemblyValue, string macroTypeValue)
{
macro.UseInEditor = macroEditor.Checked;
macro.RenderContent = macroRenderContent.Checked;
macro.CacheByPage = cacheByPage.Checked;
macro.CachePersonalized = cachePersonalized.Checked;
macro.RefreshRate = macroCachePeriod;
macro.Alias = macroAlias.Text;
macro.Name = macroName.Text;
macro.Assembly = macroAssemblyValue;
macro.Type = macroTypeValue;
macro.Xslt = macroXslt.Text;
macro.ScriptingFile = macroPython.Text;
}
private void GetXsltFilesFromDir(string orgPath, string path, ArrayList files)
{
DirectoryInfo dirInfo = new DirectoryInfo(path);
// Populate subdirectories
DirectoryInfo[] dirInfos = dirInfo.GetDirectories();
foreach (DirectoryInfo dir in dirInfos)
getXsltFilesFromDir(orgPath, path + "/" + dir.Name, files);
GetXsltFilesFromDir(orgPath, path + "/" + dir.Name, files);
FileInfo[] fileInfo = dirInfo.GetFiles("*.xsl*");
@@ -182,19 +195,17 @@ namespace umbraco.cms.presentation.developer
files.Add((path.Replace(orgPath, string.Empty).Trim('/') + "/" + file.Name).Trim('/'));
}
private void populateXsltFiles()
private void PopulateXsltFiles()
{
ArrayList xslts = new ArrayList();
string xsltDir = IOHelper.MapPath(SystemDirectories.Xslt + "/");
getXsltFilesFromDir(xsltDir, xsltDir, xslts);
GetXsltFilesFromDir(xsltDir, xsltDir, xslts);
xsltFiles.DataSource = xslts;
xsltFiles.DataBind();
xsltFiles.Items.Insert(0, new ListItem("Browse xslt files on server...", string.Empty));
xsltFiles.Attributes.Add("onChange",
"document.getElementById('" + macroXslt.ClientID + "').value = this[this.selectedIndex].value; document.getElementById('" + macroPython.ClientID + "').value =''");
}
private void getPythonFilesFromDir(string orgPath, string path, ArrayList files)
private void GetPythonFilesFromDir(string orgPath, string path, ArrayList files)
{
var dirInfo = new DirectoryInfo(path);
if (!dirInfo.Exists)
@@ -207,19 +218,17 @@ namespace umbraco.cms.presentation.developer
// Populate subdirectories
var dirInfos = dirInfo.GetDirectories();
foreach (var dir in dirInfos)
getPythonFilesFromDir(orgPath, path + "/" + dir.Name + "/", files);
GetPythonFilesFromDir(orgPath, path + "/" + dir.Name + "/", files);
}
private void populatePythonFiles()
private void PopulatePythonFiles()
{
ArrayList pythons = new ArrayList();
string pythonDir = IOHelper.MapPath(SystemDirectories.MacroScripts + "/");
getPythonFilesFromDir(pythonDir, pythonDir, pythons);
GetPythonFilesFromDir(pythonDir, pythonDir, pythons);
pythonFiles.DataSource = pythons;
pythonFiles.DataBind();
pythonFiles.Items.Insert(0, new ListItem("Browse scripting files on server...", string.Empty));
pythonFiles.Attributes.Add("onChange",
"document.getElementById('" + macroPython.ClientID + "').value = this[this.selectedIndex].value; document.getElementById('" + macroXslt.ClientID + "').value = ''");
}
public void deleteMacroProperty(object sender, EventArgs e)
@@ -304,16 +313,16 @@ namespace umbraco.cms.presentation.developer
}
}
private void populateUserControls(string path)
private void PopulateUserControls(string path)
{
DirectoryInfo di = new DirectoryInfo(path);
string rootDir = IOHelper.MapPath(SystemDirectories.Root);
string rootDir = IOHelper.MapPath(SystemDirectories.UserControls);
foreach (FileInfo uc in di.GetFiles("*.ascx"))
{
userControlList.Items.Add(
new ListItem(
new ListItem(SystemDirectories.UserControls +
uc.FullName.Substring(rootDir.Length).Replace(IOHelper.DirSepChar, '/')));
/*
uc.FullName.IndexOf(usercontrolsDir),
@@ -322,7 +331,7 @@ namespace umbraco.cms.presentation.developer
}
foreach (DirectoryInfo dir in di.GetDirectories())
populateUserControls(dir.FullName);
PopulateUserControls(dir.FullName);
}
#region Web Form Designer generated code
@@ -418,15 +427,6 @@ namespace umbraco.cms.presentation.developer
/// </remarks>
protected global::umbraco.uicontrols.Pane Pane1_2;
/// <summary>
/// Table2 control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.HtmlControls.HtmlTable Table2;
/// <summary>
/// macroXslt control.
/// </summary>
@@ -22,6 +22,7 @@
<cc1:PropertyPanel runat="server" ID="prop_domain" Text="Domain">
<asp:TextBox ID="DomainName" runat="server" Width="252px"></asp:TextBox>
<asp:RequiredFieldValidator ControlToValidate="DomainName" ErrorMessage="*" ID="DomainValidator" runat="server" Display="Dynamic" />
<asp:RegularExpressionValidator ControlToValidate="DomainName" ErrorMessage="*" ID="DomainValidator2" runat="server" Display="Dynamic" />
<br /><small><%= umbraco.ui.Text("assignDomain", "domainHelp") %></small>
</cc1:PropertyPanel>
@@ -50,7 +50,7 @@ namespace umbraco.dialogs
{
Domain d = new Domain(editDomain);
selectedLanguage = d.Language.id;
DomainName.Text = d.Name;
DomainName.Text = d.Name.StartsWith("*") ? "*" : d.Name;
ok.Text = ui.Text("general", "update", base.getUser());
}
@@ -58,6 +58,10 @@ namespace umbraco.dialogs
LanguageValidator.ErrorMessage = ui.Text("defaultdialogs", "requiredField", base.getUser()) + "<br/>";
DomainValidator.ErrorMessage = ui.Text("defaultdialogs", "requiredField", base.getUser());
DomainValidator2.ErrorMessage = ui.Text("assignDomain", "invalidDomain", base.getUser());
//DomainValidator2.ValidationExpression = @"^(?i:http[s]?://)?([-\w]+(\.[-\w]+)*)(:\d+)?(/[-\w]*)?$";
DomainValidator2.ValidationExpression = @"^(\*|((?i:http[s]?://)?([-\w]+(\.[-\w]+)*)(:\d+)?(/[-\w]*)?))$";
Languages.Items.Add(new ListItem(ui.Text("general", "choose", base.getUser()), ""));
foreach (Language l in Language.getAll)
{
@@ -82,7 +86,8 @@ namespace umbraco.dialogs
allDomains.Text = "<table border=\"0\" cellspacing=\"10\">";
foreach (Domain d in domainList) {
allDomains.Text += "<tr><td>" + d.Name + "</td><td>(" + d.Language.CultureAlias + ")</td><td><a href=\"?id=" + currentID + "&editDomain=" +
var name = d.Name.StartsWith("*") ? "*" : d.Name;
allDomains.Text += "<tr><td>" + name + "</td><td>(" + d.Language.CultureAlias + ")</td><td><a href=\"?id=" + currentID + "&editDomain=" +
d.Id.ToString() + "\">" + ui.Text("edit") + "</a></td><td><a href=\"?id=" + currentID +
"&delDomain=" + d.Id.ToString() + "\" onClick=\"return confirm('" +
ui.Text("defaultdialogs", "confirmdelete", base.getUser()) +
@@ -120,11 +125,14 @@ namespace umbraco.dialogs
}
else
{
if( !Domain.Exists(DomainName.Text.ToLower())) {
Domain.MakeNew(DomainName.Text, currentID, int.Parse(Languages.SelectedValue));
FeedBackMessage.Text = ui.Text("assignDomain", "domainCreated", DomainName.Text, base.getUser());
// have to handle wildcard
var domainName = DomainName.Text.Trim();
domainName = domainName == "*" ? ("*" + currentID.ToString()) : domainName;
if (!Domain.Exists(domainName.ToLower()))
{
Domain.MakeNew(domainName, currentID, int.Parse(Languages.SelectedValue));
FeedBackMessage.Text = ui.Text("assignDomain", "domainCreated", domainName, base.getUser());
FeedBackMessage.type = umbraco.uicontrols.Feedback.feedbacktype.success;
DomainName.Text = "";
@@ -134,7 +142,7 @@ namespace umbraco.dialogs
//this is probably the worst webform I've ever seen...
Response.Redirect("AssignDomain.aspx?id=" + currentID.ToString());
} else {
FeedBackMessage.Text = ui.Text("assignDomain", "domainExists", DomainName.Text, base.getUser());
FeedBackMessage.Text = ui.Text("assignDomain", "domainExists", DomainName.Text.Trim(), base.getUser());
FeedBackMessage.type = umbraco.uicontrols.Feedback.feedbacktype.error;
}
}
@@ -57,6 +57,15 @@ namespace umbraco.dialogs {
/// </remarks>
protected global::System.Web.UI.WebControls.RequiredFieldValidator DomainValidator;
/// <summary>
/// DomainValidator2 control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.RegularExpressionValidator DomainValidator2;
/// <summary>
/// prop_lang control.
/// </summary>
@@ -323,6 +323,9 @@ namespace umbraco.cms.presentation
UnPublish.Visible = true;
_documentHasPublishedVersion = _document.HasPublishedVersion();
foreach (var descendant in _document.GetDescendants().Cast<Document>().Where(descendant => descendant.HasPublishedVersion()))
library.UpdateDocumentCache(descendant.Id);
}
else
{
@@ -349,6 +352,9 @@ namespace umbraco.cms.presentation
library.UnPublishSingleNode(_document.Id);
Current.ClientTools.SyncTree(_document.Path, true);
ClientTools.ShowSpeechBubble(speechBubbleIcon.success, ui.Text("unpublish"), ui.Text("speechBubbles", "contentUnpublished"));
//newPublishStatus.Text = "0";
}
@@ -1,9 +1,7 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Configuration;
using System.Web.Script.Serialization;
@@ -11,6 +9,7 @@ using System.Web.Security;
using System.Web.UI;
using System.Xml;
using System.Xml.Serialization;
using Umbraco.Core.Logging;
using umbraco.BasePages;
using umbraco.BusinessLogic;
using umbraco.businesslogic.Exceptions;
@@ -137,19 +136,15 @@ namespace umbraco.presentation.umbraco.webservices
{
var pathParts = context.Request["path"].Trim('/').Split('/');
foreach (var pathPart in pathParts)
{
if (!string.IsNullOrEmpty(pathPart))
{
foreach (var pathPart in pathParts.Where(part => string.IsNullOrWhiteSpace(part) == false))
parentNode = GetOrCreateFolder(parentNode, pathPart);
}
}
parentNodeId = parentNode.Id;
}
// Check whether to replace existing
var parsed = false;
bool replaceExisting = (context.Request["replaceExisting"] == "1" || (bool.TryParse(context.Request["replaceExisting"], out parsed) && parsed));
bool parsed;
var replaceExisting = (context.Request["replaceExisting"] == "1" || (bool.TryParse(context.Request["replaceExisting"], out parsed) && parsed));
// loop through uploaded files
for (var j = 0; j < context.Request.Files.Count; j++)
@@ -190,22 +185,20 @@ namespace umbraco.presentation.umbraco.webservices
scripts.SyncTree(parentNode.Path, true);
// log succes
Log.Add(LogTypes.New, parentNodeId, "Succes");
LogHelper.Info<MediaUploader>(string.Format("Successful upload to parent ID: {0}", parentNodeId));
}
catch (Exception e)
{
// log error
Log.Add(LogTypes.Error, parentNodeId, e.ToString());
LogHelper.Error<MediaUploader>(string.Format("Error uploading to parent ID {0}", parentNodeId), e);
}
}
else
{
// log error
Log.Add(LogTypes.Error, -1, "Parent node id is in incorrect format");
LogHelper.Warn<MediaUploader>(string.Format("Parent node id is in incorrect format: {0}", parentNodeId));
}
return new UploadResponse();
}
@@ -217,16 +210,16 @@ namespace umbraco.presentation.umbraco.webservices
if (GlobalSettings.UseSSL && !context.Request.IsSecureConnection)
throw new UserAuthorizationException("This installation requires a secure connection (via SSL). Please update the URL to include https://");
string username = context.Request["username"];
string password = context.Request["password"];
string ticket = context.Request["ticket"];
var username = context.Request["username"];
var password = context.Request["password"];
var ticket = context.Request["ticket"];
bool isValid = false;
var isValid = false;
if (!string.IsNullOrEmpty(username) && !string.IsNullOrEmpty(password))
{
var mp = Membership.Providers[UmbracoSettings.DefaultBackofficeProvider];
if (mp.ValidateUser(username, password))
if (mp != null && mp.ValidateUser(username, password))
{
var user = new User(username);
isValid = user.Applications.Any(app => app.alias == "media");
@@ -239,6 +232,8 @@ namespace umbraco.presentation.umbraco.webservices
{
var t = FormsAuthentication.Decrypt(ticket);
var user = new User(username);
if (t != null)
isValid = user.LoginName.ToLower() == t.Name.ToLower() && user.Applications.Any(app => app.alias == "media");
if (isValid)
@@ -278,14 +273,13 @@ namespace umbraco.presentation.umbraco.webservices
if (appSetting > 0)
return appSetting;
var configXml = new XmlDocument();
configXml.PreserveWhitespace = true;
var configXml = new XmlDocument { PreserveWhitespace = true };
configXml.Load(HttpContext.Current.Server.MapPath("/web.config"));
var requestLimitsNode = configXml.SelectSingleNode("//configuration/system.webServer/security/requestFiltering/requestLimits");
if (requestLimitsNode != null)
{
if (requestLimitsNode.Attributes["maxAllowedContentLength"] != null)
if (requestLimitsNode.Attributes != null && requestLimitsNode.Attributes["maxAllowedContentLength"] != null)
{
var maxAllowedContentLength = Convert.ToInt32(requestLimitsNode.Attributes["maxAllowedContentLength"].Value);
if (maxAllowedContentLength > 0)
@@ -294,10 +288,8 @@ namespace umbraco.presentation.umbraco.webservices
}
var httpRuntime = ConfigurationManager.GetSection("system.web/httpRuntime") as HttpRuntimeSection;
if (httpRuntime != null)
return httpRuntime.MaxRequestLength;
return 4096;
return httpRuntime == null ? 4096 : httpRuntime.MaxRequestLength;
}
private Media GetOrCreateFolder(Media parent, string name)
@@ -260,6 +260,10 @@ namespace umbraco.BusinessLogic
LoadXml(doc =>
{
var el = doc.Root.Elements("add").SingleOrDefault(x => x.Attribute("alias").Value == alias && x.Attribute("application").Value == applicationAlias);
if (el == null)
{
doc.Root.Add(new XElement("add",
new XAttribute("silent", silent),
new XAttribute("initialize", initialize),
@@ -272,6 +276,7 @@ namespace umbraco.BusinessLogic
new XAttribute("assembly", assemblyName),
new XAttribute("type", type),
new XAttribute("action", string.IsNullOrEmpty(action) ? "" : action)));
}
}, true);
}
@@ -31,7 +31,7 @@ namespace umbraco.BusinessLogic
public ApplicationTreeRegistrar()
{
//don't do anything if the application is not configured!
if (!ApplicationContext.Current.IsConfigured)
if (ApplicationContext.Current == null || !ApplicationContext.Current.IsConfigured)
return;
// Load all Trees by attribute and add them to the XML config
+1 -2
View File
@@ -87,8 +87,7 @@ namespace umbraco.BusinessLogic
if (UmbracoSettings.DisabledLogTypes != null &&
UmbracoSettings.DisabledLogTypes.SelectSingleNode(String.Format("//logTypeAlias [. = '{0}']", type.ToString().ToLower())) == null)
{
if (comment.Length > 3999)
if (comment != null && comment.Length > 3999)
comment = comment.Substring(0, 3955) + "...";
if (UmbracoSettings.EnableAsyncLogging)
@@ -13,7 +13,8 @@ using ICSharpCode.SharpZipLib;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.Zip.Compression;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
using Umbraco.Core;
using Umbraco.Core.Logging;
using umbraco.cms.businesslogic.web;
using umbraco.cms.businesslogic.propertytype;
using umbraco.BusinessLogic;
@@ -76,7 +77,7 @@ namespace umbraco.cms.businesslogic.packager
public bool ContainsMacroConflict { get { return _containsMacroConflict; } }
public IDictionary<string, string> ConflictingMacroAliases { get { return _conflictingMacroAliases; } }
public bool ContainsUnsecureFiles { get { return _containUnsecureFiles; } }
public List<string> UnsecureFiles { get { return _unsecureFiles; } }
@@ -145,7 +146,7 @@ namespace umbraco.cms.businesslogic.packager
_macros.Add(MacroToAdd);
}
/// <summary>
/// Imports the specified package
@@ -154,33 +155,39 @@ namespace umbraco.cms.businesslogic.packager
/// <returns></returns>
public string Import(string InputFile)
{
string tempDir = "";
if (File.Exists(IOHelper.MapPath(SystemDirectories.Data + Path.DirectorySeparatorChar + InputFile)))
using (DisposableTimer.DebugDuration<Installer>(
() => "Importing package file " + InputFile,
() => "Package file " + InputFile + "imported"))
{
FileInfo fi = new FileInfo(IOHelper.MapPath(SystemDirectories.Data + Path.DirectorySeparatorChar + InputFile));
// Check if the file is a valid package
if (fi.Extension.ToLower() == ".umb")
string tempDir = "";
if (File.Exists(IOHelper.MapPath(SystemDirectories.Data + Path.DirectorySeparatorChar + InputFile)))
{
try
FileInfo fi = new FileInfo(IOHelper.MapPath(SystemDirectories.Data + Path.DirectorySeparatorChar + InputFile));
// Check if the file is a valid package
if (fi.Extension.ToLower() == ".umb")
{
tempDir = unPack(fi.FullName);
LoadConfig(tempDir);
}
catch (Exception unpackE)
{
throw new Exception("Error unpacking extension...", unpackE);
try
{
tempDir = unPack(fi.FullName);
LoadConfig(tempDir);
}
catch (Exception unpackE)
{
throw new Exception("Error unpacking extension...", unpackE);
}
}
else
throw new Exception("Error - file isn't a package (doesn't have a .umb extension). Check if the file automatically got named '.zip' upon download.");
}
else
throw new Exception("Error - file isn't a package (doesn't have a .umb extension). Check if the file automatically got named '.zip' upon download.");
throw new Exception("Error - file not found. Could find file named '" + IOHelper.MapPath(SystemDirectories.Data + Path.DirectorySeparatorChar + InputFile) + "'");
return tempDir;
}
else
throw new Exception("Error - file not found. Could find file named '" + IOHelper.MapPath(SystemDirectories.Data + Path.DirectorySeparatorChar + InputFile) + "'");
return tempDir;
}
public int CreateManifest(string tempDir, string guid, string repoGuid) {
public int CreateManifest(string tempDir, string guid, string repoGuid)
{
//This is the new improved install rutine, which chops up the process into 3 steps, creating the manifest, moving files, and finally handling umb objects
string _packName = xmlHelper.GetNodeValue(_packageConfig.DocumentElement.SelectSingleNode("/umbPackage/info/package/name"));
string _packAuthor = xmlHelper.GetNodeValue(_packageConfig.DocumentElement.SelectSingleNode("/umbPackage/info/author/name"));
@@ -216,225 +223,268 @@ namespace umbraco.cms.businesslogic.packager
insPack.Data.PackageGuid = guid; //the package unique key.
insPack.Data.RepositoryGuid = repoGuid; //the repository unique key, if the package is a file install, the repository will not get logged.
insPack.Save();
return insPack.Data.Id;
}
public void InstallFiles(int packageId, string tempDir) {
public void InstallFiles(int packageId, string tempDir)
{
using (DisposableTimer.DebugDuration<Installer>(
() => "Installing package files for package id " + packageId + " into temp folder " + tempDir,
() => "Package file installation complete for package id " + packageId))
{
//retrieve the manifest to continue installation
packager.InstalledPackage insPack = packager.InstalledPackage.GetById(packageId);
//retrieve the manifest to continue installation
packager.InstalledPackage insPack = packager.InstalledPackage.GetById(packageId);
// Move files
//string virtualBasePath = System.Web.HttpContext.Current.Request.ApplicationPath;
string basePath = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath;
// Move files
//string virtualBasePath = System.Web.HttpContext.Current.Request.ApplicationPath;
string basePath = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath;
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("//file"))
{
//we enclose the whole file-moving to ensure that the entire installer doesn't crash
try
{
String destPath = getFileName(basePath, xmlHelper.GetNodeValue(n.SelectSingleNode("orgPath")));
String sourceFile = getFileName(tempDir, xmlHelper.GetNodeValue(n.SelectSingleNode("guid")));
String destFile = getFileName(destPath, xmlHelper.GetNodeValue(n.SelectSingleNode("orgName")));
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("//file")) {
//we enclose the whole file-moving to ensure that the entire installer doesn't crash
try {
String destPath = getFileName(basePath, xmlHelper.GetNodeValue(n.SelectSingleNode("orgPath")));
String sourceFile = getFileName(tempDir, xmlHelper.GetNodeValue(n.SelectSingleNode("guid")));
String destFile = getFileName(destPath, xmlHelper.GetNodeValue(n.SelectSingleNode("orgName")));
// Create the destination directory if it doesn't exist
if (!Directory.Exists(destPath))
Directory.CreateDirectory(destPath);
//If a file with this name exists, delete it
else if (File.Exists(destFile))
File.Delete(destFile);
// Create the destination directory if it doesn't exist
if (!Directory.Exists(destPath))
Directory.CreateDirectory(destPath);
//If a file with this name exists, delete it
else if (File.Exists(destFile))
File.Delete(destFile);
// Move the file
File.Move(sourceFile, destFile);
// Move the file
File.Move(sourceFile, destFile);
//PPH log file install
insPack.Data.Files.Add(xmlHelper.GetNodeValue(n.SelectSingleNode("orgPath")) + "/" + xmlHelper.GetNodeValue(n.SelectSingleNode("orgName")));
} catch (Exception ex) {
Log.Add(LogTypes.Error, -1, "Package install error: " + ex.ToString());
//PPH log file install
insPack.Data.Files.Add(xmlHelper.GetNodeValue(n.SelectSingleNode("orgPath")) + "/" + xmlHelper.GetNodeValue(n.SelectSingleNode("orgName")));
}
catch (Exception ex)
{
Log.Add(LogTypes.Error, -1, "Package install error: " + ex.ToString());
}
}
}
insPack.Save();
insPack.Save();
}
}
public void InstallBusinessLogic(int packageId, string tempDir) {
//retrieve the manifest to continue installation
packager.InstalledPackage insPack = packager.InstalledPackage.GetById(packageId);
bool saveNeeded = false;
public void InstallBusinessLogic(int packageId, string tempDir)
{
//Install DataTypes
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("//DataType")) {
cms.businesslogic.datatype.DataTypeDefinition newDtd = cms.businesslogic.datatype.DataTypeDefinition.Import(n);
using (DisposableTimer.DebugDuration<Installer>(
() => "Installing business logic for package id " + packageId + " into temp folder " + tempDir,
() => "Package business logic installation complete for package id " + packageId))
{
//retrieve the manifest to continue installation
packager.InstalledPackage insPack = packager.InstalledPackage.GetById(packageId);
bool saveNeeded = false;
if (newDtd != null) {
insPack.Data.DataTypes.Add(newDtd.Id.ToString());
saveNeeded = true;
}
}
//Install DataTypes
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("//DataType"))
{
cms.businesslogic.datatype.DataTypeDefinition newDtd = cms.businesslogic.datatype.DataTypeDefinition.Import(n);
if (saveNeeded) {insPack.Save(); saveNeeded = false;}
//Install languages
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("//Language")) {
language.Language newLang = language.Language.Import(n);
if (newLang != null) {
insPack.Data.Languages.Add(newLang.id.ToString());
saveNeeded = true;
}
}
if (saveNeeded) { insPack.Save(); saveNeeded = false; }
//Install dictionary items
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("./DictionaryItems/DictionaryItem")) {
Dictionary.DictionaryItem newDi = Dictionary.DictionaryItem.Import(n);
if (newDi != null) {
insPack.Data.DictionaryItems.Add(newDi.id.ToString());
saveNeeded = true;
}
}
if (saveNeeded) { insPack.Save(); saveNeeded = false; }
// Install macros
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("//macro")) {
cms.businesslogic.macro.Macro m = cms.businesslogic.macro.Macro.Import(n);
if (m != null) {
insPack.Data.Macros.Add(m.Id.ToString());
saveNeeded = true;
}
}
if (saveNeeded) { insPack.Save(); saveNeeded = false; }
// Get current user, with a fallback
User u = new User(0);
if (!string.IsNullOrEmpty(BasePages.UmbracoEnsuredPage.umbracoUserContextID)) {
if (BasePages.UmbracoEnsuredPage.ValidateUserContextID(BasePages.UmbracoEnsuredPage.umbracoUserContextID)) {
u = User.GetCurrent();
}
}
// Add Templates
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("Templates/Template")) {
var t = Template.Import(n, u);
insPack.Data.Templates.Add(t.Id.ToString());
saveNeeded = true;
}
if (saveNeeded) { insPack.Save(); saveNeeded = false; }
//NOTE: SD: I'm pretty sure the only thing the below script does is ensure that the Master template Id is set
// in the database, but this is also duplicating the saving of the design content since the above Template.Import
// already does this. I've left this for now because I'm not sure the reprocussions of removing it but seems there
// is a lot of excess database calls happening here.
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("Templates/Template")) {
string master = xmlHelper.GetNodeValue(n.SelectSingleNode("Master"));
template.Template t = template.Template.GetByAlias(xmlHelper.GetNodeValue(n.SelectSingleNode("Alias")));
if (master.Trim() != "") {
template.Template masterTemplate = template.Template.GetByAlias(master);
if (masterTemplate != null) {
t.MasterTemplate = template.Template.GetByAlias(master).Id;
//SD: This appears to always just save an empty template because the design isn't set yet
// this fixes an issue now that we have MVC because if there is an empty template and MVC is
// the default, it will create a View not a master page and then the system will try to route via
// MVC which means that the package will not work anymore.
// The code below that imports the templates should suffice because it's actually importing
// template data not just blank data.
//if (UmbracoSettings.UseAspNetMasterPages)
// t.SaveMasterPageFile(t.Design);
if (newDtd != null)
{
insPack.Data.DataTypes.Add(newDtd.Id.ToString());
saveNeeded = true;
}
}
// Master templates can only be generated when their master is known
if (UmbracoSettings.UseAspNetMasterPages) {
t.ImportDesign(xmlHelper.GetNodeValue(n.SelectSingleNode("Design")));
t.SaveMasterPageFile(t.Design);
}
}
// Add documenttypes
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("DocumentTypes/DocumentType")) {
ImportDocumentType(n, u, false);
saveNeeded = true;
}
if (saveNeeded) { insPack.Save(); saveNeeded = false; }
if (saveNeeded) { insPack.Save(); saveNeeded = false; }
//Install languages
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("//Language"))
{
language.Language newLang = language.Language.Import(n);
// Add documenttype structure
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("DocumentTypes/DocumentType")) {
DocumentType dt = DocumentType.GetByAlias(xmlHelper.GetNodeValue(n.SelectSingleNode("Info/Alias")));
if (dt != null) {
ArrayList allowed = new ArrayList();
foreach (XmlNode structure in n.SelectNodes("Structure/DocumentType")) {
DocumentType dtt = DocumentType.GetByAlias(xmlHelper.GetNodeValue(structure));
if(dtt != null)
allowed.Add(dtt.Id);
if (newLang != null)
{
insPack.Data.Languages.Add(newLang.id.ToString());
saveNeeded = true;
}
}
int[] adt = new int[allowed.Count];
for (int i = 0; i < allowed.Count; i++)
adt[i] = (int)allowed[i];
dt.AllowedChildContentTypeIDs = adt;
if (saveNeeded) { insPack.Save(); saveNeeded = false; }
//Install dictionary items
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("./DictionaryItems/DictionaryItem"))
{
Dictionary.DictionaryItem newDi = Dictionary.DictionaryItem.Import(n);
if (newDi != null)
{
insPack.Data.DictionaryItems.Add(newDi.id.ToString());
saveNeeded = true;
}
}
if (saveNeeded) { insPack.Save(); saveNeeded = false; }
// Install macros
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("//macro"))
{
cms.businesslogic.macro.Macro m = cms.businesslogic.macro.Macro.Import(n);
if (m != null)
{
insPack.Data.Macros.Add(m.Id.ToString());
saveNeeded = true;
}
}
if (saveNeeded) { insPack.Save(); saveNeeded = false; }
// Get current user, with a fallback
User u = new User(0);
if (!string.IsNullOrEmpty(BasePages.UmbracoEnsuredPage.umbracoUserContextID))
{
if (BasePages.UmbracoEnsuredPage.ValidateUserContextID(BasePages.UmbracoEnsuredPage.umbracoUserContextID))
{
u = User.GetCurrent();
}
}
// Add Templates
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("Templates/Template"))
{
var t = Template.Import(n, u);
insPack.Data.Templates.Add(t.Id.ToString());
//PPH we log the document type install here.
insPack.Data.Documenttypes.Add(dt.Id.ToString());
saveNeeded = true;
}
}
if (saveNeeded) { insPack.Save(); saveNeeded = false; }
if (saveNeeded) { insPack.Save(); saveNeeded = false; }
// Stylesheets
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("Stylesheets/Stylesheet")) {
StyleSheet s = StyleSheet.Import(n, u);
insPack.Data.Stylesheets.Add(s.Id.ToString());
saveNeeded = true;
}
if (saveNeeded) { insPack.Save(); saveNeeded = false; }
// Documents
foreach (XmlElement n in _packageConfig.DocumentElement.SelectNodes("Documents/DocumentSet [@importMode = 'root']/*")) {
insPack.Data.ContentNodeId = cms.businesslogic.web.Document.Import(-1, u, n).ToString();
}
//Package Actions
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("Actions/Action")) {
if (n.Attributes["undo"] == null || n.Attributes["undo"].Value == "true") {
insPack.Data.Actions += n.OuterXml;
Log.Add(LogTypes.Debug, -1, HttpUtility.HtmlEncode(n.OuterXml));
}
if (n.Attributes["runat"] != null && n.Attributes["runat"].Value == "install") {
try {
packager.PackageAction.RunPackageAction(insPack.Data.Name, n.Attributes["alias"].Value, n);
} catch {
//NOTE: SD: I'm pretty sure the only thing the below script does is ensure that the Master template Id is set
// in the database, but this is also duplicating the saving of the design content since the above Template.Import
// already does this. I've left this for now because I'm not sure the reprocussions of removing it but seems there
// is a lot of excess database calls happening here.
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("Templates/Template"))
{
string master = xmlHelper.GetNodeValue(n.SelectSingleNode("Master"));
template.Template t = template.Template.GetByAlias(xmlHelper.GetNodeValue(n.SelectSingleNode("Alias")));
if (master.Trim() != "")
{
template.Template masterTemplate = template.Template.GetByAlias(master);
if (masterTemplate != null)
{
t.MasterTemplate = template.Template.GetByAlias(master).Id;
//SD: This appears to always just save an empty template because the design isn't set yet
// this fixes an issue now that we have MVC because if there is an empty template and MVC is
// the default, it will create a View not a master page and then the system will try to route via
// MVC which means that the package will not work anymore.
// The code below that imports the templates should suffice because it's actually importing
// template data not just blank data.
//if (UmbracoSettings.UseAspNetMasterPages)
// t.SaveMasterPageFile(t.Design);
}
}
// Master templates can only be generated when their master is known
if (UmbracoSettings.UseAspNetMasterPages)
{
t.ImportDesign(xmlHelper.GetNodeValue(n.SelectSingleNode("Design")));
t.SaveMasterPageFile(t.Design);
}
}
// Add documenttypes
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("DocumentTypes/DocumentType"))
{
ImportDocumentType(n, u, false);
saveNeeded = true;
}
if (saveNeeded) { insPack.Save(); saveNeeded = false; }
// Add documenttype structure
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("DocumentTypes/DocumentType"))
{
DocumentType dt = DocumentType.GetByAlias(xmlHelper.GetNodeValue(n.SelectSingleNode("Info/Alias")));
if (dt != null)
{
ArrayList allowed = new ArrayList();
foreach (XmlNode structure in n.SelectNodes("Structure/DocumentType"))
{
DocumentType dtt = DocumentType.GetByAlias(xmlHelper.GetNodeValue(structure));
if (dtt != null)
allowed.Add(dtt.Id);
}
int[] adt = new int[allowed.Count];
for (int i = 0; i < allowed.Count; i++)
adt[i] = (int)allowed[i];
dt.AllowedChildContentTypeIDs = adt;
//PPH we log the document type install here.
insPack.Data.Documenttypes.Add(dt.Id.ToString());
saveNeeded = true;
}
}
if (saveNeeded) { insPack.Save(); saveNeeded = false; }
// Stylesheets
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("Stylesheets/Stylesheet"))
{
StyleSheet s = StyleSheet.Import(n, u);
insPack.Data.Stylesheets.Add(s.Id.ToString());
saveNeeded = true;
}
if (saveNeeded) { insPack.Save(); saveNeeded = false; }
// Documents
foreach (XmlElement n in _packageConfig.DocumentElement.SelectNodes("Documents/DocumentSet [@importMode = 'root']/*"))
{
insPack.Data.ContentNodeId = cms.businesslogic.web.Document.Import(-1, u, n).ToString();
}
//Package Actions
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("Actions/Action"))
{
if (n.Attributes["undo"] == null || n.Attributes["undo"].Value == "true")
{
insPack.Data.Actions += n.OuterXml;
Log.Add(LogTypes.Debug, -1, HttpUtility.HtmlEncode(n.OuterXml));
}
if (n.Attributes["runat"] != null && n.Attributes["runat"].Value == "install")
{
try
{
packager.PackageAction.RunPackageAction(insPack.Data.Name, n.Attributes["alias"].Value, n);
}
catch
{
}
}
}
// Trigger update of Apps / Trees config.
// (These are ApplicationStartupHandlers so just instantiating them will trigger them)
new ApplicationRegistrar();
new ApplicationTreeRegistrar();
insPack.Save();
}
// Trigger update of Apps / Trees config.
// (These are ApplicationStartupHandlers so just instantiating them will trigger them)
new ApplicationRegistrar();
new ApplicationTreeRegistrar();
insPack.Save();
}
public void InstallCleanUp(int packageId, string tempDir) {
public void InstallCleanUp(int packageId, string tempDir)
{
//this will contain some logic to clean up all those old folders
@@ -448,12 +498,12 @@ namespace umbraco.cms.businesslogic.packager
{
//PPH added logging of installs, this adds all install info in the installedPackages config file.
string _packName = xmlHelper.GetNodeValue(_packageConfig.DocumentElement.SelectSingleNode("/umbPackage/info/package/name"));
string _packAuthor= xmlHelper.GetNodeValue(_packageConfig.DocumentElement.SelectSingleNode("/umbPackage/info/author/name"));
string _packAuthor = xmlHelper.GetNodeValue(_packageConfig.DocumentElement.SelectSingleNode("/umbPackage/info/author/name"));
string _packAuthorUrl = xmlHelper.GetNodeValue(_packageConfig.DocumentElement.SelectSingleNode("/umbPackage/info/author/website"));
string _packVersion = xmlHelper.GetNodeValue(_packageConfig.DocumentElement.SelectSingleNode("/umbPackage/info/package/version"));
string _packReadme = xmlHelper.GetNodeValue(_packageConfig.DocumentElement.SelectSingleNode("/umbPackage/info/readme"));
string _packLicense = xmlHelper.GetNodeValue(_packageConfig.DocumentElement.SelectSingleNode("/umbPackage/info/package/license "));
//Create a new package instance to record all the installed package adds - this is the same format as the created packages has.
//save the package meta data
@@ -465,10 +515,11 @@ namespace umbraco.cms.businesslogic.packager
insPack.Data.License = _packLicense;
insPack.Data.PackageGuid = guid; //the package unique key.
insPack.Data.RepositoryGuid = repoGuid; //the repository unique key, if the package is a file install, the repository will not get logged.
//Install languages
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("//Language")) {
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("//Language"))
{
language.Language newLang = language.Language.Import(n);
if (newLang != null)
@@ -476,11 +527,12 @@ namespace umbraco.cms.businesslogic.packager
}
//Install dictionary items
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("./DictionaryItems/DictionaryItem")) {
Dictionary.DictionaryItem newDi = Dictionary.DictionaryItem.Import(n);
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("./DictionaryItems/DictionaryItem"))
{
Dictionary.DictionaryItem newDi = Dictionary.DictionaryItem.Import(n);
if (newDi != null)
insPack.Data.DictionaryItems.Add(newDi.id.ToString());
if (newDi != null)
insPack.Data.DictionaryItems.Add(newDi.id.ToString());
}
// Install macros
@@ -488,7 +540,7 @@ namespace umbraco.cms.businesslogic.packager
{
cms.businesslogic.macro.Macro m = cms.businesslogic.macro.Macro.Import(n);
if(m != null)
if (m != null)
insPack.Data.Macros.Add(m.Id.ToString());
}
@@ -523,8 +575,8 @@ namespace umbraco.cms.businesslogic.packager
template.Template t = template.Template.MakeNew(xmlHelper.GetNodeValue(n.SelectSingleNode("Name")), u);
t.Alias = xmlHelper.GetNodeValue(n.SelectSingleNode("Alias"));
t.ImportDesign( xmlHelper.GetNodeValue(n.SelectSingleNode("Design")) );
t.ImportDesign(xmlHelper.GetNodeValue(n.SelectSingleNode("Design")));
insPack.Data.Templates.Add(t.Id.ToString());
}
@@ -536,14 +588,16 @@ namespace umbraco.cms.businesslogic.packager
if (master.Trim() != "")
{
template.Template masterTemplate = template.Template.GetByAlias(master);
if (masterTemplate != null) {
if (masterTemplate != null)
{
t.MasterTemplate = template.Template.GetByAlias(master).Id;
if (UmbracoSettings.UseAspNetMasterPages)
t.SaveMasterPageFile(t.Design);
}
}
// Master templates can only be generated when their master is known
if (UmbracoSettings.UseAspNetMasterPages) {
if (UmbracoSettings.UseAspNetMasterPages)
{
t.ImportDesign(xmlHelper.GetNodeValue(n.SelectSingleNode("Design")));
t.SaveMasterPageFile(t.Design);
}
@@ -602,27 +656,32 @@ namespace umbraco.cms.businesslogic.packager
}
// Documents
foreach (XmlElement n in _packageConfig.DocumentElement.SelectNodes("Documents/DocumentSet [@importMode = 'root']/*")) {
foreach (XmlElement n in _packageConfig.DocumentElement.SelectNodes("Documents/DocumentSet [@importMode = 'root']/*"))
{
cms.businesslogic.web.Document.Import(-1, u, n);
//PPH todo log document install...
}
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("Actions/Action [@runat != 'uninstall']")) {
try {
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("Actions/Action [@runat != 'uninstall']"))
{
try
{
packager.PackageAction.RunPackageAction(_packName, n.Attributes["alias"].Value, n);
} catch { }
}
catch { }
}
//saving the uninstall actions untill the package is uninstalled.
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("Actions/Action [@undo != false()]")) {
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("Actions/Action [@undo != false()]"))
{
insPack.Data.Actions += n.OuterXml;
}
insPack.Save();
}
public static void ImportDocumentType(XmlNode n, BusinessLogic.User u, bool ImportStructure)
@@ -633,7 +692,7 @@ namespace umbraco.cms.businesslogic.packager
dt = DocumentType.MakeNew(u, xmlHelper.GetNodeValue(n.SelectSingleNode("Info/Name")));
dt.Alias = xmlHelper.GetNodeValue(n.SelectSingleNode("Info/Alias"));
//Master content type
DocumentType mdt = DocumentType.GetByAlias(xmlHelper.GetNodeValue(n.SelectSingleNode("Info/Master")));
if (mdt != null)
@@ -644,7 +703,7 @@ namespace umbraco.cms.businesslogic.packager
dt.Text = xmlHelper.GetNodeValue(n.SelectSingleNode("Info/Name"));
}
// Info
dt.IconUrl = xmlHelper.GetNodeValue(n.SelectSingleNode("Info/Icon"));
dt.Thumbnail = xmlHelper.GetNodeValue(n.SelectSingleNode("Info/Thumbnail"));
@@ -688,7 +747,7 @@ namespace umbraco.cms.businesslogic.packager
for (int t = 0; t < tabs.Length; t++)
tabNames += tabs[t].Caption + ";";
Hashtable ht = new Hashtable();
foreach (XmlNode t in n.SelectNodes("Tabs/Tab"))
@@ -712,19 +771,24 @@ namespace umbraco.cms.businesslogic.packager
// Generic Properties
datatype.controls.Factory f = new datatype.controls.Factory();
foreach (XmlNode gp in n.SelectNodes("GenericProperties/GenericProperty"))
{
{
int dfId = 0;
Guid dtId = new Guid(xmlHelper.GetNodeValue(gp.SelectSingleNode("Type")));
if (gp.SelectSingleNode("Definition") != null && !string.IsNullOrEmpty(xmlHelper.GetNodeValue(gp.SelectSingleNode("Definition")))) {
if (gp.SelectSingleNode("Definition") != null && !string.IsNullOrEmpty(xmlHelper.GetNodeValue(gp.SelectSingleNode("Definition"))))
{
Guid dtdId = new Guid(xmlHelper.GetNodeValue(gp.SelectSingleNode("Definition")));
if (CMSNode.IsNode(dtdId))
dfId = new CMSNode(dtdId).Id;
}
if (dfId == 0) {
try {
}
if (dfId == 0)
{
try
{
dfId = findDataTypeDefinitionFromType(ref dtId);
} catch {
}
catch
{
throw new Exception(String.Format("Could not find datatype with id {0}.", dtId));
}
}
@@ -820,22 +884,22 @@ namespace umbraco.cms.businesslogic.packager
//to support virtual dirs we try to lookup the file...
path = IOHelper.FindFile(path);
Debug.Assert(path != null && path.Length >= 1);
Debug.Assert(fileName != null && fileName.Length >= 1);
path = path.Replace('/', '\\');
fileName = fileName.Replace('/','\\');
fileName = fileName.Replace('/', '\\');
// Does filename start with a slash? Does path end with one?
bool fileNameStartsWithSlash = (fileName[0] == Path.DirectorySeparatorChar);
bool pathEndsWithSlash = (path[path.Length-1] == Path.DirectorySeparatorChar);
bool pathEndsWithSlash = (path[path.Length - 1] == Path.DirectorySeparatorChar);
// Path ends with a slash
if (pathEndsWithSlash)
{
if(!fileNameStartsWithSlash)
if (!fileNameStartsWithSlash)
// No double slash, just concatenate
return path + fileName;
else
@@ -884,27 +948,29 @@ namespace umbraco.cms.businesslogic.packager
_reqPatch = int.Parse(_packageConfig.DocumentElement.SelectSingleNode("/umbPackage/info/package/requirements/patch").FirstChild.Value);
_authorName = _packageConfig.DocumentElement.SelectSingleNode("/umbPackage/info/author/name").FirstChild.Value;
_authorUrl = _packageConfig.DocumentElement.SelectSingleNode("/umbPackage/info/author/website").FirstChild.Value;
string basePath = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath;
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("//file")) {
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("//file"))
{
bool badFile = false;
string destPath = getFileName(basePath, xmlHelper.GetNodeValue(n.SelectSingleNode("orgPath")));
string destFile = getFileName(destPath, xmlHelper.GetNodeValue(n.SelectSingleNode("orgName")));
if (destPath.ToLower().Contains( IOHelper.DirSepChar + "app_code"))
if (destPath.ToLower().Contains(IOHelper.DirSepChar + "app_code"))
badFile = true;
if (destPath.ToLower().Contains(IOHelper.DirSepChar + "bin"))
if (destPath.ToLower().Contains(IOHelper.DirSepChar + "bin"))
badFile = true;
if (destFile.ToLower().EndsWith(".dll"))
badFile = true;
if (destFile.ToLower().EndsWith(".dll"))
badFile = true;
if (badFile) {
_containUnsecureFiles = true;
_unsecureFiles.Add(xmlHelper.GetNodeValue(n.SelectSingleNode("orgName")));
}
if (badFile)
{
_containUnsecureFiles = true;
_unsecureFiles.Add(xmlHelper.GetNodeValue(n.SelectSingleNode("orgName")));
}
}
//this will check for existing macros with the same alias
@@ -1028,7 +1094,8 @@ namespace umbraco.cms.businesslogic.packager
}
public static void updatePackageInfo(Guid Package, int VersionMajor, int VersionMinor, int VersionPatch, User User) {
public static void updatePackageInfo(Guid Package, int VersionMajor, int VersionMinor, int VersionPatch, User User)
{
}
}
@@ -1109,7 +1176,7 @@ namespace umbraco.cms.businesslogic.packager
if (Id == 0)
{
// The method is synchronized
SqlHelper.ExecuteNonQuery("INSERT INTO umbracoInstalledPackages (uninstalled, upgradeId, installDate, userId, versionMajor, versionMinor, versionPatch) VALUES (@uninstalled, @upgradeId, @installDate, @userId, @versionMajor, @versionMinor, @versionPatch)",values);
SqlHelper.ExecuteNonQuery("INSERT INTO umbracoInstalledPackages (uninstalled, upgradeId, installDate, userId, versionMajor, versionMinor, versionPatch) VALUES (@uninstalled, @upgradeId, @installDate, @userId, @versionMajor, @versionMinor, @versionPatch)", values);
Id = SqlHelper.ExecuteScalar<int>("SELECT MAX(id) FROM umbracoInstalledPackages");
}
@@ -1133,7 +1200,7 @@ namespace umbraco.cms.businesslogic.packager
get { return _uninstalled; }
set { _uninstalled = value; }
}
private User _user;
@@ -1142,7 +1209,7 @@ namespace umbraco.cms.businesslogic.packager
get { return _user; }
set { _user = value; }
}
private DateTime _installDate;
@@ -1151,7 +1218,7 @@ namespace umbraco.cms.businesslogic.packager
get { return _installDate; }
set { _installDate = value; }
}
private int _id;
@@ -1160,7 +1227,7 @@ namespace umbraco.cms.businesslogic.packager
get { return _id; }
set { _id = value; }
}
private int _upgradeId;
@@ -1169,7 +1236,7 @@ namespace umbraco.cms.businesslogic.packager
get { return _upgradeId; }
set { _upgradeId = value; }
}
private Guid _packageId;
@@ -1178,7 +1245,7 @@ namespace umbraco.cms.businesslogic.packager
get { return _packageId; }
set { _packageId = value; }
}
private int _versionPatch;
@@ -1187,7 +1254,7 @@ namespace umbraco.cms.businesslogic.packager
get { return _versionPatch; }
set { _versionPatch = value; }
}
private int _versionMinor;
@@ -1196,7 +1263,7 @@ namespace umbraco.cms.businesslogic.packager
get { return _versionMinor; }
set { _versionMinor = value; }
}
private int _versionMajor;
@@ -1207,6 +1274,6 @@ namespace umbraco.cms.businesslogic.packager
}
}
}
@@ -10,14 +10,11 @@ namespace umbraco.cms.businesslogic.macro
string Name { get; }
IEnumerable<string> SupportedExtensions { get; }
IEnumerable<string> SupportedUIExtensions { get; }
[Obsolete("This property is not used in the codebase")]
Dictionary<string, IMacroGuiRendering> SupportedProperties { get; }
bool Validate(string code, string tempFileName, INode currentPage, out string errorMessage);
string Execute(MacroModel macro, INode currentPage);
}
public interface IMacroEngineResultStatus
{
bool Success { get; }
Exception ResultException { get; }
}
}
@@ -0,0 +1,10 @@
using System;
namespace umbraco.cms.businesslogic.macro
{
public interface IMacroEngineResultStatus
{
bool Success { get; }
Exception ResultException { get; }
}
}
+30 -21
View File
@@ -2,8 +2,10 @@ using System;
using System.Data;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using System.Runtime.CompilerServices;
using Umbraco.Core.IO;
using umbraco.cms.businesslogic.cache;
using umbraco.DataLayer;
using umbraco.BusinessLogic;
@@ -131,10 +133,11 @@ namespace umbraco.cms.businesslogic.macro
}
/// <summary>
/// The relative path to the usercontrol
///
/// Specified like: /usercontrols/myusercontrol.ascx (with the .ascx postfix)
/// The relative path to the usercontrol or the assembly type of the macro when using .Net custom controls
/// </summary>
/// <remarks>
/// When using a user control the value is specified like: /usercontrols/myusercontrol.ascx (with the .ascx postfix)
/// </remarks>
public string Type
{
get {return _type;}
@@ -161,10 +164,13 @@ namespace umbraco.cms.businesslogic.macro
}
/// <summary>
/// The python file used to be executed
///
/// Umbraco assumes that the python file is present in the "/python" folder
/// This field is used to store the file value for any scripting macro such as python, ruby, razor macros or Partial View Macros
/// </summary>
/// <remarks>
/// Depending on how the file is stored depends on what type of macro it is. For example if the file path is a full virtual path
/// starting with the ~/Views/MacroPartials then it is deemed to be a Partial View Macro, otherwise the file extension of the file
/// saved will determine which macro engine will be used to execute the file.
/// </remarks>
public string ScriptingFile {
get { return _scriptingFile; }
set {
@@ -526,22 +532,25 @@ namespace umbraco.cms.businesslogic.macro
{
if (!string.IsNullOrEmpty(xslt))
return MacroTypes.XSLT;
else
{
if (!string.IsNullOrEmpty(scriptFile))
return MacroTypes.Script;
else
{
if (!string.IsNullOrEmpty(scriptType) && scriptType.ToLower().IndexOf(".ascx") > -1)
{
return MacroTypes.UserControl;
}
else if (!string.IsNullOrEmpty(scriptType) && !string.IsNullOrEmpty(scriptAssembly))
return MacroTypes.CustomControl;
}
}
if (!string.IsNullOrEmpty(scriptFile))
{
//we need to check if the file path saved is a virtual path starting with ~/Views/MacroPartials, if so then this is
//a partial view macro, not a script macro
//we also check if the file exists in ~/App_Plugins/[Packagename]/Views/MacroPartials, if so then it is also a partial view.
return (scriptFile.StartsWith(SystemDirectories.MvcViews + "/MacroPartials/")
|| (Regex.IsMatch(scriptFile, "~/App_Plugins/.+?/Views/MacroPartials", RegexOptions.Compiled)))
? MacroTypes.PartialView
: MacroTypes.Script;
}
return MacroTypes.Unknown;
if (!string.IsNullOrEmpty(scriptType) && scriptType.ToLower().IndexOf(".ascx") > -1)
return MacroTypes.UserControl;
if (!string.IsNullOrEmpty(scriptType) && !string.IsNullOrEmpty(scriptAssembly))
return MacroTypes.CustomControl;
return MacroTypes.Unknown;
}
public static string GenerateCacheKeyFromCode(string input)
@@ -49,25 +49,56 @@ namespace umbraco.cms.businesslogic.macro
EnsureInitialize();
}
public static IEnumerable<MacroEngineLanguage> GetSupportedLanguages() {
/// <summary>
/// Returns a collectino of MacroEngineLanguage objects, each of which describes a file extension and an associated macro engine
/// </summary>
/// <returns></returns>
/// <remarks>
/// Until the macro engines are rewritten, this method explicitly ignores the PartialViewMacroEngine because this method
/// is essentially just used for any macro engine that stores it's files in the ~/macroScripts folder where file extensions
/// cannot overlap.
/// </remarks>
[Obsolete("This method is not used and will be removed from the codebase in the future")]
public static IEnumerable<MacroEngineLanguage> GetSupportedLanguages()
{
var languages = new List<MacroEngineLanguage>();
foreach(var engine in GetAll()) {
foreach(string lang in engine.SupportedExtensions)
foreach (var engine in GetAll())
{
foreach (string lang in engine.SupportedExtensions)
{
if (languages.Find(t => t.Extension == lang) == null)
{
languages.Add(new MacroEngineLanguage(lang, engine.Name));
}
}
}
return languages;
}
public static IEnumerable<MacroEngineLanguage> GetSupportedUILanguages() {
/// <summary>
/// Returns a collectino of MacroEngineLanguage objects, each of which describes a file extension and an associated macro engine that
/// supports file extension lookups.
/// </summary>
/// <returns></returns>
/// <remarks>
/// The PartialViewMacroEngine will never be returned in these results because it does not support searching by file extensions. See
/// the notes in the PartialViewMacroEngine regarding this.
/// </remarks>
public static IEnumerable<MacroEngineLanguage> GetSupportedUILanguages()
{
var languages = new List<MacroEngineLanguage>();
foreach (var engine in GetAll()) {
foreach (var engine in GetAll())
{
foreach (string lang in engine.SupportedUIExtensions)
if (languages.Find(t => t.Extension == lang) == null)
{
if (languages.All(t => t.Extension != lang))
{
languages.Add(new MacroEngineLanguage(lang, engine.Name));
}
}
}
return languages.OrderBy(s => s.Extension);
}
}
public static List<IMacroEngine> GetAll()
{
@@ -80,43 +80,4 @@ namespace umbraco.cms.businesslogic.macro
MacroType = Macro.FindMacroType(Xslt, ScriptName, TypeName, TypeAssembly);
}
}
[Serializable]
public class MacroPropertyModel
{
public string Key { get; set; }
public string Value { get; set; }
public string Type { get; set; }
public string CLRType { get; set; }
public MacroPropertyModel()
{
}
public MacroPropertyModel(string key, string value)
{
Key = key;
Value = value;
}
public MacroPropertyModel(string key, string value, string type, string clrType)
{
Key = key;
Value = value;
Type = type;
CLRType = clrType;
}
}
public enum MacroTypes
{
XSLT = 1,
CustomControl = 2,
UserControl = 3,
Unknown = 4,
Python = 5,
Script = 6
}
}
@@ -0,0 +1,31 @@
using System;
namespace umbraco.cms.businesslogic.macro
{
[Serializable]
public class MacroPropertyModel
{
public string Key { get; set; }
public string Value { get; set; }
public string Type { get; set; }
public string CLRType { get; set; }
public MacroPropertyModel()
{
}
public MacroPropertyModel(string key, string value)
{
Key = key;
Value = value;
}
public MacroPropertyModel(string key, string value, string type, string clrType)
{
Key = key;
Value = value;
Type = type;
CLRType = clrType;
}
}
}
@@ -0,0 +1,13 @@
namespace umbraco.cms.businesslogic.macro
{
public enum MacroTypes
{
XSLT = 1,
CustomControl = 2,
UserControl = 3,
Unknown = 4,
Python = 5,
Script = 6,
PartialView = 7
}
}
@@ -5,12 +5,10 @@ using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Web;
using Umbraco.Core.Logging;
using umbraco.BasePages;
using umbraco.BusinessLogic;
using umbraco.cms.businesslogic.datatype;
using Encoder = System.Text.Encoder;
using Umbraco.Core.IO;
namespace umbraco.cms.businesslogic.media
{
@@ -26,10 +24,10 @@ namespace umbraco.cms.businesslogic.media
get { return new List<string> { "jpeg", "jpg", "gif", "bmp", "png", "tiff", "tif" }; }
}
public override void DoHandleMedia(Media media, PostedMediaFile postedFile, BusinessLogic.User user)
public override void DoHandleMedia(Media media, PostedMediaFile postedFile, User user)
{
// Get Image object, width and height
var image = System.Drawing.Image.FromStream(postedFile.InputStream);
var image = Image.FromStream(postedFile.InputStream);
var fileWidth = image.Width;
var fileHeight = image.Height;
@@ -42,9 +40,15 @@ namespace umbraco.cms.businesslogic.media
// Set media properties
media.getProperty("umbracoFile").Value = FileSystem.GetUrl(destFilePath);
media.getProperty("umbracoWidth").Value = fileWidth;
media.getProperty("umbracoHeight").Value = fileHeight;
media.getProperty("umbracoBytes").Value = postedFile.ContentLength;
if (media.getProperty("umbracoWidth") != null)
media.getProperty("umbracoWidth").Value = fileWidth;
if (media.getProperty("umbracoHeight") != null)
media.getProperty("umbracoHeight").Value = fileHeight;
if (media.getProperty("umbracoBytes") != null)
media.getProperty("umbracoBytes").Value = postedFile.ContentLength;
if (media.getProperty("umbracoExtension") != null)
media.getProperty("umbracoExtension").Value = ext;
@@ -78,7 +82,10 @@ namespace umbraco.cms.businesslogic.media
// Get DataTypeDefinition of upload field
dataTypeDef = DataTypeDefinition.GetByDataTypeId(uploadFieldDataTypeId);
}
catch { }
catch (Exception e)
{
LogHelper.Error<UmbracoImageMediaFactory>("Could get Upload Field datatype definition", e);
}
if (dataTypeDef != null)
{
@@ -94,8 +101,7 @@ namespace umbraco.cms.businesslogic.media
var thumbnailSizes = thumbnails.Split(";".ToCharArray());
foreach (var thumb in thumbnailSizes.Where(thumb => thumb != ""))
{
GenerateThumbnail(image, int.Parse(thumb), fileWidth, fileHeight, ext,
destFilePath + "_" + thumb + ".jpg");
GenerateThumbnail(image, int.Parse(thumb), fileWidth, fileHeight, ext, destFilePath + "_" + thumb + ".jpg");
}
}
}
@@ -115,6 +121,7 @@ namespace umbraco.cms.businesslogic.media
// fixes for empty width or height
if (widthTh == 0)
widthTh = 1;
if (heightTh == 0)
heightTh = 1;
@@ -131,15 +138,14 @@ namespace umbraco.cms.businesslogic.media
// Copy metadata
var codecs = ImageCodecInfo.GetImageEncoders();
ImageCodecInfo codec = null;
if (ext.ToLower() == "png" || ext.ToLower() == "gif")
codec = codecs.Single(t => t.MimeType.Equals("image/png"));
else
codec = codecs.Single(t => t.MimeType.Equals("image/jpeg"));
var codec = ext.ToLower() == "png" || ext.ToLower() == "gif"
? codecs.Single(t => t.MimeType.Equals("image/png"))
: codecs.Single(t => t.MimeType.Equals("image/jpeg"));
// Set compresion ratio to 90%
var ep = new EncoderParameters();
ep.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 90L);
ep.Param[0] = new EncoderParameter(Encoder.Quality, 90L);
// Save the new image
if (codec != null)
@@ -32,7 +32,7 @@ namespace umbraco.cms.businesslogic.template
if (!File.Exists(GetFilePath(t)) || overWrite)
{
masterpageContent = CreateDefaultMasterPageContent(t, t.Alias);
saveDesignToFile(t, null, masterpageContent);
SaveDesignToFile(t, null, masterpageContent);
}
else
{
@@ -59,9 +59,9 @@ namespace umbraco.cms.businesslogic.template
internal static string UpdateMasterPageFile(Template t, string currentAlias)
{
var template = updateMasterPageContent(t, currentAlias);
updateChildTemplates(t, currentAlias);
saveDesignToFile(t, currentAlias, template);
var template = UpdateMasterPageContent(t, currentAlias);
UpdateChildTemplates(t, currentAlias);
SaveDesignToFile(t, currentAlias, template);
return template;
}
@@ -137,7 +137,7 @@ namespace umbraco.cms.businesslogic.template
* */
}
internal static string updateMasterPageContent(Template template, string currentAlias)
internal static string UpdateMasterPageContent(Template template, string currentAlias)
{
var masterPageContent = template.Design;
@@ -174,7 +174,7 @@ namespace umbraco.cms.businesslogic.template
return masterPageContent;
}
private static void updateChildTemplates(Template t, string currentAlias)
private static void UpdateChildTemplates(Template t, string currentAlias)
{
//if we have a Old Alias if the alias and therefor the masterpage file name has changed...
//so before we save the new masterfile, we'll clear the old one, so we don't up with
@@ -192,7 +192,7 @@ namespace umbraco.cms.businesslogic.template
}
private static void saveDesignToFile(Template t, string currentAlias, string design)
private static void SaveDesignToFile(Template t, string currentAlias, string design)
{
//kill the old file..
if (!string.IsNullOrEmpty(currentAlias) && currentAlias != t.Alias)
@@ -1,6 +1,4 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO;
using System.Linq;
using System.Text;
using Umbraco.Core.IO;
@@ -27,7 +25,7 @@ namespace umbraco.cms.businesslogic.template
if (File.Exists(path))
{
System.IO.TextReader tr = new StreamReader(path);
TextReader tr = new StreamReader(path);
viewContent = tr.ReadToEnd();
tr.Close();
}
@@ -37,14 +35,14 @@ namespace umbraco.cms.businesslogic.template
internal static string CreateViewFile(Template t, bool overWrite = false)
{
string viewContent = "";
string viewContent;
string path = IOHelper.MapPath(ViewPath(t.Alias));
if (!File.Exists(path) || overWrite)
if (File.Exists(path) == false || overWrite)
viewContent = SaveTemplateToFile(t, t.Alias);
else
{
System.IO.TextReader tr = new StreamReader(path);
TextReader tr = new StreamReader(path);
viewContent = tr.ReadToEnd();
tr.Close();
}
@@ -55,7 +53,7 @@ namespace umbraco.cms.businesslogic.template
internal static string SaveTemplateToFile(Template template, string currentAlias)
{
var design = EnsureInheritedLayout(template);
System.IO.File.WriteAllText(IOHelper.MapPath(ViewPath(template.Alias)), design, Encoding.UTF8);
File.WriteAllText(IOHelper.MapPath(ViewPath(template.Alias)), design, Encoding.UTF8);
return template.Design;
}
@@ -64,7 +62,7 @@ namespace umbraco.cms.businesslogic.template
{
var path = IOHelper.MapPath(ViewPath(t.Alias));
if (!string.IsNullOrEmpty(currentAlias) && currentAlias != t.Alias)
if (string.IsNullOrEmpty(currentAlias) == false && currentAlias != t.Alias)
{
//NOTE: I don't think this is needed for MVC, this was ported over from the
// masterpages helper but I think only relates to when templates are stored in the db.
@@ -78,31 +76,29 @@ namespace umbraco.cms.businesslogic.template
//then kill the old file..
var oldFile = IOHelper.MapPath(ViewPath(currentAlias));
if (System.IO.File.Exists(oldFile))
System.IO.File.Delete(oldFile);
if (File.Exists(oldFile))
File.Delete(oldFile);
}
System.IO.File.WriteAllText(path, t.Design, Encoding.UTF8);
File.WriteAllText(path, t.Design, Encoding.UTF8);
return t.Design;
}
internal static void RemoveViewFile(string alias)
{
if (!string.IsNullOrWhiteSpace(alias))
if (string.IsNullOrWhiteSpace(alias) == false)
{
var file = IOHelper.MapPath(ViewPath(alias));
if (System.IO.File.Exists(file))
System.IO.File.Delete(file);
if (File.Exists(file))
File.Delete(file);
}
}
public static string ViewPath(string alias)
{
return Umbraco.Core.IO.SystemDirectories.MvcViews + "/" + alias.Replace(" ", "") + ".cshtml";
return SystemDirectories.MvcViews + "/" + alias.Replace(" ", "") + ".cshtml";
}
private static string EnsureInheritedLayout(Template template)
{
string design = template.Design;
@@ -115,8 +111,7 @@ namespace umbraco.cms.businesslogic.template
}";
if (template.MasterTemplate > 0)
design = design.Replace("null", "\"" + new Template(template.MasterTemplate).Alias.Replace(" ", "") + "\"");
design = design.Replace("null", string.Format("\"{0}.cshtml\"", new Template(template.MasterTemplate).Alias.Replace(" ", "")));
}
return design;
@@ -780,11 +780,15 @@ namespace umbraco.cms.businesslogic.web
{
get
{
// get all nodes in the path to the document, and get all matching published documents
// the difference should be zero if everything is published
// test nodeObjectType to make sure we only count _content_ nodes
int x = SqlHelper.ExecuteScalar<int>(@"select count(node.id) - count(doc.nodeid)
from umbracoNode as node
left join cmsDocument as doc on (node.id=doc.nodeId and doc.published=1)
where '" + Path + ",' like " + SqlHelper.Concat("node.path", "'%'"));
return (x == 1);
where '" + Path + ",' like " + SqlHelper.Concat("node.path", "',%'") + @"
and node.nodeObjectType='C66BA18E-EAF3-4CFF-8A22-41B16D66A972'");
return (x == 0);
}
}
+3
View File
@@ -224,8 +224,11 @@
</Compile>
<Compile Include="businesslogic\ISaveHandlerContents.cs" />
<Compile Include="businesslogic\macro\IMacroEngine.cs" />
<Compile Include="businesslogic\macro\IMacroEngineResultStatus.cs" />
<Compile Include="businesslogic\macro\MacroEngineFactory.cs" />
<Compile Include="businesslogic\macro\MacroModel.cs" />
<Compile Include="businesslogic\macro\MacroPropertyModel.cs" />
<Compile Include="businesslogic\macro\MacroTypes.cs" />
<Compile Include="businesslogic\media\IMediaFactory.cs" />
<Compile Include="businesslogic\media\MediaFactory.cs" />
<Compile Include="businesslogic\media\UmbracoFileMediaFactory.cs" />
@@ -176,7 +176,7 @@
}
.multiNodePicker .header
{
width: 622px;
width: 618px;
}
.uc-treenode-noclick > a > div
@@ -1,14 +1,10 @@
using System;
using System.Collections;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Text.RegularExpressions;
using System.Web;
using Umbraco.Core.IO;
using umbraco.BusinessLogic;
using Umbraco.Core.Logging;
using umbraco.cms.businesslogic.Files;
using umbraco.IO;
namespace umbraco.editorControls.tinymce
{
@@ -16,47 +12,36 @@ namespace umbraco.editorControls.tinymce
{
public static string cleanImages(string html)
{
string[] allowedAttributes = UmbracoSettings.ImageAllowedAttributes.ToLower().Split(',');
string pattern = @"<img [^>]*>";
MatchCollection tags =
Regex.Matches(html + " ", pattern, RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
var allowedAttributes = UmbracoSettings.ImageAllowedAttributes.ToLower().Split(',');
const string pattern = @"<img [^>]*>";
var tags = Regex.Matches(html + " ", pattern, RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
foreach (Match tag in tags)
{
if (tag.Value.ToLower().IndexOf("umbraco_macro") == -1)
if (tag.Value.ToLower().IndexOf("umbraco_macro", StringComparison.Ordinal) == -1)
{
string cleanTag = "<img";
int orgWidth = 0, orgHeight = 0;
var cleanTag = "<img";
// gather all attributes
// TODO: This should be replaced with a general helper method - but for now we'll wanna leave umbraco.dll alone for this patch
Hashtable ht = new Hashtable();
MatchCollection m =
Regex.Matches(tag.Value.Replace(">", " >"),
"(?<attributeName>\\S*)=\"(?<attributeValue>[^\"]*)\"|(?<attributeName>\\S*)=(?<attributeValue>[^\"|\\s]*)\\s",
RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
foreach (Match attributeSet in m)
var ht = new Hashtable();
var matches = Regex.Matches(tag.Value.Replace(">", " >"), "(?<attributeName>\\S*)=\"(?<attributeValue>[^\"]*)\"|(?<attributeName>\\S*)=(?<attributeValue>[^\"|\\s]*)\\s", RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
foreach (Match attributeSet in matches)
{
ht.Add(attributeSet.Groups["attributeName"].Value.ToString().ToLower(),
attributeSet.Groups["attributeValue"].Value.ToString());
if (attributeSet.Groups["attributeName"].Value.ToString().ToLower() == "width")
int.TryParse(attributeSet.Groups["attributeValue"].Value.ToString(), out orgWidth);
else if (attributeSet.Groups["attributeName"].Value.ToString().ToLower() == "height")
int.TryParse(attributeSet.Groups["attributeValue"].Value.ToString(), out orgHeight);
ht.Add(attributeSet.Groups["attributeName"].Value.ToLower(),
attributeSet.Groups["attributeValue"].Value);
}
// If rel attribute exists and if it's different from current sizing we should resize the image!
if (helper.FindAttribute(ht, "rel") != "")
{
int newWidth = 0, newHeight = 0;
// if size has changed resize image serverside
string[] newDims = helper.FindAttribute(ht, "rel").Split(",".ToCharArray());
if (newDims.Length > 0 &&
(newDims[0] != helper.FindAttribute(ht, "width") ||
newDims[1] != helper.FindAttribute(ht, "height")))
var newDims = helper.FindAttribute(ht, "rel").Split(",".ToCharArray());
if (newDims.Length > 0 && (newDims[0] != helper.FindAttribute(ht, "width") || newDims[1] != helper.FindAttribute(ht, "height")))
{
try
{
cleanTag += doResize(ht, out newWidth, out newHeight);
int newWidth;
int newHeight;
cleanTag += DoResize(ht, out newWidth, out newHeight);
}
catch (Exception err)
{
@@ -66,14 +51,12 @@ namespace umbraco.editorControls.tinymce
cleanTag += " width=\"" + helper.FindAttribute(ht, "width") + "\"";
cleanTag += " height=\"" + helper.FindAttribute(ht, "height") + "\"";
}
Log.Add(LogTypes.Error, User.GetUser(0), -1,
"Error resizing image in editor: " + err.ToString());
LogHelper.Error<tinyMCEImageHelper>("Error resizing image in editor", err);
}
}
else
{
cleanTag = StripSrc(cleanTag, ht);
if (helper.FindAttribute(ht, "width") != "")
{
cleanTag += " width=\"" + helper.FindAttribute(ht, "width") + "\"";
@@ -84,32 +67,26 @@ namespace umbraco.editorControls.tinymce
}
else
{
// Add src, width and height properties
cleanTag = StripSrc(cleanTag, ht);
if (helper.FindAttribute(ht, "width") != "")
{
cleanTag += " width=\"" + helper.FindAttribute(ht, "width") + "\"";
cleanTag += " height=\"" + helper.FindAttribute(ht, "height") + "\"";
}
}
// Build image tag
foreach (string attr in allowedAttributes)
foreach (var attr in allowedAttributes)
{
if (helper.FindAttribute(ht, attr) != "")
{
string attrValue = helper.FindAttribute(ht, attr);
var attrValue = helper.FindAttribute(ht, attr);
cleanTag += " " + attr + "=\"" + attrValue + "\"";
}
}
if (bool.Parse(GlobalSettings.EditXhtmlMode))
cleanTag += "/";
cleanTag += ">";
html = html.Replace(tag.Value, cleanTag);
}
@@ -118,113 +95,42 @@ namespace umbraco.editorControls.tinymce
return html;
}
private static string StripSrc(string cleanTag, Hashtable ht)
{
string src = helper.FindAttribute(ht, "src");
//get the media folder, minus the starting '~'
string mediaRoot = global::Umbraco.Core.IO.SystemDirectories.Media.Replace("~", string.Empty);
// update orgSrc to remove umbraco reference
int mediaRootIndex = src.IndexOf(mediaRoot);
if (mediaRootIndex > -1)
src = src.Substring(mediaRootIndex, src.Length - mediaRootIndex);
cleanTag += " src=\"" + src + "\"";
return cleanTag;
}
private static string doResize(Hashtable attributes, out int finalWidth, out int finalHeight)
private static string DoResize(IDictionary attributes, out int finalWidth, out int finalHeight)
{
var fs = FileSystemProviderManager.Current.GetFileSystemProvider<MediaFileSystem>();
var orgSrc = HttpContext.Current.Server.HtmlDecode(helper.FindAttribute(attributes, "src").Replace("%20", " "));
var orgDim = helper.FindAttribute(attributes, "rel").Split(",".ToCharArray());
var orgWidth = float.Parse(orgDim[0]);
var orgHeight = float.Parse(orgDim[1]);
var newWidth = int.Parse(helper.FindAttribute(attributes, "width"));
var newHeight = int.Parse(helper.FindAttribute(attributes, "height"));
string resizeDim = helper.FindAttribute(attributes, "width") + "," +
helper.FindAttribute(attributes, "height");
string[] resizeDimSplit = resizeDim.Split(',');
string orgSrc = HttpContext.Current.Server.HtmlDecode(helper.FindAttribute(attributes, "src").Replace("%20", " "));
string[] orgDim = helper.FindAttribute(attributes, "rel").Split(",".ToCharArray());
float orgWidth = float.Parse(orgDim[0]);
float orgHeight = float.Parse(orgDim[1]);
string newSrc = "";
int newWidth = int.Parse(resizeDimSplit[0]);
int newHeight = int.Parse(resizeDimSplit[1]);
var newSrc = "";
if (orgHeight > 0 && orgWidth > 0 && resizeDim != "" && orgSrc != "")
if (orgHeight > 0 && orgWidth > 0 && orgSrc != "")
{
// Check dimensions
if (Math.Abs(orgWidth / newWidth) > Math.Abs(orgHeight / newHeight))
{
newHeight = (int)Math.Round((float)newWidth * (orgHeight / orgWidth));
newHeight = (int)Math.Round(newWidth * (orgHeight / orgWidth));
}
else
{
newWidth = (int)Math.Round((float)newHeight * (orgWidth / orgHeight));
newWidth = (int)Math.Round(newHeight * (orgWidth / orgHeight));
}
// update orgSrc to remove umbraco reference
//string resolvedMedia = IOHelper.ResolveUrl(SystemDirectories.Media);
//if (IOHelper.ResolveUrl(orgSrc).IndexOf(resolvedMedia) > -1)
//{
// orgSrc = SystemDirectories.Media + orgSrc.Substring(orgSrc.IndexOf(resolvedMedia) + resolvedMedia.Length); //, orgSrc.Length - orgSrc.IndexOf(String.Format("/media/", SystemDirectories.Media)));
//}
//string fullSrc = IOHelper.MapPath(orgSrc);
var orgPath = fs.GetRelativePath(orgSrc);
if (fs.FileExists(orgPath))
{
var uf = new UmbracoFile(orgPath);
newSrc = uf.Resize(newWidth, newHeight);
}
/*
// Load original image
Image image = Image.FromFile(fullSrc);
// Create new image with best quality settings
Bitmap bp = new Bitmap(newWidth, newHeight);
Graphics g = Graphics.FromImage(bp);
g.SmoothingMode = SmoothingMode.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
// Copy the old image to the new and resized
Rectangle rect = new Rectangle(0, 0, newWidth, newHeight);
g.DrawImage(image, rect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel);
// Copy metadata
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
ImageCodecInfo codec = null;
for (int i = 0; i < codecs.Length; i++)
{
if (codecs[i].MimeType.Equals("image/jpeg"))
codec = codecs[i];
}
// Set compresion ratio to 90%
EncoderParameters ep = new EncoderParameters();
ep.Param[0] = new EncoderParameter(Encoder.Quality, 90L);
// Save the new image
bp.Save(fullSrcNew, codec, ep);
* */
}
// return the new width and height
finalWidth = newWidth;
finalHeight = newHeight;
//GE: When the SystemDirectories.Media contains a ~, newSrc will also contain this and hasn't been resolved.
//This causes the editor to save content which contains a virtual url, and thus the image doesn't serve
//the admin editor successfully displays the image because the HTML is rewritten, but when you get the RTE content in the template
//it hasn't been replaced
//2011-08-12 added a IOHelper.ResolveUrl call around newSrc
//2012-08-20 IFileSystem now takes care of URL resolution, so should be safe to assume newSrc is a full/absolute URL
return
" src=\"" + newSrc + "\" width=\"" + newWidth.ToString() + "\" height=\"" + newHeight.ToString() +
"\"";
return " src=\"" + newSrc + "\" width=\"" + newWidth + "\" height=\"" + newHeight + "\"";
}
}
}
@@ -60,6 +60,13 @@ namespace umbraco.editorControls.userControlGrapper
{
base.OnInit (e);
if (!_usercontrolPath.StartsWith("~"))
{
if (_usercontrolPath.StartsWith("/"))
_usercontrolPath = "~" + _usercontrolPath;
else
_usercontrolPath = "~/" + _usercontrolPath;
}
Control oControl = new System.Web.UI.UserControl().LoadControl(_usercontrolPath);
if (HasSettings(oControl.GetType()))

Some files were not shown because too many files have changed in this diff Show More