The Starter Kit is a great way to experience some of the ways you can use Umbraco. It's a complete website with textpages, landing pages, blog, product listings and more that's easy to get started with Umbraco.
-
-
- It's also a great way to learn Umbraco as the Starter Kit comes with a set of Lessons that'll teach you how to implement and extend Umbraco using short 5-15 minute tasks.
-
diff --git a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/textstring.html b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/textstring.html
index 8fcfc8b5c6..a394bdefe4 100644
--- a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/textstring.html
+++ b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/textstring.html
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/treepicker.html b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/treepicker.html
index 1ffa878818..5ec114fc19 100644
--- a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/treepicker.html
+++ b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/treepicker.html
@@ -4,7 +4,7 @@
ng-model="renderModel">
\ No newline at end of file
diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
index 7c634a376e..4228baf532 100644
--- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
+++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
@@ -568,6 +568,8 @@
+
+
@@ -2378,9 +2380,9 @@ xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\x86\*.* "$(TargetDir)x86\"
TrueTrue
- 7640
+ 7650/
- http://localhost:7640
+ http://localhost:7650FalseFalse
diff --git a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/Breadcrumb.cshtml b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/Breadcrumb.cshtml
old mode 100644
new mode 100755
index ff63081996..5dd44df7f9
--- a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/Breadcrumb.cshtml
+++ b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/Breadcrumb.cshtml
@@ -1,13 +1,13 @@
@inherits Umbraco.Web.Macros.PartialViewMacroPage
@*
- This snippet makes a breadcrumb of parents using an unordered html list.
+ This snippet makes a breadcrumb of parents using an unordered HTML list.
How it works:
- It uses the Ancestors() method to get all parents and then generates links so the visitor can go back
- Finally it outputs the name of the current page (without a link)
*@
-@{ var selection = CurrentPage.Ancestors(); }
+@{ var selection = Model.Content.Ancestors(); }
@if (selection.Any())
{
@@ -19,6 +19,6 @@
}
@* Display the current page as the last item in the list *@
-
@CurrentPage.Name
+
@Model.Content.Name
}
\ No newline at end of file
diff --git a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/Gallery.cshtml b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/Gallery.cshtml
old mode 100644
new mode 100755
index f7c5954c5a..7ed0e01680
--- a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/Gallery.cshtml
+++ b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/Gallery.cshtml
@@ -1,50 +1,50 @@
@inherits Umbraco.Web.Macros.PartialViewMacroPage
@*
- Macro to display a gallery of images from media the media section.
+ Macro to display a gallery of images from the Media section.
Works with either a 'Single Media Picker' or a 'Multiple Media Picker' macro parameter (see below).
How it works:
- Confirm the macro parameter has been passed in with a value
- - Loop through all the media Id's passed in (might be a single item, might be many)
+ - Loop through all the media Ids passed in (might be a single item, might be many)
- Display any individual images, as well as any folders of images
Macro Parameters To Create, for this macro to work:
Alias:mediaIds Name:Select folders and/or images Type: Multiple Media Picker
- Type: (note: you can use a Single Media Picker if that's more appropriate to your needs)
+ Type: (note: You can use a Single Media Picker if that's more appropriate to your needs)
*@
-@{ var mediaIds = Model.MacroParameters["mediaIds"]; }
+@{ var mediaIds = Model.MacroParameters["mediaIds"] as string; }
+
@if (mediaIds != null)
{
-
- @foreach (var mediaId in mediaIds.ToString().Split(','))
+
+ @foreach (var mediaId in mediaIds.Split(','))
{
- var media = Umbraco.Media(mediaId);
+ var media = Umbraco.TypedMedia(mediaId);
@* a single image *@
if (media.DocumentTypeAlias == "Image")
{
- @Render(media);
+ @Render(media as Image);
}
@* a folder with images under it *@
- if (media.Children("Image").Any())
+ if (media.Children().Any())
{
- foreach (var image in media.Children("Image"))
+ foreach (var image in media.Children())
{
@Render(image);
}
}
-
}
-
+
}
\ No newline at end of file
diff --git a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/ListAncestorsFromCurrentPage.cshtml b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/ListAncestorsFromCurrentPage.cshtml
old mode 100644
new mode 100755
index b7ca9d06e4..8d4d897b89
--- a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/ListAncestorsFromCurrentPage.cshtml
+++ b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/ListAncestorsFromCurrentPage.cshtml
@@ -1,24 +1,24 @@
@inherits Umbraco.Web.Macros.PartialViewMacroPage
@*
- This snippet makes a list of links to the of parents of the current page using an unordered html list.
+ This snippet makes a list of links to the of parents of the current page using an unordered HTML list.
How it works:
- It uses the Ancestors() method to get all parents and then generates links so the visitor can go back
- Finally it outputs the name of the current page (without a link)
*@
-@{ var selection = CurrentPage.Ancestors(); }
+@{ var selection = Model.Content.Ancestors(); }
@if (selection.Any())
{
@* For each page in the ancestors collection which have been ordered by Level (so we start with the highest top node first) *@
- @foreach (var item in selection.OrderBy("Level"))
+ @foreach (var item in selection.OrderBy(x => x.Level))
{
}
diff --git a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/ListChildPagesFromCurrentPage.cshtml b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/ListChildPagesFromCurrentPage.cshtml
old mode 100644
new mode 100755
index 9bd13f68a2..09144cff47
--- a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/ListChildPagesFromCurrentPage.cshtml
+++ b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/ListChildPagesFromCurrentPage.cshtml
@@ -1,6 +1,14 @@
@inherits Umbraco.Web.Macros.PartialViewMacroPage
-@{ var selection = CurrentPage.Children.Where("Visible"); }
+@*
+ This snippet makes a list of links to the of children of the current page using an unordered HTML list.
+
+ How it works:
+ - It uses the Children method to get all child pages
+ - It then generates links so the visitor can go to each page
+*@
+
+@{ var selection = Model.Content.Children.Where(x => x.IsVisible()); }
@if (selection.Any())
{
diff --git a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/ListChildPagesOrderedByDate.cshtml b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/ListChildPagesOrderedByDate.cshtml
old mode 100644
new mode 100755
index c8cbdf7d32..5cd74a62f9
--- a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/ListChildPagesOrderedByDate.cshtml
+++ b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/ListChildPagesOrderedByDate.cshtml
@@ -1,11 +1,22 @@
@inherits Umbraco.Web.Macros.PartialViewMacroPage
-@{ var selection = CurrentPage.Children.Where("Visible").OrderBy("CreateDate desc"); }
-@* OrderBy() takes the property to sort by and optionally order desc/asc *@
+@*
+ This snippet makes a list of links to the of children of the current page using an unordered HTML list.
-
+ How it works:
+ - It uses the Children method to get all child pages
+ - It then uses the OrderByDescending() method, which takes the property to sort. In this case the page's creation date.
+ - It then generates links so the visitor can go to each page
+*@
+
+@{ var selection = Model.Content.Children.Where(x => x.IsVisible()).OrderByDescending(x => x.CreateDate); }
+
+@if (selection.Any())
+{
+
+}
diff --git a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/ListChildPagesOrderedByName.cshtml b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/ListChildPagesOrderedByName.cshtml
old mode 100644
new mode 100755
index da73ff8164..643855006f
--- a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/ListChildPagesOrderedByName.cshtml
+++ b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/ListChildPagesOrderedByName.cshtml
@@ -1,11 +1,22 @@
@inherits Umbraco.Web.Mvc.UmbracoTemplatePage
-@{ var selection = CurrentPage.Children.Where("Visible").OrderBy("Name"); }
-@* OrderBy() takes the property to sort by *@
+@*
+ This snippet makes a list of links to the of children of the current page using an unordered HTML list.
-
+ How it works:
+ - It uses the Children method to get all child pages
+ - It then uses the OrderBy() method, which takes the property to sort. In this case, the page's name.
+ - It then generates links so the visitor can go to each page
+*@
+
+@{ var selection = Model.Content.Children.Where(x => x.IsVisible()).OrderBy(x => x.Name); }
+
+@if (selection.Any())
+{
+
+ }
}
diff --git a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/ListChildPagesWithDoctype.cshtml b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/ListChildPagesWithDoctype.cshtml
old mode 100644
new mode 100755
index 4ca6f93c71..9ac71a4fd2
--- a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/ListChildPagesWithDoctype.cshtml
+++ b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/ListChildPagesWithDoctype.cshtml
@@ -1,17 +1,13 @@
@inherits Umbraco.Web.Macros.PartialViewMacroPage
@*
- This snippet shows how simple it is to fetch only children of a certain Document Type using Razor.
- Be sure to change "DocumentTypeAlias" below to match your needs, such as "TextPage" or "NewsItems".
+ This snippet shows how simple it is to fetch only children of a certain Document Type.
+
+ Be sure to change "IPublishedContent" below to match your needs, such as "TextPage" or "NewsItem".
(You can find the alias of your Document Type by editing it in the Settings section)
*@
-@{ var selection = CurrentPage.Children("DocumentTypeAlias").Where("Visible"); }
-@*
- As an example of more querying, if you have a true/false property with the alias of shouldBeFeatured:
- var selection= CurrentPage.Children("DocumentTypeAlias").Where("shouldBeFeatured == true").Where("Visible");
-*@
-
+@{ var selection = Model.Content.Children().Where(x => x.IsVisible()); }
@if (selection.Any())
{
diff --git a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/ListDescendantsFromCurrentPage.cshtml b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/ListDescendantsFromCurrentPage.cshtml
old mode 100644
new mode 100755
index 1e2274bcc0..e649328cfb
--- a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/ListDescendantsFromCurrentPage.cshtml
+++ b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/ListDescendantsFromCurrentPage.cshtml
@@ -2,27 +2,27 @@
@*
This snippet creates links for every single page (no matter how deep) below
- the page currently being viewed by the website visitor, displayed as nested unordered html lists.
+ the page currently being viewed by the website visitor, displayed as nested unordered HTML lists.
*@
-@{ var selection = CurrentPage.Children.Where("Visible"); }
+@{ var selection = Model.Content.Children.Where(x => x.IsVisible()); }
@* Ensure that the Current Page has children *@
@if (selection.Any())
{
@* Get the first page in the children, where the property umbracoNaviHide is not True *@
- var naviLevel = CurrentPage.FirstChild().Where("Visible").Level;
+ var naviLevel = Model.Content.FirstChild(x => x.IsVisible()).Level;
@* Add in level for a CSS hook *@
- @* For each child page where the property umbracoNaviHide is not True *@
+ @* Loop through the selection *@
@foreach (var item in selection)
{
@item.Name
@* if this child page has any children, where the property umbracoNaviHide is not True *@
- @if (item.Children.Where("Visible").Any())
+ @if (item.Children.Where(x => x.IsVisible()).Any())
{
@* Call our helper to display the children *@
@childPages(item.Children)
@@ -33,7 +33,7 @@
}
-@helper childPages(dynamic selection)
+@helper childPages(IEnumerable selection)
{
@* Ensure that we have a collection of pages *@
if (selection.Any())
@@ -43,13 +43,13 @@
@* Add in level for a CSS hook *@
- @foreach (var item in selection.Where("Visible"))
+ @foreach (var item in selection.Where(x => x.IsVisible()))
{
@item.Name
@* if the this page has any children, where the property umbracoNaviHide is not True *@
- @if (item.Children.Where("Visible").Any())
+ @if (item.Children.Where(x => x.IsVisible()).Any())
{
@* Call our helper to display the children *@
@childPages(item.Children)
diff --git a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/ListImagesFromMediaFolder.cshtml b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/ListImagesFromMediaFolder.cshtml
old mode 100644
new mode 100755
index 1549c1eed2..6e5d68b829
--- a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/ListImagesFromMediaFolder.cshtml
+++ b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/ListImagesFromMediaFolder.cshtml
@@ -5,7 +5,7 @@
How it works:
- Confirm the macro parameter has been passed in with a value
- - Loop through all the media Id's passed in (might be a single item, might be many)
+ - Loop through all the media Ids passed in (might be a single item, might be many)
- Display any individual images, as well as any folders of images
Macro Parameters To Create, for this macro to work:
@@ -15,9 +15,9 @@
@{ var mediaId = Model.MacroParameters["mediaId"]; }
@if (mediaId != null)
{
- @* Get all the media item associated with the id passed in *@
- var media = Umbraco.Media(mediaId);
- var selection = media.Children("Image");
+ @* Get the media item associated with the id passed in *@
+ var media = Umbraco.TypedMedia(mediaId);
+ var selection = media.Children();
if (selection.Any())
{
@@ -25,7 +25,7 @@
@foreach (var item in selection)
{
-
+
}
diff --git a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/MultinodeTree-picker.cshtml b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/MultinodeTree-picker.cshtml
old mode 100644
new mode 100755
index ae8e427449..379b5b0ea0
--- a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/MultinodeTree-picker.cshtml
+++ b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/MultinodeTree-picker.cshtml
@@ -1,21 +1,23 @@
@inherits Umbraco.Web.Macros.PartialViewMacroPage
@*
- This snippet lists the items from a Multinode tree picker, using the pickers default settings.
- Content Values stored as xml.
+ This snippet lists the items from a Multinode tree picker, using the picker's default settings.
+ Content Values stored as XML.
To get it working with any site's data structure, set the selection equal to the property which has the
multinode treepicker (so: replace "PropertyWithPicker" with the alias of your property).
*@
-@{ var selection = CurrentPage.PropertyWithPicker.Split(','); }
+@{ var selection = Model.Content.GetPropertyValue>("PropertyWithPicker"); }
-
- @foreach (var id in selection)
- {
- var item = Umbraco.Content(id);
-
+}
\ No newline at end of file
diff --git a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/Navigation.cshtml b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/Navigation.cshtml
old mode 100644
new mode 100755
index f2a4920a12..94870a37c4
--- a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/Navigation.cshtml
+++ b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/Navigation.cshtml
@@ -3,16 +3,19 @@
@*
This snippet displays a list of links of the pages immediately under the top-most page in the content tree.
This is the home page for a standard website.
- It also highlights the current active page/section in the navigation with the css class "current".
+ It also highlights the current active page/section in the navigation with the CSS class "current".
*@
-@{ var selection = CurrentPage.Site().Children.Where("Visible"); }
+@{ var selection = Model.Content.Site().Children.Where(x => x.IsVisible()); }
-
+}
diff --git a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/SiteMap.cshtml b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/SiteMap.cshtml
old mode 100644
new mode 100755
index 0aef1eb3a4..7630b26ed1
--- a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/SiteMap.cshtml
+++ b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/SiteMap.cshtml
@@ -1,13 +1,13 @@
@inherits Umbraco.Web.Macros.PartialViewMacroPage
@*
- This snippet makes a list of links of all visible pages of the site, as nested unordered html lists.
+ This snippet makes a list of links of all visible pages of the site, as nested unordered HTML lists.
How it works:
- It uses a custom Razor helper called Traverse() to select and display the markup and links.
*@
-@{ var selection = CurrentPage.Site(); }
+@{ var selection = Model.Content.Site(); }
@* Render the sitemap by passing the root node to the traverse helper, below *@
@@ -15,14 +15,14 @@
要发布当前页和所有子页,请选中 全部发布 发布所有子页。
- ]]>
+ ]]>
+ 您没有配置任何认可的颜色
@@ -885,6 +1014,10 @@
Reset
+ Define crop
+ Give the crop an alias and its default width and height
+ Save crop
+ Add new crop当前版本
@@ -950,8 +1083,8 @@
请不要关闭窗口]]>
- 验证
- 在保存项之前必须修复验证错误
+ 验证
+ 在保存项之前必须修复验证错误失败用户权限不足, 无法完成操作取消
@@ -1027,15 +1160,90 @@
编辑模板
+ 部分插入内容区插入内容占位符
+ 插入
+ 选择要插入到模板中的内容插入字典项
+ 字典项是可翻译的文本部分的占位符, 这使得为多语言网站创建设计变得容易。插入宏
+
+ 宏是一个可配置的组件, 对于
+ 设计的可重用部分, 在这里您需要提供参数的选项,
+ 如画廊、表格和列表。
+ 插入页字段
+ 显示当前页中指定字段的值, 其中有用于修改值或回退到替代值的选项。
+ 分部视图
+
+ 分部视图是可以在另一个模板内呈现的单独的模板文件,
+ 它对于重用标记或将复杂的模板分离到单独的文件中非常重要。
+ 母版
- 模板标签快速指南
+ 无主模板
+ 无主
+ 呈现子模板
+
+ @RenderBody().
+ ]]>
+
+ 定义命名节
+
+ @section { ... }. 这可以呈现在
+ 此模板的父级的特定区域, 请使用 @RenderSection.
+ ]]>
+
+ 呈现命名节
+
+ @RenderSection(name).
+ 这将呈现子模板的一个区域, 它被包装在相应的 @section [名称] {...} 定义中.
+ ]]>
+
+ 节名称
+ 节是必需的
+
+ 如果强制, 子模板必须包含 @section 定义, 否则将显示错误。
+
+ 查询生成器
+ 生成查询
+ 返回的项, 在
+ 我要
+ 所有内容
+ 类型 "%0%"的内容
+ from
+ 我的网站
+ where
+ and
+ is
+ is not
+ before
+ before (包含选定日期)
+ after
+ after (包含选定日期)
+ equals
+ does not equal
+ contains
+ does not contain
+ greater than
+ greater than or equal to
+ less than
+ less than or equal to
+ Id
+ Name
+ Created Date
+ Last Updated Date
+ order by
+ ascending
+ descending模板
+
选择内容类别选择一项布局
@@ -1043,15 +1251,12 @@
添加内容丢弃内容设置已应用
-
此处不允许有该内容此处允许有该内容
-
点击嵌入点击添加图片图片说明...在这里输入...
-
网格布局布局是网格编辑器的整体工作区域, 通常只需要一个或两个不同的布局添加网络布局
@@ -1060,18 +1265,13 @@
行是水平排列的预定义单元格添加行配置通过设置单元格宽度和添加其他单元格来调整行
-
列网格布局中的总和列数
-
设置配置编辑器可以更改的设置
-
样式配置编辑器可以更改的样式
-
输入的 json 配置有效, 设置才可保存
-
允许所有的编辑器允许所有行配置设置为默认值
@@ -1081,89 +1281,81 @@
-
- 组合
- 您没有添加任何选项卡
- 添加新选项卡
- 添加其他选项卡
- 继承自
- 添加属性
- 必需的标签
-
- 启用列表视图
- 配置内容项以显示其子项的可排序和搜索列表, 这些子项将不会显示在树中
-
- 允许的模板
- 选择允许在该类型的内容上使用哪些模板编辑器
-
- 允许作为根
- 允许编辑器在内容树的根目录中创建此类型的内容
- 是 - 允许根中的此类型的内容
-
- 允许的子节点类型
- 允许在该类型的内容下方创建指定类型的内容
-
- 选择子节点
-
- 从现有文档类型继承选项卡和属性。如果存在同名的选项卡, 则新选项卡将添加到当前文档类型或合并。
- 此内容类型在组合中使用, 因此不能自行组成。
- 没有可供组合使用的内容类型。
-
- 可用编辑器
- 重用
- 编辑器设置
-
- 配置
-
- 是,删除
-
- 被移动到下方
- 被复制到下面
- 选择要移动的文件夹
- 选择要复制的文件夹
- 在下面的树结构中
-
- 所有文档类型
- 所有文档
- 所有媒体项目
-
- 使用此文档类型将被永久删除, 请确认您还要删除这些文件。
- 使用此媒体类型将被永久删除, 请确认您也要删除这些。
- 使用此成员类型将被永久删除, 请确认您想要删除这些
-
- 和所有使用此类型的文档
- 和所有使用此类型的媒体项目
- 和使用此类型的所有成员
-
- 使用此编辑器将用新设置更新
-
- 成员可编辑
- 显示成员配置文件
-
+ 组合
+ 您没有添加任何选项卡
+ 添加新选项卡
+ 添加其他选项卡
+ 继承自
+ 添加属性
+ 必需的标签
+ 启用列表视图
+ 配置内容项以显示其子项的可排序和搜索列表, 这些子项将不会显示在树中
+ 允许的模板
+ 选择允许在该类型的内容上使用哪些模板编辑器
+ 允许作为根
+ 允许编辑器在内容树的根目录中创建此类型的内容
+ 是 - 允许根中的此类型的内容
+ 允许的子节点类型
+ 允许在该类型的内容下方创建指定类型的内容
+ 选择子节点
+ 从现有文档类型继承选项卡和属性。如果存在同名的选项卡, 则新选项卡将添加到当前文档类型或合并。
+ 此内容类型在组合中使用, 因此不能自行组成。
+ 没有可供组合使用的内容类型。
+ 可用编辑器
+ 重用
+ 编辑器设置
+ 配置
+ 是,删除
+ 被移动到下方
+ 被复制到下面
+ 选择要移动的文件夹
+ 选择要复制的文件夹
+ 在下面的树结构中
+ 所有文档类型
+ 所有文档
+ 所有媒体项目
+ 使用此文档类型将被永久删除, 请确认您还要删除这些文件。
+ 使用此媒体类型将被永久删除, 请确认您也要删除这些。
+ 使用此成员类型将被永久删除, 请确认您想要删除这些
+ 和所有使用此类型的文档
+ 和所有使用此类型的媒体项目
+ 和使用此类型的所有成员
+ 使用此编辑器将用新设置更新
+ 成员可编辑
+ 显示成员配置文件
+ 添加后备字段
+ 后备字段
+ 添加默认值
+ 默认值替代字段替代文本大小写
+ 编码选取字段转换换行符
+ 是, 转换换行符将换行符转化为<br>自定义字段是,仅日期
- 编码
+ 格式和编码格式化时间
+ 根据活动区域性将该值设置为日期或日期。HTML编码将替换HTML中的特殊字符将在字段值后插入将在字段值前插入小写
+ 修改输出无
+ 输出示例字段后插入字段前插入递归
- 移除段落符号
- 将移除<P>标签
+ 是, 让它递归
+ 分隔符标准字段大写URL编码
@@ -1174,10 +1366,12 @@
标记为您的任务
- 分配给您. 查看详情, 点击“详情”或页名。
+
+ 分配给您. 查看详情, 点击“详情”或页名。
如果需要XML格式,请点击“下载 XML”链接。
关闭翻译任务,请返回详细视图点击“关闭”按钮。
- ]]>
+ ]]>
+ 关闭任务翻译详情将翻译任务下载为xml
@@ -1185,7 +1379,8 @@
下载 XML DTD字段包含子页
-
+
+ ]]>
+
[%0%]翻译任务:%1%没有翻译员,请创建翻译员角色的用户。您创建的任务
- 您创建的页面. 查看详情, 点击“详情” 或页名.
+
+ 您创建的页面. 查看详情, 点击“详情” 或页名.
如果需要XML格式,请点击“下载 Xml”链接。
关闭翻译任务,请返回详细视图点击“关闭”按钮。
- ]]>
+ ]]>
+ 页面'%0%'已经发送给翻译请选择内容应翻译成的语言发送页面'%0%'以便翻译
@@ -1242,6 +1440,8 @@
关系类型扩展包扩展包
+ 分部视图
+ 分部视图宏文件Python文件从在线程序库安装安装Runway
@@ -1252,8 +1452,6 @@
模板XSLT文件分析
- 分部视图
- 分部视图宏文件有可用更新
@@ -1307,95 +1505,94 @@
会话过期于
- 验证
- 验证为电子邮件
- 验证为数字
- 验证为 url
- ...或输入自定义验证
- 字段是强制性的
+ 验证
+ 验证为电子邮件
+ 验证为数字
+ 验证为 url
+ ...或输入自定义验证
+ 字段是强制性的
+ 输入正则表达式
+ 您需要添加至少
+ 你只能有
+ 项
+ 选定的项
+ 无效日期
+ 不是一个数字
+ 无效的电子邮件
-
+
Value is set to the recommended value: '%0%'.
- Value was set to '%1%' for XPath '%2%' in configuration file '%3%'.
+ Value was set to '%1%' for XPath '%2%' in configuration file '%3%'.Expected value '%1%' for '%2%' in configuration file '%3%', but found '%0%'.Found unexpected value '%0%' for '%2%' in configuration file '%3%'.
-
- Custom errors are set to '%0%'.
- Custom errors are currently set to '%0%'. It is recommended to set this to '%1%' before go live.
- Custom errors successfully set to '%0%'.
+
+ Custom errors are set to '%0%'.
+ Custom errors are currently set to '%0%'. It is recommended to set this to '%1%' before go live.
+ Custom errors successfully set to '%0%'.
+ MacroErrors are set to '%0%'.
+ MacroErrors are set to '%0%' which will prevent some or all pages in your site from loading completely if there are any errors in macros. Rectifying this will set the value to '%1%'.
+ MacroErrors are now set to '%0%'.
- MacroErrors are set to '%0%'.
- MacroErrors are set to '%0%' which will prevent some or all pages in your site from loading completely if there are any errors in macros. Rectifying this will set the value to '%1%'.
- MacroErrors are now set to '%0%'.
+
+ Try Skip IIS Custom Errors is set to '%0%' and you're using IIS version '%1%'.
+ Try Skip IIS Custom Errors is currently '%0%'. It is recommended to set this to '%1%' for your IIS version (%2%).
+ Try Skip IIS Custom Errors successfully set to '%0%'.
-
- Try Skip IIS Custom Errors is set to '%0%' and you're using IIS version '%1%'.
- Try Skip IIS Custom Errors is currently '%0%'. It is recommended to set this to '%1%' for your IIS version (%2%).
- Try Skip IIS Custom Errors successfully set to '%0%'.
+
+ File does not exist: '%0%'.
+ '%0%' in config file '%1%'.]]>
+ There was an error, check log for full error: %0%.
+ Members - Total XML: %0%, Total: %1%, Total invalid: %2%
+ Media - Total XML: %0%, Total: %1%, Total invalid: %2%
+ Content - Total XML: %0%, Total published: %1%, Total invalid: %2%
+ Your site certificate was marked as valid.
+ Certificate validation error: '%0%'
+ Error pinging the URL %0% - '%1%'
+ You are currently %0% viewing the site using the HTTPS scheme.
+ The appSetting 'umbracoUseSSL' is set to 'false' in your web.config file. Once you access this site using the HTTPS scheme, that should be set to 'true'.
+ The appSetting 'umbracoUseSSL' is set to '%0%' in your web.config file, your cookies are %1% marked as secure.
+ Could not update the 'umbracoUseSSL' setting in your web.config file. Error: %0%
-
- File does not exist: '%0%'.
- '%0%' in config file '%1%'.]]>
- There was an error, check log for full error: %0%.
-
- Members - Total XML: %0%, Total: %1%, Total invalid: %2%
- Media - Total XML: %0%, Total: %1%, Total invalid: %2%
- Content - Total XML: %0%, Total published: %1%, Total invalid: %2%
-
- Your site certificate was marked as valid.
- Certificate validation error: '%0%'
- Error pinging the URL %0% - '%1%'
- You are currently %0% viewing the site using the HTTPS scheme.
- The appSetting 'umbracoUseSSL' is set to 'false' in your web.config file. Once you access this site using the HTTPS scheme, that should be set to 'true'.
- The appSetting 'umbracoUseSSL' is set to '%0%' in your web.config file, your cookies are %1% marked as secure.
- Could not update the 'umbracoUseSSL' setting in your web.config file. Error: %0%
-
-
- Enable HTTPS
- Sets umbracoSSL setting to true in the appSettings of the web.config file.
- The appSetting 'umbracoUseSSL' is now set to 'true' in your web.config file, your cookies will be marked as secure.
-
- Fix
+
+ Enable HTTPS
+ Sets umbracoSSL setting to true in the appSettings of the web.config file.
+ The appSetting 'umbracoUseSSL' is now set to 'true' in your web.config file, your cookies will be marked as secure.
+ FixCannot fix a check with a value comparison type of 'ShouldNotEqual'.Cannot fix a check with a value comparison type of 'ShouldEqual' with a provided value.Value to fix check not provided.
-
- Debug compilation mode is disabled.
- Debug compilation mode is currently enabled. It is recommended to disable this setting before go live.
- Debug compilation mode successfully disabled.
-
- Trace mode is disabled.
- Trace mode is currently enabled. It is recommended to disable this setting before go live.
- Trace mode successfully disabled.
-
+ Debug compilation mode is disabled.
+ Debug compilation mode is currently enabled. It is recommended to disable this setting before go live.
+ Debug compilation mode successfully disabled.
+ Trace mode is disabled.
+ Trace mode is currently enabled. It is recommended to disable this setting before go live.
+ Trace mode successfully disabled.All folders have the correct permissions set.
+ 0: Comma delimitted list of failed folder paths
+ -->
%0%.]]>%0%. If they aren't being written to no action need be taken.]]>
-
All files have the correct permissions set.
+ 0: Comma delimitted list of failed folder paths
+ -->
%0%.]]>%0%. If they aren't being written to no action need be taken.]]>
-
X-Frame-Options used to control whether a site can be IFRAMEd by another was found.]]>X-Frame-Options used to control whether a site can be IFRAMEd by another was not found.]]>Set Header in Config
@@ -1404,16 +1601,14 @@
Could not update web.config file. Error: %0%
+ 0: Comma delimitted list of headers found
+ -->
%0%.]]>No headers revealing information about the website technology were found.
-
In the Web.config file, system.net/mailsettings could not be found.In the Web.config file system.net/mailsettings section, the host is not configured.SMTP settings are configured correctly and the service is operating as expected.The SMTP server configured with host '%0%' and port '%1%' could not be reached. Please check to ensure the SMTP settings in the Web.config file system.net/mailsettings are correct.
-
%0%.]]>%0%.]]>
@@ -1434,4 +1629,7 @@
现在已启用 url 跟踪程序。启用 url 跟踪程序时出错, 可以在日志文件中找到更多信息。
+
+ 没有可供选择的词典项目
+
diff --git a/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs b/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs
index 6b001d24fa..1aaa52a3f4 100644
--- a/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs
+++ b/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs
@@ -113,7 +113,7 @@ namespace Umbraco.Web.Cache
}
TagsValueConverter.ClearCaches();
- MultipleMediaPickerPropertyConverter.ClearCaches();
+ LegacyMediaPickerPropertyConverter.ClearCaches();
SliderValueConverter.ClearCaches();
MediaPickerPropertyConverter.ClearCaches();
diff --git a/src/Umbraco.Web/Editors/MediaTypeController.cs b/src/Umbraco.Web/Editors/MediaTypeController.cs
index 879ffd3d0a..32d3ba6f34 100644
--- a/src/Umbraco.Web/Editors/MediaTypeController.cs
+++ b/src/Umbraco.Web/Editors/MediaTypeController.cs
@@ -230,7 +230,7 @@ namespace Umbraco.Web.Editors
basic.Description = TranslateItem(basic.Description);
}
- return basics;
+ return basics.OrderBy(x => x.Name);
}
///
diff --git a/src/Umbraco.Web/HealthCheck/Checks/Security/HttpsCheck.cs b/src/Umbraco.Web/HealthCheck/Checks/Security/HttpsCheck.cs
index 4e2dc4f8f5..b50fc99a6e 100644
--- a/src/Umbraco.Web/HealthCheck/Checks/Security/HttpsCheck.cs
+++ b/src/Umbraco.Web/HealthCheck/Checks/Security/HttpsCheck.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Net;
+using System.Security.Cryptography.X509Certificates;
using System.Web;
using Umbraco.Core.IO;
using Umbraco.Core.Services;
@@ -53,7 +54,7 @@ namespace Umbraco.Web.HealthCheck.Checks.Security
private HealthCheckStatus CheckForValidCertificate()
{
var message = string.Empty;
- var success = false;
+ StatusResultType result;
var url = HealthCheckContext.HttpContext.Request.Url;
// Attempt to access the site over HTTPS to see if it HTTPS is supported
@@ -65,7 +66,37 @@ namespace Umbraco.Web.HealthCheck.Checks.Security
try
{
var response = (HttpWebResponse)request.GetResponse();
- success = response.StatusCode == HttpStatusCode.OK;
+ if (response.StatusCode == HttpStatusCode.OK)
+ {
+ // Got a valid response, check now for if certificate expiring within 14 days
+ // Hat-tip: https://stackoverflow.com/a/15343898/489433
+ const int NumberOfDaysForExpiryWarning = 14;
+ var cert = request.ServicePoint.Certificate;
+ var cert2 = new X509Certificate2(cert);
+ var expirationDate = cert2.NotAfter;
+
+ var daysToExpiry = (int)Math.Floor((cert2.NotAfter - DateTime.Now).TotalDays);
+ if (daysToExpiry <= 0)
+ {
+ result = StatusResultType.Error;
+ message = _textService.Localize("healthcheck/httpsCheckExpiredCertificate");
+ }
+ else if (daysToExpiry < NumberOfDaysForExpiryWarning)
+ {
+ result = StatusResultType.Warning;
+ message = _textService.Localize("healthcheck/httpsCheckExpiringCertificate", new[] { daysToExpiry.ToString() });
+ }
+ else
+ {
+ result = StatusResultType.Success;
+ message = _textService.Localize("healthcheck/httpsCheckValidCertificate");
+ }
+ }
+ else
+ {
+ result = StatusResultType.Error;
+ message = _textService.Localize("healthcheck/httpsCheckInvalidUrl", new[] { address, response.StatusDescription });
+ }
}
catch (Exception ex)
{
@@ -80,17 +111,16 @@ namespace Umbraco.Web.HealthCheck.Checks.Security
{
message = _textService.Localize("healthcheck/httpsCheckInvalidUrl", new[] { address, ex.Message });
}
+
+ result = StatusResultType.Error;
}
var actions = new List();
- if (success)
- message = _textService.Localize("healthcheck/httpsCheckValidCertificate");
-
return
new HealthCheckStatus(message)
{
- ResultType = success ? StatusResultType.Success : StatusResultType.Error,
+ ResultType = result,
Actions = actions
};
}
diff --git a/src/Umbraco.Web/Models/ImageCropDataSet.cs b/src/Umbraco.Web/Models/ImageCropDataSet.cs
index 4c5a68a6b9..00f46dd2d7 100644
--- a/src/Umbraco.Web/Models/ImageCropDataSet.cs
+++ b/src/Umbraco.Web/Models/ImageCropDataSet.cs
@@ -76,7 +76,7 @@ namespace Umbraco.Web.Models
public bool HasImage()
{
- return string.IsNullOrEmpty(Src);
+ return ! string.IsNullOrEmpty(Src);
}
public string ToHtmlString()
diff --git a/src/Umbraco.Web/Models/Mapping/TabsAndPropertiesResolver.cs b/src/Umbraco.Web/Models/Mapping/TabsAndPropertiesResolver.cs
index 0671f59273..1722eecf79 100644
--- a/src/Umbraco.Web/Models/Mapping/TabsAndPropertiesResolver.cs
+++ b/src/Umbraco.Web/Models/Mapping/TabsAndPropertiesResolver.cs
@@ -165,12 +165,20 @@ namespace Umbraco.Web.Models.Mapping
var listViewTab = new Tab();
listViewTab.Alias = Constants.Conventions.PropertyGroups.ListViewGroupName;
listViewTab.Label = localizedTextService.Localize("content/childItems");
- listViewTab.Id = 25;
+ listViewTab.Id = display.Tabs.Count() + 1;
listViewTab.IsActive = true;
var listViewConfig = editor.PreValueEditor.ConvertDbToEditor(editor.DefaultPreValues, preVals);
//add the entity type to the config
- listViewConfig["entityType"] = entityType;
+ listViewConfig["entityType"] = entityType;
+
+ //Override Tab Label if tabName is provided
+ if (listViewConfig.ContainsKey("tabName"))
+ {
+ var configTabName = listViewConfig["tabName"];
+ if (configTabName != null && string.IsNullOrWhiteSpace(configTabName.ToString()) == false)
+ listViewTab.Label = configTabName.ToString();
+ }
var listViewProperties = new List();
listViewProperties.Add(new ContentPropertyDisplay
diff --git a/src/Umbraco.Web/PropertyEditors/ListViewPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/ListViewPropertyEditor.cs
index f744e4d807..2ee208ed48 100644
--- a/src/Umbraco.Web/PropertyEditors/ListViewPropertyEditor.cs
+++ b/src/Umbraco.Web/PropertyEditors/ListViewPropertyEditor.cs
@@ -42,7 +42,7 @@ namespace Umbraco.Web.PropertyEditors
allowBulkPublish = true,
allowBulkUnpublish = true,
allowBulkCopy = true,
- allowBulkMove = true,
+ allowBulkMove = false,
allowBulkDelete = true
}}
};
@@ -50,7 +50,10 @@ namespace Umbraco.Web.PropertyEditors
}
internal class ListViewPreValueEditor : PreValueEditor
- {
+ {
+ [PreValueField("tabName", "Tab Name", "textstring", Description = "The name of the listview tab (default if empty: 'Child Items')")]
+ public int TabName { get; set; }
+
[PreValueField("displayAtTabNumber", "Display At Tab Number", "number", Description = "Which tab position that the list of child items will be displayed")]
public int DisplayAtTabNumber { get; set; }
diff --git a/src/Umbraco.Web/PropertyEditors/TextAreaPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/TextAreaPropertyEditor.cs
index 3bec23f004..7006befdcd 100644
--- a/src/Umbraco.Web/PropertyEditors/TextAreaPropertyEditor.cs
+++ b/src/Umbraco.Web/PropertyEditors/TextAreaPropertyEditor.cs
@@ -6,5 +6,15 @@ namespace Umbraco.Web.PropertyEditors
[PropertyEditor(Constants.PropertyEditors.TextboxMultipleAlias, "Textarea", "textarea", IsParameterEditor = true, ValueType = PropertyEditorValueTypes.Text, Icon="icon-application-window-alt")]
public class TextAreaPropertyEditor : PropertyEditor
{
+ protected override PreValueEditor CreatePreValueEditor()
+ {
+ return new TextAreaPreValueEditor();
+ }
+
+ internal class TextAreaPreValueEditor : PreValueEditor
+ {
+ [PreValueField("maxChars", "Maximum allowed characters", "number", Description = "If empty - no character limit")]
+ public bool MaxChars { get; set; }
+ }
}
}
diff --git a/src/Umbraco.Web/PropertyEditors/TextboxPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/TextboxPropertyEditor.cs
index bcfbbbf682..0fd243180c 100644
--- a/src/Umbraco.Web/PropertyEditors/TextboxPropertyEditor.cs
+++ b/src/Umbraco.Web/PropertyEditors/TextboxPropertyEditor.cs
@@ -12,6 +12,19 @@ namespace Umbraco.Web.PropertyEditors
{
[PropertyEditor(Constants.PropertyEditors.TextboxAlias, "Textbox", "textbox", IsParameterEditor = true, Group = "Common")]
public class TextboxPropertyEditor : PropertyEditor
- {
+ {
+
+
+ protected override PreValueEditor CreatePreValueEditor()
+ {
+ return new TextboxPreValueEditor();
+ }
+
+ internal class TextboxPreValueEditor : PreValueEditor
+ {
+ [PreValueField("maxChars", "Maximum allowed characters", "number", Description = "If empty - no character limit")]
+ public bool MaxChars { get; set; }
+ }
+
}
}
diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/MultipleMediaPickerPropertyConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/LegacyMediaPickerPropertyConverter.cs
similarity index 90%
rename from src/Umbraco.Web/PropertyEditors/ValueConverters/MultipleMediaPickerPropertyConverter.cs
rename to src/Umbraco.Web/PropertyEditors/ValueConverters/LegacyMediaPickerPropertyConverter.cs
index 161e7178e7..8ef11bec8d 100644
--- a/src/Umbraco.Web/PropertyEditors/ValueConverters/MultipleMediaPickerPropertyConverter.cs
+++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/LegacyMediaPickerPropertyConverter.cs
@@ -1,5 +1,5 @@
// --------------------------------------------------------------------------------------------------------------------
-//
+//
// Umbraco
//
//
@@ -24,20 +24,20 @@ using Umbraco.Core.Services;
namespace Umbraco.Web.PropertyEditors.ValueConverters
{
///
- /// The multiple media picker property value converter.
+ /// The multiple media picker and double legacy media picker property value converter, should be deleted for v8
///
[DefaultPropertyValueConverter(typeof(MustBeStringValueConverter))]
- public class MultipleMediaPickerPropertyConverter : PropertyValueConverterBase, IPropertyValueConverterMeta
+ public class LegacyMediaPickerPropertyConverter : PropertyValueConverterBase, IPropertyValueConverterMeta
{
private readonly IDataTypeService _dataTypeService;
//TODO: Remove this ctor in v8 since the other one will use IoC
- public MultipleMediaPickerPropertyConverter()
+ public LegacyMediaPickerPropertyConverter()
: this(ApplicationContext.Current.Services.DataTypeService)
{
}
- public MultipleMediaPickerPropertyConverter(IDataTypeService dataTypeService)
+ public LegacyMediaPickerPropertyConverter(IDataTypeService dataTypeService)
{
if (dataTypeService == null) throw new ArgumentNullException("dataTypeService");
_dataTypeService = dataTypeService;
@@ -54,10 +54,17 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
///
public override bool IsConverter(PublishedPropertyType propertyType)
{
- if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters)
+ if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters && propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.MultipleMediaPickerAlias))
{
- return propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.MultipleMediaPickerAlias);
+ return true;
}
+
+ if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters && propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.MediaPickerAlias))
+ {
+ // this is the double legacy media picker, it can pick only single media items
+ return true;
+ }
+
return false;
}
@@ -109,7 +116,7 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
ApplicationContext.Current.Services.DataTypeService.GetDataTypeDefinitionById(
propertyType.DataTypeId).Name);
- LogHelper.Warn(error);
+ LogHelper.Warn(error);
throw new Exception(error);
}
}
@@ -264,4 +271,4 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
Storages.Clear();
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerPropertyConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerPropertyConverter.cs
index 5f54363975..2e9d0c7d96 100644
--- a/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerPropertyConverter.cs
+++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerPropertyConverter.cs
@@ -126,10 +126,6 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
if (propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.MediaPicker2Alias))
return true;
- if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters)
- {
- return propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.MediaPickerAlias);
- }
return false;
}
diff --git a/src/Umbraco.Web/PublishedContentExtensions.cs b/src/Umbraco.Web/PublishedContentExtensions.cs
index 36d1306ab6..38666dadb9 100644
--- a/src/Umbraco.Web/PublishedContentExtensions.cs
+++ b/src/Umbraco.Web/PublishedContentExtensions.cs
@@ -10,6 +10,7 @@ using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.Services;
using Umbraco.Web.Models;
using Umbraco.Core;
+using Umbraco.Core.Logging;
using Umbraco.Web.Routing;
using ContentType = umbraco.cms.businesslogic.ContentType;
@@ -24,8 +25,24 @@ namespace Umbraco.Web
public static Guid GetKey(this IPublishedContent content)
{
+ // fast
var contentWithKey = content as IPublishedContentWithKey;
- return contentWithKey == null ? Guid.Empty : contentWithKey.Key;
+ if (contentWithKey != null) return contentWithKey.Key;
+
+ // try to unwrap (models...)
+ var contentWrapped = content as PublishedContentWrapped;
+ while (contentWrapped != null)
+ {
+ content = contentWrapped.Unwrap();
+ contentWrapped = content as PublishedContentWrapped;
+ }
+
+ // again
+ contentWithKey = content as IPublishedContentWithKey;
+ if (contentWithKey != null) return contentWithKey.Key;
+
+ LogHelper.Debug(typeof(PublishedContentExtensions), string.Format("Could not get key for IPublishedContent with id {0} of type {1}.", content.Id, content.GetType().FullName));
+ return Guid.Empty;
}
#endregion
@@ -634,14 +651,10 @@ namespace Umbraco.Web
private static bool IsDocumentTypeRecursive(IPublishedContent content, string docTypeAlias)
{
var contentTypeService = UmbracoContext.Current.Application.Services.ContentTypeService;
- var type = contentTypeService.GetContentType(content.DocumentTypeAlias);
- while (type != null && type.ParentId > 0)
- {
- type = contentTypeService.GetContentType(type.ParentId);
- if (type.Alias.InvariantEquals(docTypeAlias))
- return true;
- }
- return false;
+ var type = contentTypeService.GetContentType(content.DocumentTypeAlias);
+ if (type.Alias.InvariantEquals(docTypeAlias) || content.IsComposedOf(docTypeAlias))
+ return true;
+ return false;
}
public static bool IsNull(this IPublishedContent content, string alias, bool recurse)
@@ -912,14 +925,14 @@ namespace Umbraco.Web
#region Axes: ancestors, ancestors-or-self
- // as per XPath 1.0 specs 2.2,
+ // as per XPath 1.0 specs §2.2,
// - the ancestor axis contains the ancestors of the context node; the ancestors of the context node consist
// of the parent of context node and the parent's parent and so on; thus, the ancestor axis will always
// include the root node, unless the context node is the root node.
// - the ancestor-or-self axis contains the context node and the ancestors of the context node; thus,
// the ancestor axis will always include the root node.
//
- // as per XPath 2.0 specs 3.2.1.1,
+ // as per XPath 2.0 specs §3.2.1.1,
// - the ancestor axis is defined as the transitive closure of the parent axis; it contains the ancestors
// of the context node (the parent, the parent of the parent, and so on) - The ancestor axis includes the
// root node of the tree in which the context node is found, unless the context node is the root node.
@@ -929,7 +942,7 @@ namespace Umbraco.Web
// the ancestor and ancestor-or-self axis are reverse axes ie they contain the context node or nodes that
// are before the context node in document order.
//
- // document order is defined by 2.4.1 as:
+ // document order is defined by §2.4.1 as:
// - the root node is the first node.
// - every node occurs before all of its children and descendants.
// - the relative order of siblings is the order in which they occur in the children property of their parent node.
@@ -1240,12 +1253,12 @@ namespace Umbraco.Web
}
- // as per XPath 1.0 specs 2.2,
+ // as per XPath 1.0 specs §2.2,
// - the descendant axis contains the descendants of the context node; a descendant is a child or a child of a child and so on; thus
// the descendant axis never contains attribute or namespace nodes.
// - the descendant-or-self axis contains the context node and the descendants of the context node.
//
- // as per XPath 2.0 specs 3.2.1.1,
+ // as per XPath 2.0 specs §3.2.1.1,
// - the descendant axis is defined as the transitive closure of the child axis; it contains the descendants of the context node (the
// children, the children of the children, and so on).
// - the descendant-or-self axis contains the context node and the descendants of the context node.
@@ -1253,7 +1266,7 @@ namespace Umbraco.Web
// the descendant and descendant-or-self axis are forward axes ie they contain the context node or nodes that are after the context
// node in document order.
//
- // document order is defined by 2.4.1 as:
+ // document order is defined by §2.4.1 as:
// - the root node is the first node.
// - every node occurs before all of its children and descendants.
// - the relative order of siblings is the order in which they occur in the children property of their parent node.
diff --git a/src/Umbraco.Web/Routing/UrlProviderExtensions.cs b/src/Umbraco.Web/Routing/UrlProviderExtensions.cs
index 54ef8a42b5..d464b8962e 100644
--- a/src/Umbraco.Web/Routing/UrlProviderExtensions.cs
+++ b/src/Umbraco.Web/Routing/UrlProviderExtensions.cs
@@ -70,6 +70,7 @@ namespace Umbraco.Web.Routing
// test for collisions
var uri = new Uri(url.TrimEnd('/'), UriKind.RelativeOrAbsolute);
if (uri.IsAbsoluteUri == false) uri = uri.MakeAbsolute(UmbracoContext.Current.CleanedUmbracoUrl);
+ uri = UriUtility.UriToUmbraco(uri);
var pcr = new PublishedContentRequest(uri, UmbracoContext.Current.RoutingContext, UmbracoConfig.For.UmbracoSettings().WebRouting, s => Roles.Provider.GetRolesForUser(s));
pcr.Engine.TryRouteRequest();
diff --git a/src/Umbraco.Web/Security/Providers/UmbracoMembershipProvider.cs b/src/Umbraco.Web/Security/Providers/UmbracoMembershipProvider.cs
index 8482eb72a2..71e2b1d0f3 100644
--- a/src/Umbraco.Web/Security/Providers/UmbracoMembershipProvider.cs
+++ b/src/Umbraco.Web/Security/Providers/UmbracoMembershipProvider.cs
@@ -166,11 +166,11 @@ namespace Umbraco.Web.Security.Providers
username,
email,
FormatPasswordForStorage(encodedPassword, salt),
- memberTypeAlias);
+ memberTypeAlias,
+ isApproved);
member.PasswordQuestion = passwordQuestion;
member.RawPasswordAnswerValue = EncryptString(passwordAnswer);
- member.IsApproved = isApproved;
member.LastLoginDate = DateTime.Now;
member.LastPasswordChangeDate = DateTime.Now;
diff --git a/src/Umbraco.Web/Trees/FileSystemTreeController.cs b/src/Umbraco.Web/Trees/FileSystemTreeController.cs
index 54979990b7..0d612b5d4e 100644
--- a/src/Umbraco.Web/Trees/FileSystemTreeController.cs
+++ b/src/Umbraco.Web/Trees/FileSystemTreeController.cs
@@ -1,21 +1,18 @@
using System;
using System.IO;
-using System.Linq;
using System.Net.Http.Formatting;
using umbraco.BusinessLogic.Actions;
using Umbraco.Core;
using Umbraco.Core.IO;
-using Umbraco.Core.Services;
using Umbraco.Web.Models.Trees;
-using System.Web;
+using Umbraco.Core.Services;
namespace Umbraco.Web.Trees
{
public abstract class FileSystemTreeController : TreeController
{
- protected abstract IFileSystem2 FileSystem { get; }
- protected abstract string[] Extensions { get; }
- protected abstract string FileIcon { get; }
+ protected abstract string FilePath { get; }
+ protected abstract string FileSearchPattern { get; }
///
/// Inheritors can override this method to modify the file node that is created.
@@ -31,43 +28,67 @@ namespace Umbraco.Web.Trees
protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings)
{
- var path = string.IsNullOrEmpty(id) == false && id != Constants.System.Root.ToInvariantString()
- ? HttpUtility.UrlDecode(id).TrimStart("/")
- : "";
+ var orgPath = "";
+ string path;
+ if (string.IsNullOrEmpty(id) == false && id != "-1")
+ {
+ orgPath = id;
+ path = IOHelper.MapPath(FilePath + "/" + orgPath);
+ orgPath += "/";
+ }
+ else
+ {
+ path = IOHelper.MapPath(FilePath);
+ }
- var directories = FileSystem.GetDirectories(path);
+ var dirInfo = new DirectoryInfo(path);
+ var dirInfos = dirInfo.GetDirectories();
var nodes = new TreeNodeCollection();
- foreach (var directory in directories)
+ foreach (var dir in dirInfos)
{
- var hasChildren = FileSystem.GetFiles(directory).Any() || FileSystem.GetDirectories(directory).Any();
+ if ((dir.Attributes & FileAttributes.Hidden) != 0)
+ continue;
+
+ var hasChildren = dir.GetFiles().Length > 0 || dir.GetDirectories().Length > 0;
+ var node = CreateTreeNode(orgPath + dir.Name, orgPath, queryStrings, dir.Name, "icon-folder", hasChildren);
- var name = Path.GetFileName(directory);
- var node = CreateTreeNode(HttpUtility.UrlEncode(directory), path, queryStrings, name, "icon-folder", hasChildren);
OnRenderFolderNode(ref node);
- if(node != null)
+ if (node != null)
nodes.Add(node);
}
//this is a hack to enable file system tree to support multiple file extension look-up
//so the pattern both support *.* *.xml and xml,js,vb for lookups
- var files = FileSystem.GetFiles(path).Where(x =>
- {
- var extension = Path.GetExtension(x);
- return extension != null && Extensions.Contains(extension.Trim('.'), StringComparer.InvariantCultureIgnoreCase);
- });
+ var allowedExtensions = new string[0];
+ var filterByMultipleExtensions = FileSearchPattern.Contains(",");
+ FileInfo[] fileInfo;
- foreach (var file in files)
- {
- var withoutExt = Path.GetFileNameWithoutExtension(file);
- if (withoutExt.IsNullOrWhiteSpace() == false)
- {
- var name = Path.GetFileName(file);
- var node = CreateTreeNode(HttpUtility.UrlEncode(file), path, queryStrings, name, FileIcon, false);
- OnRenderFileNode(ref node);
- if (node != null)
- nodes.Add(node);
- }
+ if (filterByMultipleExtensions)
+ {
+ fileInfo = dirInfo.GetFiles();
+ allowedExtensions = FileSearchPattern.ToLower().Split(',');
+ }
+ else
+ fileInfo = dirInfo.GetFiles(FileSearchPattern);
+
+ foreach (var file in fileInfo)
+ {
+ if ((file.Attributes & FileAttributes.Hidden) != 0)
+ continue;
+
+ if (filterByMultipleExtensions && Array.IndexOf(allowedExtensions, file.Extension.ToLower().Trim('.')) < 0)
+ continue;
+
+ var withoutExt = Path.GetFileNameWithoutExtension(file.Name);
+ if (withoutExt.IsNullOrWhiteSpace())
+ continue;
+
+ var node = CreateTreeNode(orgPath + file.Name, orgPath, queryStrings, file.Name, "icon-file", false);
+
+ OnRenderFileNode(ref node);
+ if (node != null)
+ nodes.Add(node);
}
return nodes;
@@ -90,22 +111,27 @@ namespace Umbraco.Web.Trees
return menu;
}
- var path = string.IsNullOrEmpty(id) == false && id != Constants.System.Root.ToInvariantString()
- ? System.Web.HttpUtility.UrlDecode(id).TrimStart("/")
- : "";
+ string path;
+ if (string.IsNullOrEmpty(id) == false)
+ {
+ var orgPath = System.Web.HttpUtility.UrlDecode(id);
+ path = IOHelper.MapPath(FilePath + "/" + orgPath);
+ }
+ else
+ {
+ path = IOHelper.MapPath(FilePath);
+ }
- var isFile = FileSystem.FileExists(path);
- var isDirectory = FileSystem.DirectoryExists(path);
-
- if (isDirectory)
+ var dirInfo = new DirectoryInfo(path);
+ //check if it's a directory
+ if (dirInfo.Attributes == FileAttributes.Directory)
{
//set the default to create
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
//create action
menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionNew.Instance.Alias)));
-
- var hasChildren = FileSystem.GetFiles(path).Any() || FileSystem.GetDirectories(path).Any();
-
+
+ var hasChildren = dirInfo.GetFiles().Length > 0 || dirInfo.GetDirectories().Length > 0;
//We can only delete folders if it doesn't have any children (folders or files)
if (hasChildren == false)
{
@@ -116,9 +142,10 @@ namespace Umbraco.Web.Trees
//refresh action
menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionRefresh.Instance.Alias)), true);
}
- else if (isFile)
+ //if it's not a directory then we only allow to delete the item
+ else
{
- //if it's not a directory then we only allow to delete the item
+ //delete action
menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionDelete.Instance.Alias)));
}
diff --git a/src/Umbraco.Web/Trees/FileSystemTreeController2.cs b/src/Umbraco.Web/Trees/FileSystemTreeController2.cs
new file mode 100644
index 0000000000..d43d68ee77
--- /dev/null
+++ b/src/Umbraco.Web/Trees/FileSystemTreeController2.cs
@@ -0,0 +1,127 @@
+using System;
+using System.IO;
+using System.Linq;
+using System.Net.Http.Formatting;
+using umbraco.BusinessLogic.Actions;
+using Umbraco.Core;
+using Umbraco.Core.IO;
+using Umbraco.Core.Services;
+using Umbraco.Web.Models.Trees;
+using System.Web;
+
+namespace Umbraco.Web.Trees
+{
+ public abstract class FileSystemTreeController2 : TreeController
+ {
+ protected abstract IFileSystem2 FileSystem { get; }
+ protected abstract string[] Extensions { get; }
+ protected abstract string FileIcon { get; }
+
+ ///
+ /// Inheritors can override this method to modify the file node that is created.
+ ///
+ ///
+ protected virtual void OnRenderFileNode(ref TreeNode treeNode) { }
+
+ ///
+ /// Inheritors can override this method to modify the folder node that is created.
+ ///
+ ///
+ protected virtual void OnRenderFolderNode(ref TreeNode treeNode) { }
+
+ protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings)
+ {
+ var path = string.IsNullOrEmpty(id) == false && id != Constants.System.Root.ToInvariantString()
+ ? HttpUtility.UrlDecode(id).TrimStart("/")
+ : "";
+
+ var directories = FileSystem.GetDirectories(path);
+
+ var nodes = new TreeNodeCollection();
+ foreach (var directory in directories)
+ {
+ var hasChildren = FileSystem.GetFiles(directory).Any() || FileSystem.GetDirectories(directory).Any();
+
+ var name = Path.GetFileName(directory);
+ var node = CreateTreeNode(HttpUtility.UrlEncode(directory), path, queryStrings, name, "icon-folder", hasChildren);
+ OnRenderFolderNode(ref node);
+ if(node != null)
+ nodes.Add(node);
+ }
+
+ //this is a hack to enable file system tree to support multiple file extension look-up
+ //so the pattern both support *.* *.xml and xml,js,vb for lookups
+ var files = FileSystem.GetFiles(path).Where(x =>
+ {
+ var extension = Path.GetExtension(x);
+ return extension != null && Extensions.Contains(extension.Trim('.'), StringComparer.InvariantCultureIgnoreCase);
+ });
+
+ foreach (var file in files)
+ {
+ var withoutExt = Path.GetFileNameWithoutExtension(file);
+ if (withoutExt.IsNullOrWhiteSpace()) continue;
+
+ var name = Path.GetFileName(file);
+ var node = CreateTreeNode(HttpUtility.UrlEncode(file), path, queryStrings, name, FileIcon, false);
+ OnRenderFileNode(ref node);
+ if (node != null)
+ nodes.Add(node);
+ }
+
+ return nodes;
+ }
+
+ protected override MenuItemCollection GetMenuForNode(string id, FormDataCollection queryStrings)
+ {
+ var menu = new MenuItemCollection();
+
+ //if root node no need to visit the filesystem so lets just create the menu and return it
+ if (id == Constants.System.Root.ToInvariantString())
+ {
+ //set the default to create
+ menu.DefaultMenuAlias = ActionNew.Instance.Alias;
+ //create action
+ menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionNew.Instance.Alias)));
+ //refresh action
+ menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionRefresh.Instance.Alias)), true);
+
+ return menu;
+ }
+
+ var path = string.IsNullOrEmpty(id) == false && id != Constants.System.Root.ToInvariantString()
+ ? HttpUtility.UrlDecode(id).TrimStart("/")
+ : "";
+
+ var isFile = FileSystem.FileExists(path);
+ var isDirectory = FileSystem.DirectoryExists(path);
+
+ if (isDirectory)
+ {
+ //set the default to create
+ menu.DefaultMenuAlias = ActionNew.Instance.Alias;
+ //create action
+ menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionNew.Instance.Alias)));
+
+ var hasChildren = FileSystem.GetFiles(path).Any() || FileSystem.GetDirectories(path).Any();
+
+ //We can only delete folders if it doesn't have any children (folders or files)
+ if (hasChildren == false)
+ {
+ //delete action
+ menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionDelete.Instance.Alias)), true);
+ }
+
+ //refresh action
+ menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionRefresh.Instance.Alias)), true);
+ }
+ else if (isFile)
+ {
+ //if it's not a directory then we only allow to delete the item
+ menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionDelete.Instance.Alias)));
+ }
+
+ return menu;
+ }
+ }
+}
diff --git a/src/Umbraco.Web/Trees/PartialViewMacrosTreeController.cs b/src/Umbraco.Web/Trees/PartialViewMacrosTreeController.cs
index b4cc2eb2fd..ba4724aead 100644
--- a/src/Umbraco.Web/Trees/PartialViewMacrosTreeController.cs
+++ b/src/Umbraco.Web/Trees/PartialViewMacrosTreeController.cs
@@ -7,15 +7,15 @@ namespace Umbraco.Web.Trees
///
/// Tree for displaying partial view macros in the developer app
///
- [Tree(Constants.Applications.Developer, "partialViewMacros", "Partial View Macro Files", sortOrder: 6)]
- public class PartialViewMacrosTreeController : FileSystemTreeController
+ [Tree(Constants.Applications.Developer, "partialViewMacros", null, sortOrder: 6)]
+ public class PartialViewMacrosTreeController : FileSystemTreeController2
{
protected override IFileSystem2 FileSystem
{
get { return FileSystemProviderManager.Current.MacroPartialsFileSystem; }
}
- private static readonly string[] ExtensionsStatic = { "cshtml" };
+ private static readonly string[] ExtensionsStatic = {"cshtml"};
protected override string[] Extensions
{
diff --git a/src/Umbraco.Web/Trees/PartialViewsTreeController.cs b/src/Umbraco.Web/Trees/PartialViewsTreeController.cs
index 264b44ad73..bf4ec65a2e 100644
--- a/src/Umbraco.Web/Trees/PartialViewsTreeController.cs
+++ b/src/Umbraco.Web/Trees/PartialViewsTreeController.cs
@@ -7,15 +7,15 @@ namespace Umbraco.Web.Trees
///
/// Tree for displaying partial views in the settings app
///
- [Tree(Constants.Applications.Settings, "partialViews", "Partial Views", sortOrder: 2)]
- public class PartialViewsTreeController : FileSystemTreeController
+ [Tree(Constants.Applications.Settings, "partialViews", null, sortOrder: 2)]
+ public class PartialViewsTreeController : FileSystemTreeController2
{
- protected override IFileSystem2 FileSystem
- {
- get { return FileSystemProviderManager.Current.PartialViewsFileSystem; }
- }
+ protected override IFileSystem2 FileSystem
+ {
+ get { return FileSystemProviderManager.Current.PartialViewsFileSystem; }
+ }
- private static readonly string[] ExtensionsStatic = { "cshtml" };
+ private static readonly string[] ExtensionsStatic = {"cshtml"};
protected override string[] Extensions
{
diff --git a/src/Umbraco.Web/Trees/ScriptTreeController.cs b/src/Umbraco.Web/Trees/ScriptTreeController.cs
index 616106a625..cb9954019b 100644
--- a/src/Umbraco.Web/Trees/ScriptTreeController.cs
+++ b/src/Umbraco.Web/Trees/ScriptTreeController.cs
@@ -4,8 +4,8 @@ using Umbraco.Web.Models.Trees;
namespace Umbraco.Web.Trees
{
- [Tree(Constants.Applications.Settings, "scripts", "Scripts", sortOrder: 4)]
- public class ScriptTreeController : FileSystemTreeController
+ [Tree(Constants.Applications.Settings, "scripts", null, sortOrder: 4)]
+ public class ScriptTreeController : FileSystemTreeController2
{
protected override IFileSystem2 FileSystem
{
diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj
index cb51683498..7724f083a2 100644
--- a/src/Umbraco.Web/Umbraco.Web.csproj
+++ b/src/Umbraco.Web/Umbraco.Web.csproj
@@ -411,7 +411,7 @@
-
+
@@ -435,6 +435,7 @@
+
@@ -712,7 +713,7 @@
-
+
diff --git a/src/Umbraco.Web/UmbracoApplication.cs b/src/Umbraco.Web/UmbracoApplication.cs
index 0f6fc03b80..b9650a8230 100644
--- a/src/Umbraco.Web/UmbracoApplication.cs
+++ b/src/Umbraco.Web/UmbracoApplication.cs
@@ -34,9 +34,9 @@ namespace Umbraco.Web
var appPluginFolder = IOHelper.MapPath("~/App_Plugins/");
if (Directory.Exists(appPluginFolder))
{
- _mw = new ManifestWatcher(LoggerResolver.Current.Logger);
- _mw.Start(Directory.GetDirectories(IOHelper.MapPath("~/App_Plugins/")));
- }
+ _mw = new ManifestWatcher(LoggerResolver.Current.Logger);
+ _mw.Start(Directory.GetDirectories(appPluginFolder));
+ }
}
}
diff --git a/src/Umbraco.Web/umbraco.presentation/library.cs b/src/Umbraco.Web/umbraco.presentation/library.cs
index 38b8b1b95d..4ab89c5c7d 100644
--- a/src/Umbraco.Web/umbraco.presentation/library.cs
+++ b/src/Umbraco.Web/umbraco.presentation/library.cs
@@ -1393,15 +1393,25 @@ namespace umbraco
/// An XpathNodeIterator containing the current page as Xml.
public static XPathNodeIterator GetXmlNodeCurrent()
{
+ var pageId = "";
+
try
{
var nav = Umbraco.Web.UmbracoContext.Current.ContentCache.GetXPathNavigator();
- nav.MoveToId(HttpContext.Current.Items["pageID"].ToString());
+ var pageIdItem = HttpContext.Current.Items["pageID"];
+
+ if (pageIdItem == null)
+ {
+ throw new NullReferenceException("pageID not found in the current HTTP context");
+ }
+
+ pageId = pageIdItem.ToString();
+ nav.MoveToId(pageId);
return nav.Select(".");
}
catch (Exception ex)
{
- LogHelper.Error("Could not retrieve current xml node", ex);
+ LogHelper.Error(string.Concat("Could not retrieve current xml node for page Id ",pageId), ex);
}
XmlDocument xd = new XmlDocument();
diff --git a/src/Umbraco.Web/umbraco.presentation/macro.cs b/src/Umbraco.Web/umbraco.presentation/macro.cs
index 6d2936cd9a..dac3c0e1bf 100644
--- a/src/Umbraco.Web/umbraco.presentation/macro.cs
+++ b/src/Umbraco.Web/umbraco.presentation/macro.cs
@@ -46,6 +46,7 @@ using System.Linq;
using File = System.IO.File;
using MacroTypes = umbraco.cms.businesslogic.macro.MacroTypes;
using Member = umbraco.cms.businesslogic.member.Member;
+using UserControl = System.Web.UI.UserControl;
namespace umbraco
{
diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Macros/assemblyBrowser.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Macros/assemblyBrowser.aspx.cs
index d186d9ef50..273318cbff 100644
--- a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Macros/assemblyBrowser.aspx.cs
+++ b/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Macros/assemblyBrowser.aspx.cs
@@ -19,6 +19,7 @@ using Umbraco.Core.PropertyEditors;
using umbraco.BusinessLogic;
using System.Collections.Generic;
using MacroProperty = umbraco.cms.businesslogic.macro.MacroProperty;
+using UserControl = System.Web.UI.UserControl;
namespace umbraco.developer
{