U4-10409 - udi parsing and assembly scanning
This commit is contained in:
26
src/Umbraco.Core/Serialization/KnownTypeUdiJsonConverter.cs
Normal file
26
src/Umbraco.Core/Serialization/KnownTypeUdiJsonConverter.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Umbraco.Core.Serialization
|
||||
{
|
||||
public class KnownTypeUdiJsonConverter : JsonConverter
|
||||
{
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
return typeof(Udi).IsAssignableFrom(objectType);
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
writer.WriteValue(value.ToString());
|
||||
}
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
var jo = JToken.ReadFrom(reader);
|
||||
var val = jo.ToObject<string>();
|
||||
return val == null ? null : Udi.Parse(val, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,12 +4,11 @@ using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Umbraco.Core.Serialization
|
||||
{
|
||||
|
||||
public class UdiJsonConverter : JsonConverter
|
||||
{
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
return typeof(Udi).IsAssignableFrom(objectType);
|
||||
return typeof (Udi).IsAssignableFrom(objectType);
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Umbraco.Core
|
||||
|
||||
private static volatile bool _scanned;
|
||||
private static readonly object ScanLocker = new object();
|
||||
private static readonly Lazy<ConcurrentDictionary<string, UdiType>> KnownUdiTypes;
|
||||
private static ConcurrentDictionary<string, UdiType> _udiTypes;
|
||||
private static readonly ConcurrentDictionary<string, Udi> RootUdis = new ConcurrentDictionary<string, Udi>();
|
||||
internal readonly Uri UriValue; // internal for UdiRange
|
||||
|
||||
@@ -50,8 +50,15 @@ namespace Umbraco.Core
|
||||
static Udi()
|
||||
{
|
||||
// initialize with known (built-in) Udi types
|
||||
// for non-known Udi types we'll try to parse a GUID and if that doesn't work, we'll decide that it's a string
|
||||
KnownUdiTypes = new Lazy<ConcurrentDictionary<string, UdiType>>(() => new ConcurrentDictionary<string, UdiType>(Constants.UdiEntityType.GetTypes()));
|
||||
// we will add scanned types later on
|
||||
_udiTypes = new ConcurrentDictionary<string, UdiType>(Constants.UdiEntityType.GetTypes());
|
||||
}
|
||||
|
||||
// for tests, totally unsafe
|
||||
internal static void ResetUdiTypes()
|
||||
{
|
||||
_udiTypes = new ConcurrentDictionary<string, UdiType>(Constants.UdiEntityType.GetTypes());
|
||||
_scanned = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -79,46 +86,65 @@ namespace Umbraco.Core
|
||||
public static Udi Parse(string s)
|
||||
{
|
||||
Udi udi;
|
||||
ParseInternal(s, false, out udi);
|
||||
ParseInternal(s, false, false, out udi);
|
||||
return udi;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the string representation of an entity identifier into the equivalent Udi instance.
|
||||
/// </summary>
|
||||
/// <param name="s">The string to convert.</param>
|
||||
/// <param name="knownTypes">A value indicating whether to only deal with known types.</param>
|
||||
/// <returns>An Udi instance that contains the value that was parsed.</returns>
|
||||
/// <remarks>
|
||||
/// <para>If <paramref name="knownTypes"/> is <c>true</c>, and the string could not be parsed because
|
||||
/// the entity type was not known, the method succeeds but sets <c>udi</c>to an
|
||||
/// <see cref="UnknownTypeUdi"/> value.</para>
|
||||
/// <para>If <paramref name="knownTypes"/> is <c>true</c>, assemblies are not scanned for types,
|
||||
/// and therefore only builtin types may be known. Unless scanning already took place.</para>
|
||||
/// </remarks>
|
||||
public static Udi Parse(string s, bool knownTypes)
|
||||
{
|
||||
Udi udi;
|
||||
ParseInternal(s, false, knownTypes, out udi);
|
||||
return udi;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the string representation of an entity identifier into the equivalent Udi instance.
|
||||
/// </summary>
|
||||
/// <param name="s">The string to convert.</param>
|
||||
/// <param name="udi">An Udi instance that contains the value that was parsed.</param>
|
||||
/// <returns>A boolean value indicating whether the string could be parsed.</returns>
|
||||
public static bool TryParse(string s, out Udi udi)
|
||||
{
|
||||
return ParseInternal(s, true, out udi);
|
||||
return ParseInternal(s, true, false, out udi);
|
||||
}
|
||||
|
||||
private static UdiType GetUdiType(Uri uri, out string path)
|
||||
/// <summary>
|
||||
/// Converts the string representation of an entity identifier into the equivalent Udi instance.
|
||||
/// </summary>
|
||||
/// <param name="s">The string to convert.</param>
|
||||
/// <param name="knownTypes">A value indicating whether to only deal with known types.</param>
|
||||
/// <param name="udi">An Udi instance that contains the value that was parsed.</param>
|
||||
/// <returns>A boolean value indicating whether the string could be parsed.</returns>
|
||||
/// <remarks>
|
||||
/// <para>If <paramref name="knownTypes"/> is <c>true</c>, and the string could not be parsed because
|
||||
/// the entity type was not known, the method returns <c>false</c> but still sets <c>udi</c>
|
||||
/// to an <see cref="UnknownTypeUdi"/> value.</para>
|
||||
/// <para>If <paramref name="knownTypes"/> is <c>true</c>, assemblies are not scanned for types,
|
||||
/// and therefore only builtin types may be known. Unless scanning already took place.</para>
|
||||
/// </remarks>
|
||||
public static bool TryParse(string s, bool knownTypes, out Udi udi)
|
||||
{
|
||||
path = uri.AbsolutePath.TrimStart('/');
|
||||
|
||||
UdiType udiType;
|
||||
if (KnownUdiTypes.Value.TryGetValue(uri.Host, out udiType))
|
||||
{
|
||||
return udiType;
|
||||
}
|
||||
|
||||
// if it's empty and it's not in our known list then we don't know
|
||||
if (path.IsNullOrWhiteSpace())
|
||||
return UdiType.Unknown;
|
||||
|
||||
// try to parse into a Guid
|
||||
// (note: root udis use Guid.Empty so this is ok)
|
||||
Guid guidId;
|
||||
if (Guid.TryParse(path, out guidId))
|
||||
{
|
||||
//add it to our known list
|
||||
KnownUdiTypes.Value.TryAdd(uri.Host, UdiType.GuidUdi);
|
||||
return UdiType.GuidUdi;
|
||||
}
|
||||
|
||||
// add it to our known list - if it's not a GUID then it must a string
|
||||
KnownUdiTypes.Value.TryAdd(uri.Host, UdiType.StringUdi);
|
||||
return UdiType.StringUdi;
|
||||
return ParseInternal(s, true, knownTypes, out udi);
|
||||
}
|
||||
|
||||
private static bool ParseInternal(string s, bool tryParse, out Udi udi)
|
||||
private static bool ParseInternal(string s, bool tryParse, bool knownTypes, out Udi udi)
|
||||
{
|
||||
if (knownTypes == false)
|
||||
EnsureScanForUdiTypes();
|
||||
|
||||
udi = null;
|
||||
Uri uri;
|
||||
|
||||
@@ -129,24 +155,30 @@ namespace Umbraco.Core
|
||||
throw new FormatException(string.Format("String \"{0}\" is not a valid udi.", s));
|
||||
}
|
||||
|
||||
// if it's a known entity type, GetUdiType will return it
|
||||
// else it will try to guess based on the path, and register the type as known
|
||||
string path;
|
||||
var udiType = GetUdiType(uri, out path);
|
||||
|
||||
if (path.IsNullOrWhiteSpace())
|
||||
var entityType = uri.Host;
|
||||
UdiType udiType;
|
||||
if (_udiTypes.TryGetValue(entityType, out udiType) == false)
|
||||
{
|
||||
// path is empty which indicates we need to return the root udi
|
||||
udi = GetRootUdi(uri.Host);
|
||||
return true;
|
||||
if (knownTypes)
|
||||
{
|
||||
// not knowing the type is not an error
|
||||
// just return the unknown type udi
|
||||
udi = UnknownTypeUdi.Instance;
|
||||
return false;
|
||||
}
|
||||
if (tryParse) return false;
|
||||
throw new FormatException(string.Format("Unknown entity type \"{0}\".", entityType));
|
||||
}
|
||||
|
||||
// if the path is not empty, type should not be unknown
|
||||
if (udiType == UdiType.Unknown)
|
||||
throw new FormatException(string.Format("Could not determine the Udi type for string \"{0}\".", s));
|
||||
var path = uri.AbsolutePath.TrimStart('/');
|
||||
|
||||
if (udiType == UdiType.GuidUdi)
|
||||
{
|
||||
if (path == string.Empty)
|
||||
{
|
||||
udi = GetRootUdi(uri.Host);
|
||||
return true;
|
||||
}
|
||||
Guid guid;
|
||||
if (Guid.TryParse(path, out guid) == false)
|
||||
{
|
||||
@@ -156,23 +188,25 @@ namespace Umbraco.Core
|
||||
udi = new GuidUdi(uri.Host, guid);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (udiType == UdiType.StringUdi)
|
||||
{
|
||||
udi = new StringUdi(uri.Host, Uri.UnescapeDataString(path));
|
||||
udi = path == string.Empty ? GetRootUdi(uri.Host) : new StringUdi(uri.Host, Uri.UnescapeDataString(path));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (tryParse) return false;
|
||||
throw new InvalidOperationException("Internal error.");
|
||||
throw new InvalidOperationException(string.Format("Invalid udi type \"{0}\".", udiType));
|
||||
}
|
||||
|
||||
private static Udi GetRootUdi(string entityType)
|
||||
{
|
||||
ScanAllUdiTypes();
|
||||
EnsureScanForUdiTypes();
|
||||
|
||||
return RootUdis.GetOrAdd(entityType, x =>
|
||||
{
|
||||
UdiType udiType;
|
||||
if (KnownUdiTypes.Value.TryGetValue(x, out udiType) == false)
|
||||
if (_udiTypes.TryGetValue(x, out udiType) == false)
|
||||
throw new ArgumentException(string.Format("Unknown entity type \"{0}\".", entityType));
|
||||
return udiType == UdiType.StringUdi
|
||||
? (Udi)new StringUdi(entityType, string.Empty)
|
||||
@@ -186,7 +220,7 @@ namespace Umbraco.Core
|
||||
/// <remarks>
|
||||
/// This is only required when needing to resolve root udis
|
||||
/// </remarks>
|
||||
private static void ScanAllUdiTypes()
|
||||
private static void EnsureScanForUdiTypes()
|
||||
{
|
||||
if (_scanned) return;
|
||||
|
||||
@@ -212,11 +246,9 @@ namespace Umbraco.Core
|
||||
}
|
||||
}
|
||||
|
||||
//merge these into the known list
|
||||
// merge these into the known list
|
||||
foreach (var item in result)
|
||||
{
|
||||
KnownUdiTypes.Value.TryAdd(item.Key, item.Value);
|
||||
}
|
||||
_udiTypes.TryAdd(item.Key, item.Value);
|
||||
|
||||
_scanned = true;
|
||||
}
|
||||
@@ -241,11 +273,13 @@ namespace Umbraco.Core
|
||||
public static Udi Create(string entityType, string id)
|
||||
{
|
||||
UdiType udiType;
|
||||
if (KnownUdiTypes.Value.TryGetValue(entityType, out udiType) && udiType != UdiType.StringUdi)
|
||||
throw new InvalidOperationException(string.Format("Entity type \"{0}\" is not a StringUdi.", entityType));
|
||||
if (_udiTypes.TryGetValue(entityType, out udiType) == false)
|
||||
throw new ArgumentException(string.Format("Unknown entity type \"{0}\".", entityType), "entityType");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(id))
|
||||
throw new ArgumentException("Value cannot be null or whitespace.", "id");
|
||||
if (udiType != UdiType.StringUdi)
|
||||
throw new InvalidOperationException(string.Format("Entity type \"{0}\" does not have string udis.", entityType));
|
||||
|
||||
return new StringUdi(entityType, id);
|
||||
}
|
||||
@@ -259,11 +293,14 @@ namespace Umbraco.Core
|
||||
public static Udi Create(string entityType, Guid id)
|
||||
{
|
||||
UdiType udiType;
|
||||
if (KnownUdiTypes.Value.TryGetValue(entityType, out udiType) && udiType != UdiType.GuidUdi)
|
||||
throw new InvalidOperationException(string.Format("Entity type \"{0}\" is not a GuidUdi.", entityType));
|
||||
if (_udiTypes.TryGetValue(entityType, out udiType) == false)
|
||||
throw new ArgumentException(string.Format("Unknown entity type \"{0}\".", entityType), "entityType");
|
||||
|
||||
if (udiType != UdiType.GuidUdi)
|
||||
throw new InvalidOperationException(string.Format("Entity type \"{0}\" does not have guid udis.", entityType));
|
||||
if (id == default(Guid))
|
||||
throw new ArgumentException("Cannot be an empty guid.", "id");
|
||||
|
||||
return new GuidUdi(entityType, id);
|
||||
}
|
||||
|
||||
@@ -273,13 +310,14 @@ namespace Umbraco.Core
|
||||
// else fallback to parsing the string (and guess the type)
|
||||
|
||||
UdiType udiType;
|
||||
if (KnownUdiTypes.Value.TryGetValue(uri.Host, out udiType) == false)
|
||||
return Parse(uri.ToString());
|
||||
if (_udiTypes.TryGetValue(uri.Host, out udiType) == false)
|
||||
throw new ArgumentException(string.Format("Unknown entity type \"{0}\".", uri.Host), "uri");
|
||||
|
||||
if (udiType == UdiType.GuidUdi)
|
||||
return new GuidUdi(uri);
|
||||
if (udiType == UdiType.GuidUdi)
|
||||
return new StringUdi(uri);
|
||||
|
||||
throw new ArgumentException(string.Format("Uri \"{0}\" is not a valid udi.", uri));
|
||||
}
|
||||
|
||||
@@ -328,6 +366,19 @@ namespace Umbraco.Core
|
||||
{
|
||||
return (udi1 == udi2) == false;
|
||||
}
|
||||
}
|
||||
|
||||
private class UnknownTypeUdi : Udi
|
||||
{
|
||||
private UnknownTypeUdi()
|
||||
: base("unknown", "umb://unknown/")
|
||||
{ }
|
||||
|
||||
public static readonly UnknownTypeUdi Instance = new UnknownTypeUdi();
|
||||
|
||||
public override bool IsRoot
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -644,6 +644,7 @@
|
||||
<Compile Include="Security\EmailService.cs" />
|
||||
<Compile Include="Security\OwinExtensions.cs" />
|
||||
<Compile Include="SemVersionExtensions.cs" />
|
||||
<Compile Include="Serialization\KnownTypeUdiJsonConverter.cs" />
|
||||
<Compile Include="Serialization\NoTypeConverterJsonConverter.cs" />
|
||||
<Compile Include="Serialization\StreamResultExtensions.cs" />
|
||||
<Compile Include="Serialization\UdiJsonConverter.cs" />
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Deploy;
|
||||
using Umbraco.Core.Serialization;
|
||||
|
||||
namespace Umbraco.Tests
|
||||
@@ -180,16 +182,6 @@ namespace Umbraco.Tests
|
||||
Assert.IsInstanceOf<GuidUdi>(udi);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NotKnownTypeTest()
|
||||
{
|
||||
var udi1 = Udi.Parse("umb://not-known-1/DA845952BE474EE9BD6F6194272AC750");
|
||||
Assert.IsInstanceOf<GuidUdi>(udi1);
|
||||
|
||||
var udi2 = Udi.Parse("umb://not-known-2/this-is-not-a-guid");
|
||||
Assert.IsInstanceOf<StringUdi>(udi2);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RangeTest()
|
||||
{
|
||||
@@ -265,5 +257,86 @@ namespace Umbraco.Tests
|
||||
|
||||
Assert.AreEqual(0, types.Count, "Error in class Constants.UdiEntityType, GetTypes declares types that don't exist ({0}).", string.Join(",", types.Keys.Select(x => "\"" + x + "\"")));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void KnownTypes()
|
||||
{
|
||||
Udi udi;
|
||||
|
||||
// cannot parse an unknown type, udi is null
|
||||
// this will scan
|
||||
Assert.IsFalse(Udi.TryParse("umb://whatever/1234", out udi));
|
||||
Assert.IsNull(udi);
|
||||
|
||||
Udi.ResetUdiTypes();
|
||||
|
||||
// unless we want to know
|
||||
Assert.IsFalse(Udi.TryParse("umb://whatever/1234", true, out udi));
|
||||
Assert.AreEqual(Constants.UdiEntityType.Unknown, udi.EntityType);
|
||||
Assert.AreEqual("Umbraco.Core.Udi+UnknownTypeUdi", udi.GetType().FullName);
|
||||
|
||||
Udi.ResetUdiTypes();
|
||||
|
||||
// not known
|
||||
Assert.IsFalse(Udi.TryParse("umb://foo/A87F65C8D6B94E868F6949BA92C93045", true, out udi));
|
||||
Assert.AreEqual(Constants.UdiEntityType.Unknown, udi.EntityType);
|
||||
Assert.AreEqual("Umbraco.Core.Udi+UnknownTypeUdi", udi.GetType().FullName);
|
||||
|
||||
// scanned
|
||||
Assert.IsTrue(Udi.TryParse("umb://foo/A87F65C8D6B94E868F6949BA92C93045", out udi));
|
||||
Assert.IsInstanceOf<GuidUdi>(udi);
|
||||
|
||||
// known
|
||||
Assert.IsTrue(Udi.TryParse("umb://foo/A87F65C8D6B94E868F6949BA92C93045", true, out udi));
|
||||
Assert.IsInstanceOf<GuidUdi>(udi);
|
||||
|
||||
// can get method for Deploy compatibility
|
||||
var method = typeof (Udi).GetMethod("Parse", BindingFlags.Static | BindingFlags.Public, null, new[] { typeof (string), typeof (bool) }, null);
|
||||
Assert.IsNotNull(method);
|
||||
}
|
||||
|
||||
[UdiDefinition("foo", UdiType.GuidUdi)]
|
||||
public class FooConnector : IServiceConnector
|
||||
{
|
||||
public IArtifact GetArtifact(Udi udi)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IArtifact GetArtifact(object entity)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public ArtifactDeployState ProcessInit(IArtifact art, IDeployContext context)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Process(ArtifactDeployState dart, IDeployContext context, int pass)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Explode(UdiRange range, List<Udi> udis)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public NamedUdiRange GetRange(Udi udi, string selector)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public NamedUdiRange GetRange(string entityType, string sid, string selector)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool Compare(IArtifact art1, IArtifact art2, ICollection<Difference> differences = null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -119,4 +119,14 @@
|
||||
</control>
|
||||
</tab>
|
||||
</section>
|
||||
<section alias="Deploy">
|
||||
<areas>
|
||||
<area>content</area>
|
||||
</areas>
|
||||
<tab caption="Deploy">
|
||||
<control>
|
||||
/App_Plugins/Deploy/views/dashboards/dashboard.html
|
||||
</control>
|
||||
</tab>
|
||||
</section>
|
||||
</dashBoard>
|
||||
@@ -1,7 +1,7 @@
|
||||
<%@ Page Language="C#" AutoEventWireup="True" Inherits="Umbraco.Web.UI.Config.Splashes.NoNodes" CodeBehind="NoNodes.aspx.cs" %>
|
||||
<%@ Import Namespace="Umbraco.Core.Configuration" %>
|
||||
<%@ Page Language="C#" AutoEventWireup="true"%>
|
||||
<%@ Import Namespace="Umbraco.Core.IO" %>
|
||||
|
||||
<%@ Import Namespace="Umbraco.Deploy.UI" %>
|
||||
<%@ Import Namespace="Umbraco.Web" %>
|
||||
<!doctype html>
|
||||
<!--[if lt IE 7]> <html class="no-js ie6 oldie" lang="en"> <![endif]-->
|
||||
<!--[if IE 7]> <html class="no-js ie7 oldie" lang="en"> <![endif]-->
|
||||
@@ -11,51 +11,145 @@
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
|
||||
|
||||
<title></title>
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
|
||||
<link rel="stylesheet" href="../../Umbraco/assets/css/nonodes.style.min.css" />
|
||||
<link href='//fonts.googleapis.com/css?family=Open+Sans:300,400,700,600' rel='stylesheet' type='text/css'>
|
||||
<link href='//fonts.googleapis.com/css?family=Asap:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
|
||||
|
||||
<link rel="stylesheet" href="<%=IOHelper.ResolveUrl(SystemDirectories.Umbraco)%>/assets/css/nonodes.style.min.css" />
|
||||
<link rel="stylesheet" href="<%=IOHelper.ResolveUrl(SystemDirectories.AppPlugins)%>/deploy/assets/css/deploy.css" />
|
||||
|
||||
<!--[if lt IE 9]>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/modernizr/2.7.1/modernizr.min.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<% if(HttpContext.Current.Request.IsLocal == false){ %>
|
||||
<section>
|
||||
<article>
|
||||
<div>
|
||||
<div class="logo"></div>
|
||||
<article>
|
||||
<div>
|
||||
<div class="logo"></div>
|
||||
|
||||
<h1>Welcome to your Umbraco installation</h1>
|
||||
<h3>You're seeing this wonderful page because your website doesn't contain any published content yet.</h3>
|
||||
<h1>Welcome to your Umbraco installation</h1>
|
||||
<h3>You're seeing the wonderful page because your website doesn't contain any published content yet.</h3>
|
||||
|
||||
<div class="cta">
|
||||
<a href="<%= IOHelper.ResolveUrl(SystemDirectories.Umbraco) %>" class="button">Open Umbraco</a>
|
||||
</div>
|
||||
<div class="cta">
|
||||
<a href="<%= IOHelper.ResolveUrl(SystemDirectories.Umbraco) %>" class="button">Open Umbraco</a>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h2>Easy start with Umbraco.tv</h2>
|
||||
<p>We have created a bunch of 'how-to' videos, to get you easily started with Umbraco. Learn how to build projects in just a couple of minutes. Easiest CMS in the world.</p>
|
||||
|
||||
<a href="http://umbraco.tv?ref=tvFromInstaller" target="_blank">Umbraco.tv →</a>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h2>Easy start with Umbraco.tv</h2>
|
||||
<p>We have created a bunch of 'how-to' videos, to get you easily started with Umbraco. Learn how to build projects in just a couple of minutes. Easiest CMS in the world.</p>
|
||||
|
||||
<a href="http://umbraco.tv?ref=tvFromInstaller" target="_blank">Umbraco.tv →</a>
|
||||
</div>
|
||||
|
||||
<div class="col">
|
||||
<h2>Be a part of the community</h2>
|
||||
<p>The Umbraco community is the best of its kind, be sure to visit, and if you have any questions, we're sure that you can get your answers from the community.</p>
|
||||
|
||||
<a href="http://our.umbraco.org?ref=ourFromInstaller" target="_blank">our.Umbraco →</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h2>Be a part of the community</h2>
|
||||
<p>The Umbraco community is the best of its kind, be sure to visit, and if you have any questions, we’re sure that you can get your answers from the community.</p>
|
||||
|
||||
<a href="http://our.umbraco.org?ref=ourFromInstaller" target="_blank">our.Umbraco →</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<% }else{ %>
|
||||
|
||||
<section ng-controller="Umbraco.NoNodes.Controller as vm">
|
||||
<article class="ud-nonodes">
|
||||
|
||||
<div>
|
||||
<div class="logo"></div>
|
||||
|
||||
<div>
|
||||
|
||||
<div ng-if="vm.restore.status === ''">
|
||||
|
||||
<div ng-if="!vm.requiresInitialization">
|
||||
<h1>Initializing...</h1>
|
||||
<small>Please wait while your site is loaded</small>
|
||||
</div>
|
||||
|
||||
<p ng-show="vm.restore.restoreProgress">{{ vm.restore.restoreProgress }}% restored</p>
|
||||
<small ng-show="vm.restore.currentActivity">{{ vm.restore.currentActivity }}</small>
|
||||
|
||||
<div ng-if="vm.requiresInitialization">
|
||||
<h1>Initialize your site...</h1>
|
||||
<small>Press the button below to get started</small>
|
||||
<div class="cta">
|
||||
<button class="button" ng-click="vm.restoreSchema()">Go!</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-if="vm.restore.status === 'ready'">
|
||||
<h1>Restore from Umbraco Cloud</h1>
|
||||
<div class="cta">
|
||||
<button class="button" ng-click="vm.restoreData()">Restore</button>
|
||||
<small><span>or</span> <a ng-href="<%= IOHelper.ResolveUrl(SystemDirectories.Umbraco) %>">Skip restore and open Umbraco</a></small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-if="vm.restore.status === 'inProgress'">
|
||||
<h1>Restoring your website...</h1>
|
||||
<p>{{ vm.restore.restoreProgress }}% restored</p>
|
||||
<small>{{ vm.restore.currentActivity }}</small>
|
||||
</div>
|
||||
|
||||
<div ng-if="vm.restore.status === 'completed'">
|
||||
<h1>Ready to rock n' roll!</h1>
|
||||
<p>Everything has been restored and is ready for use, click below to open Umbraco</p>
|
||||
<div class="cta">
|
||||
<a href="<%= IOHelper.ResolveUrl(SystemDirectories.Umbraco) %>" class="button">Open Umbraco</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ud-error
|
||||
ng-if="vm.restore.error.hasError"
|
||||
comment="vm.restore.error.comment"
|
||||
log="vm.restore.error.log"
|
||||
exception="vm.restore.error.exception"
|
||||
status="vm.restore.status"
|
||||
class="ud-restore-error"
|
||||
no-nodes="true">
|
||||
</ud-error>
|
||||
|
||||
<%--<div ng-if="vm.restore.error.hasError" class="json">
|
||||
<h1 style="margin-top: 0;">An error occurred: </h1>
|
||||
<h2 ng-if="vm.restore.error.exceptionMessage">{{ vm.restore.error.exceptionMessage }}</h2>
|
||||
<a href="#" ng-click="vm.showLog()" ng-hide="vm.logIsvisible">Show details</a>
|
||||
<pre ng-if="vm.logIsvisible === true">{{ vm.restore.error.log }}</pre>
|
||||
</div>--%>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</article>
|
||||
|
||||
</section>
|
||||
|
||||
<script src="https://code.jquery.com/jquery-latest.min.js"></script>
|
||||
|
||||
<%= NoNodesHelper.ServerVariables(HttpContext.Current.Request.RequestContext, UmbracoContext.Current) %>
|
||||
<script type="text/javascript" src="<%= IOHelper.ResolveUrl(SystemDirectories.Umbraco) %>/lib/jquery/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="<%= IOHelper.ResolveUrl(SystemDirectories.Umbraco) %>/lib/angular/1.1.5/angular.min.js"></script>
|
||||
<script type="text/javascript" src="<%= IOHelper.ResolveUrl(SystemDirectories.AppPlugins) %>/deploy/lib/signalr/jquery.signalR.min.js"></script>
|
||||
<script type="text/javascript" src="<%= IOHelper.ResolveUrl(SystemDirectories.Umbraco) %>/backoffice/signalr/hubs"></script>
|
||||
<script type="text/javascript" src="<%= IOHelper.ResolveUrl(SystemDirectories.AppPlugins) %>/deploy/js/nonodes.modules.js"></script>
|
||||
<script type="text/javascript" src="<%= IOHelper.ResolveUrl(SystemDirectories.AppPlugins) %>/deploy/js/deploy.services.js"></script>
|
||||
<script type="text/javascript" src="<%= IOHelper.ResolveUrl(SystemDirectories.AppPlugins) %>/deploy/js/deploy.components.js"></script>
|
||||
<script type="text/javascript" src="<%= IOHelper.ResolveUrl(SystemDirectories.AppPlugins) %>/deploy/js/nonodes.bootstrap.js"></script>
|
||||
<script type="text/javascript">
|
||||
angular.bootstrap(document, ['umbraco.nonodes']);
|
||||
</script>
|
||||
<% } %>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
@@ -41,4 +41,5 @@
|
||||
<add initialize="true" sortOrder="0" alias="form" application="forms" title="Forms" iconClosed="icon-folder" iconOpen="icon-folder-open" type="Umbraco.Forms.Web.Trees.FormTreeController, Umbraco.Forms.Web" />
|
||||
<add initialize="true" sortOrder="3" alias="prevaluesource" application="forms" title="Prevalue sources" iconClosed="icon-folder" iconOpen="icon-folder-open" type="Umbraco.Forms.Web.Trees.PreValueSourceTreeController, Umbraco.Forms.Web" />
|
||||
<add initialize="true" sortOrder="3" alias="formsecurity" application="users" title="Forms Security" iconClosed="icon-folder" iconOpen="icon-folder-open" type="Umbraco.Forms.Web.Trees.FormSecurityTreeController, Umbraco.Forms.Web" />
|
||||
<add initialize="false" sortOrder="0" alias="emailTemplates" application="forms" title="Email Templates" iconClosed="icon-folder" iconOpen="icon-folder-open" type="Umbraco.Forms.Web.Trees.EmailTemplateTreeController, Umbraco.Forms.Web" />
|
||||
</trees>
|
||||
Reference in New Issue
Block a user