mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-04-05 21:01:35 +08:00
Added ability to generate a simple theme from the command line
--HG-- branch : dev
This commit is contained in:
parent
5317183002
commit
e2bada7486
@ -0,0 +1,7 @@
|
|||||||
|
name: $$ThemeName$$
|
||||||
|
author: The Orchard Team
|
||||||
|
website: http://www.orchardproject.net
|
||||||
|
description: Description for the theme
|
||||||
|
version: 1.0
|
||||||
|
# todo: provide tags
|
||||||
|
# tags: Classic, Serif
|
@ -1,7 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using System.Web.Hosting;
|
using System.Web.Hosting;
|
||||||
using Orchard.Commands;
|
using Orchard.Commands;
|
||||||
using Orchard.Data.Migration.Generator;
|
using Orchard.Data.Migration.Generator;
|
||||||
@ -18,6 +20,7 @@ namespace Orchard.CodeGeneration.Commands {
|
|||||||
private readonly ISchemaCommandGenerator _schemaCommandGenerator;
|
private readonly ISchemaCommandGenerator _schemaCommandGenerator;
|
||||||
|
|
||||||
private const string ModuleName = "CodeGeneration";
|
private const string ModuleName = "CodeGeneration";
|
||||||
|
private static readonly string CodeGenTemplatePath = HostingEnvironment.MapPath("~/Modules/Orchard." + ModuleName + "/CodeGenerationTemplates/");
|
||||||
|
|
||||||
public CodeGenerationCommands(
|
public CodeGenerationCommands(
|
||||||
IExtensionManager extensionManager,
|
IExtensionManager extensionManager,
|
||||||
@ -29,6 +32,9 @@ namespace Orchard.CodeGeneration.Commands {
|
|||||||
[OrchardSwitch]
|
[OrchardSwitch]
|
||||||
public bool IncludeInSolution { get; set; }
|
public bool IncludeInSolution { get; set; }
|
||||||
|
|
||||||
|
[OrchardSwitch]
|
||||||
|
public string BasedOn { get; set; }
|
||||||
|
|
||||||
[CommandHelp("generate create datamigration <feature-name> \r\n\t" + "Create a new Data Migration class")]
|
[CommandHelp("generate create datamigration <feature-name> \r\n\t" + "Create a new Data Migration class")]
|
||||||
[CommandName("generate create datamigration")]
|
[CommandName("generate create datamigration")]
|
||||||
public void CreateDataMigration(string featureName) {
|
public void CreateDataMigration(string featureName) {
|
||||||
@ -95,7 +101,7 @@ namespace Orchard.CodeGeneration.Commands {
|
|||||||
public void CreateModule(string moduleName) {
|
public void CreateModule(string moduleName) {
|
||||||
Context.Output.WriteLine(T("Creating Module {0}", moduleName));
|
Context.Output.WriteLine(T("Creating Module {0}", moduleName));
|
||||||
|
|
||||||
if ( _extensionManager.AvailableExtensions().Any(extension => extension.ExtensionType == "Module" && String.Equals(moduleName, extension.DisplayName, StringComparison.OrdinalIgnoreCase)) ) {
|
if ( _extensionManager.AvailableExtensions().Any(extension => String.Equals(moduleName, extension.DisplayName, StringComparison.OrdinalIgnoreCase)) ) {
|
||||||
Context.Output.WriteLine(T("Creating Module {0} failed: a module of the same name already exists", moduleName));
|
Context.Output.WriteLine(T("Creating Module {0} failed: a module of the same name already exists", moduleName));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -104,6 +110,26 @@ namespace Orchard.CodeGeneration.Commands {
|
|||||||
Context.Output.WriteLine(T("Module {0} created successfully", moduleName));
|
Context.Output.WriteLine(T("Module {0} created successfully", moduleName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[CommandName("generate create theme")]
|
||||||
|
[CommandHelp("generate create theme <theme-name> [/IncludeInSolution:true|false][/BasedOn:<theme-name>]\r\n\tCreate a new Orchard theme")]
|
||||||
|
[OrchardSwitches("IncludeInSolution,BasedOn")]
|
||||||
|
public void CreateTheme(string themeName) {
|
||||||
|
Context.Output.WriteLine(T("Creating Theme {0}", themeName));
|
||||||
|
if (_extensionManager.AvailableExtensions().Any(extension => String.Equals(themeName, extension.DisplayName, StringComparison.OrdinalIgnoreCase))) {
|
||||||
|
Context.Output.WriteLine(base.T("Creating Theme {0} failed: an extention of the same name already exists", themeName));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
string baseThemePath = null;
|
||||||
|
if (!string.IsNullOrEmpty(BasedOn)) {
|
||||||
|
baseThemePath = HostingEnvironment.MapPath("~/Themes/" + BasedOn + "/");
|
||||||
|
if (string.IsNullOrEmpty(baseThemePath) || Directory.Exists(baseThemePath)) {
|
||||||
|
Context.Output.WriteLine(T("Creating Theme {0} failed: could not find base theme '{1}'", themeName, baseThemePath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IntegrateTheme(themeName, baseThemePath);
|
||||||
|
Context.Output.WriteLine(base.T("Theme {0} created successfully", new object[] {themeName}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[CommandHelp("generate create controller <module-name> <controller-name>\r\n\t" + "Create a new Orchard controller in a module")]
|
[CommandHelp("generate create controller <module-name> <controller-name>\r\n\t" + "Create a new Orchard controller in a module")]
|
||||||
[CommandName("generate create controller")]
|
[CommandName("generate create controller")]
|
||||||
@ -159,56 +185,134 @@ namespace Orchard.CodeGeneration.Commands {
|
|||||||
CreateFilesFromTemplates(moduleName, projectGuid);
|
CreateFilesFromTemplates(moduleName, projectGuid);
|
||||||
// The string searches in solution/project files can be made aware of comment lines.
|
// The string searches in solution/project files can be made aware of comment lines.
|
||||||
if (IncludeInSolution) {
|
if (IncludeInSolution) {
|
||||||
// Add project to Orchard.sln
|
AddToSolution(moduleName, projectGuid, null, null);
|
||||||
string solutionPath = Directory.GetParent(rootWebProjectPath).Parent.FullName + "\\Orchard.sln";
|
}
|
||||||
if (File.Exists(solutionPath)) {
|
}
|
||||||
string projectReference = string.Format(
|
|
||||||
"EndProject\r\nProject(\"{{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}}\") = \"{0}\", \"Orchard.Web\\Modules\\{0}\\{0}.csproj\", \"{{{1}}}\"\r\n",
|
|
||||||
moduleName, projectGuid);
|
|
||||||
string projectConfiguationPlatforms = string.Format(
|
|
||||||
"GlobalSection(ProjectConfigurationPlatforms) = postSolution\r\n\t\t{{{0}}}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{{{0}}}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{{{0}}}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{{{0}}}.Release|Any CPU.Build.0 = Release|Any CPU\r\n",
|
|
||||||
projectGuid);
|
|
||||||
string solutionText = File.ReadAllText(solutionPath);
|
|
||||||
solutionText = solutionText.Insert(solutionText.LastIndexOf("EndProject\r\n"), projectReference);
|
|
||||||
solutionText = solutionText.Replace("GlobalSection(ProjectConfigurationPlatforms) = postSolution\r\n", projectConfiguationPlatforms);
|
|
||||||
solutionText = solutionText.Insert(solutionText.LastIndexOf("EndGlobalSection"), "\t{" + projectGuid + "} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5}\r\n\t");
|
|
||||||
|
|
||||||
File.WriteAllText(solutionPath, solutionText);
|
private void IntegrateTheme(string themeName, string baseThemePath) {
|
||||||
TouchSolution();
|
HashSet<string> createdFiles;
|
||||||
}
|
HashSet<string> createdFolders;
|
||||||
else {
|
var projectGuid = Guid.NewGuid().ToString().ToUpper();
|
||||||
Context.Output.WriteLine(T("Warning: Solution file could not be found at {0}", solutionPath));
|
CreateThemeFromTemplates(themeName, baseThemePath, projectGuid, out createdFiles, out createdFolders);
|
||||||
}
|
if (IncludeInSolution) {
|
||||||
|
AddToSolution(themeName, null, createdFiles, createdFolders);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void CreateFilesFromTemplates(string moduleName, string projectGuid) {
|
private static void CreateFilesFromTemplates(string moduleName, string projectGuid) {
|
||||||
string modulePath = HostingEnvironment.MapPath("~/Modules/" + moduleName + "/");
|
string modulePath = HostingEnvironment.MapPath("~/Modules/" + moduleName + "/");
|
||||||
string propertiesPath = modulePath + "Properties";
|
string propertiesPath = modulePath + "Properties";
|
||||||
string templatesPath = HostingEnvironment.MapPath("~/Modules/Orchard." + ModuleName + "/CodeGenerationTemplates/");
|
|
||||||
|
|
||||||
Directory.CreateDirectory(modulePath);
|
Directory.CreateDirectory(modulePath);
|
||||||
Directory.CreateDirectory(propertiesPath);
|
Directory.CreateDirectory(propertiesPath);
|
||||||
Directory.CreateDirectory(modulePath + "Controllers");
|
Directory.CreateDirectory(modulePath + "Controllers");
|
||||||
Directory.CreateDirectory(modulePath + "Views");
|
Directory.CreateDirectory(modulePath + "Views");
|
||||||
File.WriteAllText(modulePath + "\\Views\\Web.config", File.ReadAllText(templatesPath + "ViewsWebConfig.txt"));
|
File.WriteAllText(modulePath + "\\Views\\Web.config", File.ReadAllText(CodeGenTemplatePath + "ViewsWebConfig.txt"));
|
||||||
Directory.CreateDirectory(modulePath + "Models");
|
Directory.CreateDirectory(modulePath + "Models");
|
||||||
Directory.CreateDirectory(modulePath + "Scripts");
|
Directory.CreateDirectory(modulePath + "Scripts");
|
||||||
|
|
||||||
string templateText = File.ReadAllText(templatesPath + "ModuleAssemblyInfo.txt");
|
string templateText = File.ReadAllText(CodeGenTemplatePath + "ModuleAssemblyInfo.txt");
|
||||||
templateText = templateText.Replace("$$ModuleName$$", moduleName);
|
templateText = templateText.Replace("$$ModuleName$$", moduleName);
|
||||||
templateText = templateText.Replace("$$ModuleTypeLibGuid$$", Guid.NewGuid().ToString());
|
templateText = templateText.Replace("$$ModuleTypeLibGuid$$", Guid.NewGuid().ToString());
|
||||||
File.WriteAllText(propertiesPath + "\\AssemblyInfo.cs", templateText);
|
File.WriteAllText(propertiesPath + "\\AssemblyInfo.cs", templateText);
|
||||||
File.WriteAllText(modulePath + "\\Web.config", File.ReadAllText(templatesPath + "ModuleWebConfig.txt"));
|
File.WriteAllText(modulePath + "\\Web.config", File.ReadAllText(CodeGenTemplatePath + "ModuleWebConfig.txt"));
|
||||||
templateText = File.ReadAllText(templatesPath + "ModuleManifest.txt");
|
templateText = File.ReadAllText(CodeGenTemplatePath + "ModuleManifest.txt");
|
||||||
templateText = templateText.Replace("$$ModuleName$$", moduleName);
|
templateText = templateText.Replace("$$ModuleName$$", moduleName);
|
||||||
File.WriteAllText(modulePath + "\\Module.txt", templateText);
|
File.WriteAllText(modulePath + "\\Module.txt", templateText);
|
||||||
templateText = File.ReadAllText(templatesPath + "\\ModuleCsProj.txt");
|
templateText = File.ReadAllText(CodeGenTemplatePath + "\\ModuleCsProj.txt");
|
||||||
templateText = templateText.Replace("$$ModuleName$$", moduleName);
|
templateText = templateText.Replace("$$ModuleName$$", moduleName);
|
||||||
templateText = templateText.Replace("$$ModuleProjectGuid$$", projectGuid);
|
templateText = templateText.Replace("$$ModuleProjectGuid$$", projectGuid);
|
||||||
File.WriteAllText(modulePath + "\\" + moduleName + ".csproj", templateText);
|
File.WriteAllText(modulePath + "\\" + moduleName + ".csproj", templateText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void CreateThemeFromTemplates(string themeName, string baseThemePath, string projectGuid, out HashSet<string> createdFiles, out HashSet<string> createdFolders) {
|
||||||
|
var themePath = HostingEnvironment.MapPath("~/Themes/" + themeName + "/");
|
||||||
|
createdFiles = new HashSet<string>();
|
||||||
|
createdFolders = new HashSet<string>();
|
||||||
|
// create directories
|
||||||
|
foreach (var folderName in new string[] { "", "Content", "Styles", "Scripts", "Views", "Zones" }) {
|
||||||
|
var folder = themePath + folderName;
|
||||||
|
createdFolders.Add(folder);
|
||||||
|
Directory.CreateDirectory(folder);
|
||||||
|
}
|
||||||
|
if (baseThemePath != null) {
|
||||||
|
// copy BasedOn theme file by file
|
||||||
|
foreach (var file in Directory.GetFiles(baseThemePath, "*", SearchOption.AllDirectories)) {
|
||||||
|
var destPath = file.Replace(baseThemePath, themePath);
|
||||||
|
Directory.CreateDirectory(Path.GetDirectoryName(destPath));
|
||||||
|
File.Copy(file, destPath);
|
||||||
|
createdFiles.Add(destPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// non-BasedOn theme default files
|
||||||
|
var webConfig = themePath + "Views\\Web.config";
|
||||||
|
File.WriteAllText(webConfig, File.ReadAllText(CodeGenTemplatePath + "\\ViewsWebConfig.txt"));
|
||||||
|
createdFiles.Add(webConfig);
|
||||||
|
}
|
||||||
|
var templateText = File.ReadAllText(CodeGenTemplatePath + "\\ThemeManifest.txt").Replace("$$ThemeName$$", themeName);
|
||||||
|
File.WriteAllText(themePath + "Theme.txt", templateText);
|
||||||
|
createdFiles.Add(themePath + "Theme.txt");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void AddToSolution(string projectName, string projectGuid, HashSet<string> filesToAddToOrchardWeb, HashSet<string> foldersToAddToOrchardWeb) {
|
||||||
|
var rootWebProjectPath = HostingEnvironment.MapPath("~/Orchard.Web.csproj");
|
||||||
|
if (!string.IsNullOrEmpty(projectGuid)) {
|
||||||
|
var solutionPath = Directory.GetParent(rootWebProjectPath).Parent.FullName + "\\Orchard.sln";
|
||||||
|
if (File.Exists(solutionPath)) {
|
||||||
|
var projectReference = string.Format("EndProject\r\nProject(\"{{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}}\") = \"{0}\", \"Orchard.Web\\Modules\\{0}\\{0}.csproj\", \"{{{1}}}\"\r\n", projectName, projectGuid);
|
||||||
|
var projectConfiguationPlatforms = string.Format("GlobalSection(ProjectConfigurationPlatforms) = postSolution\r\n\t\t{{{0}}}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{{{0}}}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{{{0}}}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{{{0}}}.Release|Any CPU.Build.0 = Release|Any CPU\r\n", projectGuid);
|
||||||
|
var solutionText = File.ReadAllText(solutionPath);
|
||||||
|
solutionText = solutionText.Insert(solutionText.LastIndexOf("EndProject\r\n"), projectReference).Replace("GlobalSection(ProjectConfigurationPlatforms) = postSolution\r\n", projectConfiguationPlatforms);
|
||||||
|
solutionText = solutionText.Insert(solutionText.LastIndexOf("EndGlobalSection"), "\t{" + projectGuid + "} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5}\r\n\t");
|
||||||
|
File.WriteAllText(solutionPath, solutionText);
|
||||||
|
TouchSolution();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Context.Output.WriteLine(base.T("Warning: Solution file could not be found at {0}", solutionPath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AddFilesToOrchardWeb(filesToAddToOrchardWeb, foldersToAddToOrchardWeb);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddFilesToOrchardWeb(HashSet<string> content, HashSet<string> folders) {
|
||||||
|
if (content == null && folders == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var orchardWebProj = HostingEnvironment.MapPath("~/Orchard.Web.csproj");
|
||||||
|
if (!File.Exists(orchardWebProj)) {
|
||||||
|
Context.Output.WriteLine(T("Warning: Orchard.Web project file could not be found at {0}", orchardWebProj));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var filesBaseDir = Path.GetDirectoryName(orchardWebProj) + "\\";
|
||||||
|
var contentInclude = "";
|
||||||
|
if (content != null && content.Count > 0) {
|
||||||
|
contentInclude = string.Join("\r\n",
|
||||||
|
from file in content
|
||||||
|
select " <Content Include=\"" + file.Replace(filesBaseDir, "") + "\" />");
|
||||||
|
}
|
||||||
|
if (folders != null && folders.Count > 0) {
|
||||||
|
contentInclude += "\r\n" + string.Join("\r\n", from folder in folders
|
||||||
|
select " <Folder Include=\"" + folder.Replace(filesBaseDir, "") + "\" />");
|
||||||
|
}
|
||||||
|
var itemGroup = string.Format(CultureInfo.InvariantCulture, "<ItemGroup>\r\n{0}\r\n </ItemGroup>\r\n ", contentInclude);
|
||||||
|
var projectText = File.ReadAllText(orchardWebProj);
|
||||||
|
// find where the first ItemGroup is after any References
|
||||||
|
var refIndex = projectText.LastIndexOf("<Reference Include");
|
||||||
|
if (refIndex != -1) {
|
||||||
|
var firstItemGroupIndex = projectText.IndexOf("<ItemGroup>", refIndex);
|
||||||
|
if (firstItemGroupIndex != -1) {
|
||||||
|
projectText = projectText.Insert(firstItemGroupIndex, itemGroup);
|
||||||
|
File.WriteAllText(orchardWebProj, projectText);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Context.Output.WriteLine(T("Warning: Unable to modify Orchard.Web project file at {0}", orchardWebProj));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void TouchSolution() {
|
private void TouchSolution() {
|
||||||
string rootWebProjectPath = HostingEnvironment.MapPath("~/Orchard.Web.csproj");
|
string rootWebProjectPath = HostingEnvironment.MapPath("~/Orchard.Web.csproj");
|
||||||
string solutionPath = Directory.GetParent(rootWebProjectPath).Parent.FullName + "\\Orchard.sln";
|
string solutionPath = Directory.GetParent(rootWebProjectPath).Parent.FullName + "\\Orchard.sln";
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
<Compile Include="Services\CodeGenerationCommandInterpreter.cs" />
|
<Compile Include="Services\CodeGenerationCommandInterpreter.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Content Include="CodeGenerationTemplates\ThemeManifest.txt" />
|
||||||
<Content Include="Module.txt" />
|
<Content Include="Module.txt" />
|
||||||
<Content Include="CodeGenerationTemplates\Controller.txt" />
|
<Content Include="CodeGenerationTemplates\Controller.txt" />
|
||||||
<Content Include="CodeGenerationTemplates\DataMigration.txt" />
|
<Content Include="CodeGenerationTemplates\DataMigration.txt" />
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
Loading…
Reference in New Issue
Block a user