2017年9月28日 星期四

How to upgrade the umbraco backoffice or package involved backoffice changes under TFS control


Environment
- Umbraco version 7.x
- TFS 2010
- Ms Visual Studio 2015


Step 1
Make sure Backup whole solution and database included appData folder

Step 2
Stop the Wesite in IIS ( if the current runtime folder is binding to IIS )

Step 3 Un-blind TFS
- Open the Visual Studio Solution
- Click File > Source Control > Advanced > Change Source Control


- Save Solution and Close

Step 4 Made all folder and file under the solution writeable

Step 5 Open VS solution 

Step 6 Backup config folder (..\config)

Step 7. Install or Upgrade the package or umbracoCms

Click Yes to conflict file, let umbraco overwrite your own config file ( Caution: your own config file must be backup )


PM> update-package umbracocms
Attempting to gather dependency information for multiple packages with respect to project 'Intranet', targeting '.NETFramework,Version=v4.6.1'
Attempting to resolve dependencies for multiple packages.
Resolving actions install multiple packages
Removed package 'UmbracoCms 7.7.4' from 'packages.config'
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\applications.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\ClientDependency.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\Dashboard.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\ExamineIndex.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\ExamineSettings.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\HealthChecks.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\log4net.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\trees.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\umbracoSettings.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\applications.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\ClientDependency.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\Dashboard.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\ExamineIndex.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\ExamineSettings.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\HealthChecks.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\log4net.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\trees.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\umbracoSettings.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\applications.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\ClientDependency.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\Dashboard.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\ExamineIndex.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\ExamineSettings.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\HealthChecks.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\log4net.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\trees.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\umbracoSettings.config' because it was modified.
Directory 'Media' is not empty. Skipping...
Successfully uninstalled 'UmbracoCms 7.7.4' from Intranet
Removed package 'UmbracoCms.Core 7.7.4' from 'packages.config'
Successfully uninstalled 'UmbracoCms.Core 7.7.4' from Intranet
Removed package 'Examine 0.1.85' from 'packages.config'
Successfully uninstalled 'Examine 0.1.85' from Intranet
Removed package 'ImageProcessor.Web.Config 2.3.0.0' from 'packages.config'
Successfully uninstalled 'ImageProcessor.Web.Config 2.3.0.0' from Intranet
Removed package 'ImageProcessor.Web 4.8.3' from 'packages.config'
Successfully uninstalled 'ImageProcessor.Web 4.8.3' from Intranet
Removed package 'Microsoft.IO.RecyclableMemoryStream 1.2.1' from 'packages.config'
Successfully uninstalled 'Microsoft.IO.RecyclableMemoryStream 1.2.1' from Intranet
Removed package 'ImageProcessor 2.5.3' from 'packages.config'
Successfully uninstalled 'ImageProcessor 2.5.3' from Intranet
  GET https://api.nuget.org/v3-flatcontainer/imageprocessor/2.5.6/imageprocessor.2.5.6.nupkg
  OK https://api.nuget.org/v3-flatcontainer/imageprocessor/2.5.6/imageprocessor.2.5.6.nupkg 1531ms
Installing ImageProcessor 2.5.6.
Adding package 'ImageProcessor.2.5.6' to folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Added package 'ImageProcessor.2.5.6' to folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Added package 'ImageProcessor.2.5.6' to 'packages.config'
Successfully installed 'ImageProcessor 2.5.6' to Intranet
  GET https://api.nuget.org/v3-flatcontainer/microsoft.io.recyclablememorystream/1.2.2/microsoft.io.recyclablememorystream.1.2.2.nupkg
  OK https://api.nuget.org/v3-flatcontainer/microsoft.io.recyclablememorystream/1.2.2/microsoft.io.recyclablememorystream.1.2.2.nupkg 1053ms
Installing Microsoft.IO.RecyclableMemoryStream 1.2.2.
Adding package 'Microsoft.IO.RecyclableMemoryStream.1.2.2' to folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Added package 'Microsoft.IO.RecyclableMemoryStream.1.2.2' to folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Added package 'Microsoft.IO.RecyclableMemoryStream.1.2.2' to 'packages.config'
Successfully installed 'Microsoft.IO.RecyclableMemoryStream 1.2.2' to Intranet
  GET https://api.nuget.org/v3-flatcontainer/imageprocessor.web/4.8.7/imageprocessor.web.4.8.7.nupkg
  OK https://api.nuget.org/v3-flatcontainer/imageprocessor.web/4.8.7/imageprocessor.web.4.8.7.nupkg 861ms
Installing ImageProcessor.Web 4.8.7.
Adding package 'ImageProcessor.Web.4.8.7' to folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Added package 'ImageProcessor.Web.4.8.7' to folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Added package 'ImageProcessor.Web.4.8.7' to 'packages.config'
Successfully installed 'ImageProcessor.Web 4.8.7' to Intranet
  GET https://api.nuget.org/v3-flatcontainer/imageprocessor.web.config/2.3.1/imageprocessor.web.config.2.3.1.nupkg
  OK https://api.nuget.org/v3-flatcontainer/imageprocessor.web.config/2.3.1/imageprocessor.web.config.2.3.1.nupkg 872ms
Installing ImageProcessor.Web.Config 2.3.1.
Adding package 'ImageProcessor.Web.Config.2.3.1' to folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Added package 'ImageProcessor.Web.Config.2.3.1' to folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Added package 'ImageProcessor.Web.Config.2.3.1' to 'packages.config'
Successfully installed 'ImageProcessor.Web.Config 2.3.1' to Intranet
  GET https://api.nuget.org/v3-flatcontainer/examine/0.1.88/examine.0.1.88.nupkg
  OK https://api.nuget.org/v3-flatcontainer/examine/0.1.88/examine.0.1.88.nupkg 863ms
Installing Examine 0.1.88.
Adding package 'Examine.0.1.88' to folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Added package 'Examine.0.1.88' to folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Added package 'Examine.0.1.88' to 'packages.config'
Successfully installed 'Examine 0.1.88' to Intranet
  GET https://api.nuget.org/v3-flatcontainer/umbracocms.core/7.7.6/umbracocms.core.7.7.6.nupkg
  OK https://api.nuget.org/v3-flatcontainer/umbracocms.core/7.7.6/umbracocms.core.7.7.6.nupkg 863ms
Installing UmbracoCms.Core 7.7.6.
Adding package 'UmbracoCms.Core.7.7.6' to folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Added package 'UmbracoCms.Core.7.7.6' to folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Added package 'UmbracoCms.Core.7.7.6' to 'packages.config'
Executing script file 'X:\Umbraco\Trunk\Source\MySolution\packages\UmbracoCms.Core.7.7.6\tools\install.ps1'
installPath: X:\Umbraco\Trunk\Source\MySolution\packages\UmbracoCms.Core.7.7.6
toolsPath: X:\Umbraco\Trunk\Source\MySolution\packages\UmbracoCms.Core.7.7.6\tools
 
projectPath: X:\Umbraco\Trunk\Source\MySolution\MyProject\
backupPath: X:\Umbraco\Trunk\Source\MySolution\MyProject\App_Data\NuGetBackup\20171128-105604
copyLogsPath: X:\Umbraco\Trunk\Source\MySolution\MyProject\App_Data\NuGetBackup\20171128-105604\CopyLogs
umbracoBinFolder: X:\Umbraco\Trunk\Source\MySolution\MyProject\bin
Successfully installed 'UmbracoCms.Core 7.7.6' to Intranet
  GET https://api.nuget.org/v3-flatcontainer/umbracocms/7.7.6/umbracocms.7.7.6.nupkg
  OK https://api.nuget.org/v3-flatcontainer/umbracocms/7.7.6/umbracocms.7.7.6.nupkg 876ms
Installing UmbracoCms 7.7.6.
Adding package 'UmbracoCms.7.7.6' to folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Added package 'UmbracoCms.7.7.6' to folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
File Conflict
File 'Config\umbracoSettings.config' already exists in project 'Intranet'. Do you want to overwrite it?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [?] Help (default is "N"):y
Overwriting existing file 'Config\umbracoSettings.config'..
File Conflict
File 'Config\trees.config' already exists in project 'Intranet'. Do you want to overwrite it?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [?] Help (default is "N"):y
Overwriting existing file 'Config\trees.config'..
File Conflict
File 'Config\log4net.config' already exists in project 'Intranet'. Do you want to overwrite it?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [?] Help (default is "N"):y
Overwriting existing file 'Config\log4net.config'..
File Conflict
File 'Config\HealthChecks.config' already exists in project 'Intranet'. Do you want to overwrite it?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [?] Help (default is "N"):y
Overwriting existing file 'Config\HealthChecks.config'..
File Conflict
File 'Config\ExamineSettings.config' already exists in project 'Intranet'. Do you want to overwrite it?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [?] Help (default is "N"):y
Overwriting existing file 'Config\ExamineSettings.config'..
File Conflict
File 'Config\ExamineIndex.config' already exists in project 'Intranet'. Do you want to overwrite it?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [?] Help (default is "N"):y
Overwriting existing file 'Config\ExamineIndex.config'..
File Conflict
File 'Config\Dashboard.config' already exists in project 'Intranet'. Do you want to overwrite it?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [?] Help (default is "N"):y
Overwriting existing file 'Config\Dashboard.config'..
File Conflict
File 'Config\ClientDependency.config' already exists in project 'Intranet'. Do you want to overwrite it?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [?] Help (default is "N"):y
Overwriting existing file 'Config\ClientDependency.config'..
File Conflict
File 'Config\applications.config' already exists in project 'Intranet'. Do you want to overwrite it?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [?] Help (default is "N"):y
Overwriting existing file 'Config\applications.config'..
Added package 'UmbracoCms.7.7.6' to 'packages.config'
Executing script file 'X:\Umbraco\Trunk\Source\MySolution\packages\UmbracoCms.7.7.6\tools\install.ps1'
installPath: X:\Umbraco\Trunk\Source\MySolution\packages\UmbracoCms.7.7.6
toolsPath: X:\Umbraco\Trunk\Source\MySolution\packages\UmbracoCms.7.7.6\tools
 
projectPath: X:\Umbraco\Trunk\Source\MySolution\MyProject\
backupPath: X:\Umbraco\Trunk\Source\MySolution\MyProject\App_Data\NuGetBackup\20171128-110339
copyLogsPath: X:\Umbraco\Trunk\Source\MySolution\MyProject\App_Data\NuGetBackup\20171128-110339\CopyLogs
webConfigSource: X:\Umbraco\Trunk\Source\MySolution\MyProject\Web.config
configFolder: X:\Umbraco\Trunk\Source\MySolution\MyProject\Config
Copying2 X:\Umbraco\Trunk\Source\MySolution\packages\UmbracoCms.7.7.6\UmbracoFiles\Umbraco\Views\install\* to X:\Umbraco\Trunk\Source\MySolution\MyProject\Umbraco\Views\install\
Successfully installed 'UmbracoCms 7.7.6' to Intranet
Removing package 'UmbracoCms 7.7.4' from folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Removed package 'UmbracoCms 7.7.4' from folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Removing package 'UmbracoCms.Core 7.7.4' from folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Removed package 'UmbracoCms.Core 7.7.4' from folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Removing package 'Examine 0.1.85' from folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Removed package 'Examine 0.1.85' from folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Removing package 'ImageProcessor.Web.Config 2.3.0.0' from folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Removed package 'ImageProcessor.Web.Config 2.3.0.0' from folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Removing package 'ImageProcessor.Web 4.8.3' from folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Removed package 'ImageProcessor.Web 4.8.3' from folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Removing package 'Microsoft.IO.RecyclableMemoryStream 1.2.1' from folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Removed package 'Microsoft.IO.RecyclableMemoryStream 1.2.1' from folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Removing package 'ImageProcessor 2.5.3' from folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Removed package 'ImageProcessor 2.5.3' from folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
PM> 



Step 8 Handle conflict config file

Use WinMerge to compare config file one by one carefully, add back your own part to the umbraco one.

Step 9. After Successfully install or upgrade and tested bind to TFS again.

How to back to normal online status from restoring status on sql database


RESTORE DATABASE [Your Database name] WITH RECOVERY

2017年9月27日 星期三

How to get access vorto value in razor

Environment
- Umbraco version 7.6.3 assembly: 1.0.6361.21154
- Vorto v1.5.3

@using Our.Umbraco.Vorto.Extensions;
@if(Model.Content.HasVortoValue("bodyText"))
{
@Model.Content.GetVortoValue("bodyText")
}


2017年9月18日 星期一

TFS Error TF30170 when create the new repos

Error:

New Team Project Creation fails - TF30170: The plugin Microsoft.ProjectCreationWizard.TestManagement failed during task TestSettings from group TestManagement


Solution:
Goto IIS recycle TFS application pool


2017年9月17日 星期日

How to automation Umbraco package via Grunt

Environment
- Umbraco version 7.6.3 assembly: 1.0.6361.21154
- NodeJs
- Grunt

1. Install Node.js

2. Install Grunt

> npm install grunt
> npm install grunt-cli

Optional : -g install grunt globally (will modified windows environment parameter )

3. Install 'grunt-umbraco-package'

> npm install grunt-umbraco-package --save-dev

Remarks : if you are not install globally, for install all grunt dependencies, you need to execute the command under the your project folder.

4. Create the folder structure like

{Project Name}
|-- config
|   `-- meta.json
|-- files
|-- node_modules
|-- releases
|   |-- github
|   `-- umbraco
|-- src
|   `-- App_Plugins
|       `-- {Project Name}
|           |-- assets
|           |-- css
|           |-- js
|           |-- langs
|           |-- views
|           `-- package.manifest
|-- Gruntfile.js
|-- LICENSE
|-- package.xml
|-- package.json
`-- README.md


Gruntfile.js


module.exports = function(grunt) {

    // Load the package JSON file
    var pkg = grunt.file.readJSON('package.json');

    // get the root path of the project
    var projectRoot = 'src/App_Plugins/' + pkg.name + '/';
 var destRoot = 'files/';

    // Load information about the assembly
    var assembly = grunt.file.readJSON('config/meta.json');

    // Get the version of the package
    var version = assembly.informationalVersion ? assembly.informationalVersion : assembly.version;

    grunt.initConfig({
        pkg: pkg,
  clean: {
            files: [
                destRoot + '**/*.*'
            ]
        },
        copy: {
            release: {
                files: [
                    {
                        expand: true,
                        cwd: projectRoot,
                        src: ['**/*.*'],
                        dest: destRoot
                    }
                ]
            }
        },
  zip: {
   release: {
    cwd: destRoot,
    src: [
     destRoot + '**/*.*'
    ],
    dest: 'releases/github/' + pkg.name + '.v' + version + '.zip'
   }
  },
  umbracoPackage: {
   dist: {
    src: destRoot,
    dest: 'releases/umbraco',
    options: {
     name: pkg.name,
     version: version,
     url: pkg.url,
     license: pkg.license.name,
     licenseUrl: pkg.license.url,
     author: pkg.author.name,
     authorUrl: pkg.author.url,
     readme: pkg.readme,
     outputName: pkg.name + '.v' + version + '.zip',
     manifest: 'package.xml'
    }
   }
  }
    });

    grunt.loadNpmTasks('grunt-contrib-clean');
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-nuget');
    grunt.loadNpmTasks('grunt-zip');
    grunt.loadNpmTasks('grunt-umbraco-package');

    grunt.registerTask('dev', ['clean', 'copy', 'umbracoPackage']);
    grunt.registerTask('default', ['dev']);

};

Package.xml 


<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<umbPackage>
  <files>
    <file>
      <guid>package.manifest</guid>
      <orgPath>/App_Plugins/Pairs</orgPath>
      <orgName>package.manifest</orgName>
    </file>
    <file>
      <guid>CmsUser.png</guid>
      <orgPath>/App_Plugins/Pairs/assets</orgPath>
      <orgName>CmsUser.png</orgName>
    </file>
    <file>
      <guid>cs_code.png</guid>
      <orgPath>/App_Plugins/Pairs/assets</orgPath>
      <orgName>cs_code.png</orgName>
    </file>
    <file>
      <guid>logo.png</guid>
      <orgPath>/App_Plugins/Pairs/assets</orgPath>
      <orgName>logo.png</orgName>
    </file>
    <file>
      <guid>propertyeditor.png</guid>
      <orgPath>/App_Plugins/Pairs/assets</orgPath>
      <orgName>propertyeditor.png</orgName>
    </file>
    <file>
      <guid>pairs.css</guid>
      <orgPath>/App_Plugins/Pairs/css</orgPath>
      <orgName>pairs.css</orgName>
    </file>
    <file>
      <guid>pairs.controller.js</guid>
      <orgPath>/App_Plugins/Pairs/js</orgPath>
      <orgName>pairs.controller.js</orgName>
    </file>
    <file>
      <guid>pairs.prevalue.controller.js</guid>
      <orgPath>/App_Plugins/Pairs/js</orgPath>
      <orgName>pairs.prevalue.controller.js</orgName>
    </file>
    <file>
      <guid>pairs.html</guid>
      <orgPath>/App_Plugins/Pairs/views</orgPath>
      <orgName>pairs.html</orgName>
    </file>
    <file>
      <guid>pairs.prevalue.html</guid>
      <orgPath>/App_Plugins/Pairs/views</orgPath>
      <orgName>pairs.prevalue.html</orgName>
    </file>
  </files>
  <info>
    <package>
      <name>Pairs</name>
      <version>0.1.0</version>
      <iconUrl />
      <license url="http://opensource.org/licenses/MIT">MIT License</license>
      <url>https://github.com/samsam321/umbraco-Pairs</url>
      <requirements type="strict">
        <major>7</major>
        <minor>6</minor>
        <patch>3</patch>
      </requirements>
    </package>
    <author>
      <name>SamAY</name>
      <website>https://www.linkedin.com/in/threewood/</website>
    </author>
    <readme><![CDATA[
 <p>Thank you for installing Threewood Umbraco Pairs - the tool that makes you can create simple key value pairs property editor.</p>
          
                             
]]></readme>
  </info>
  <DocumentTypes />
  <Templates />
  <Stylesheets />
  <Macros />
  <DictionaryItems />
  <Languages />
  <DataTypes />
</umbPackage>

Package.json


{
  "name": "Pairs",
  "url": "https://github.com/samsam321/umbraco-Pairs",
  "license": {
    "name": "MIT",
    "url": "https://github.com/samsam321/umbraco-Pairs/blob/master/LICENSE"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/samsam321/umbraco-Pairs.git"
  },
  "author": {
    "name": "SamAY",
    "url": "https://www.linkedin.com/in/threewood/"
  },
  "readme": "Threewood.Umbraco.Pairs is a small package with key value pair property editor.",
  "devDependencies": {
    "grunt": "~0.4.5",
    "grunt-contrib-clean": "^0.6.0",
    "grunt-contrib-copy": "^0.4.1",
    "grunt-nuget": "^0.1.7",
    "grunt-umbraco-package": "1.0.0",
    "grunt-zip": "^0.17.1"
  }
}

P.S create or copy from the package file ( created manually via Umbraco backoffice )


meta.json


{
  "title": "Threewood.Umbraco.Pairs",
  "description": "Threewood.Umbraco.Pairs is a small package with key value pair property editor.",
  "company": "",
  "product": "Threewood.Umbraco.Pairs",
  "copyright": "Copyright © 2017",
  "version": "0.1.0",
  "informationalVersion": "0.1.0",
  "fileVersion": "0.1.0"
}

5. Open Command Prompt and goto the folder same level as Gruntfile.js

6. $>grunt

7.
 



How to create custom package manually

Environment
- Umbraco version 7.6.3 assembly: 1.0.6361.21154 


1. Goto Umbraco Backoffice Developer node

2. Create package by mouse click ...next to "Packages"






3. Input all necessary information















4. Click Save button

5. Goto Package  Properties Page

6. Click Download

7. Goto Umbraco Folder "\media\created-package" and you will see your package zip file.


2017年9月12日 星期二

How to query Umbraco latest publish content by content type alias

Environment
- Umbraco version 7.6.3 assembly: 1.0.6361.21154
- MSSQL 2012 V11


SELECT TOP 1 cmsPX.*, cmsCT.*
FROM [Umbraco_Intranet].[dbo].[cmsPreviewXml] AS cmsPX
LEFT JOIN [Umbraco_Intranet].[dbo].[cmsContentVersion] AS cmsCV ON ( cmsPX.versionId = cmsCV.VersionId 
                 and cmsPX.nodeId = cmsCV.ContentId)               
LEFT JOIN [Umbraco_Intranet].[dbo].[cmsContent] AS cmsC ON cmsC.nodeId = cmsPX.nodeId
LEFT JOIN [Umbraco_Intranet].[dbo].[cmsContentType] AS cmsCT ON cmsCT.nodeId = cmsC.contentType 
WHERE cmsCT.alias = 'Content Alias'
ORDER BY cmsPX.timestamp DESC

How to query Umbraco property editor prevalue


Environment
- Umbraco version 7.6.3 assembly: 1.0.6361.21154
- MSSQL 2012 V11


  SELECT DT.*, DYPV.*
  FROM [Umbraco_Intranet].[dbo].[cmsDataType] AS DT
  LEFT JOIN [Umbraco_Intranet].[dbo].[cmsDataTypePreValues] AS DYPV ON DYPV.[datatypeNodeId] = DT.nodeId
  WHERE [propertyEditorAlias] = 'Property Editor Alias'




2017年9月6日 星期三

How to exclude the custom field property alias in examine search of umbraco

How to exclude the custom field property alias in examine search of umbraco

Environment
- Umbraco version 7.6.3 assembly: 1.0.6361.21154
- VS2015


Reference
https://techvalut.blogspot.hk/2017/09/how-to-include-custom-properties-in.html
http://www.codeshare.co.uk/videos/how-to-build-a-site-with-umbraco-part-12-advanced-search/

Partial Code for search condition of  !(A ==1) & ( (B==SearchTerm) || (C==SearchTerm) )

ISearchCriteria searchCriteria = ExamineManager.Instance.CreateSearchCriteria(BooleanOperation.And);
IBooleanOperation queryNodes = null;
   
queryNodes = searchCriteria.GroupedOr(new string[] { "B", "C" }, "searchTerm");
queryNodes = queryNodes.Not().GroupedOr(new string[] {"A"}, "1");

ExamineManager.Instance.Search(queryNodes.Compile());


Search View

<section class="container">
    <div class="row">
        <div class="col-xs-12">
            <p></p>            
            @{ Html.RenderAction("RenderSearchForm", "Search", new { docTypeAliases = "blogPost,videoPost,home",
                                                                     fieldPropertyAliases = "title,subTitle,articleIntro,body,intro,nodeName,metaName,metaKeyWords,metaDescription,contentGrid",
                                                                     inclusionExclusionFieldPropertyAliases = "excludeFromSearch:1",
                                                                     pageSize = 10,
                                                                     pagingGroupSize = 3,
                                                                     isIncludePDFContent = true}); }
        </div>
    </div>
</section>


Controller

  [HttpGet]
        public ActionResult RenderSearchForm(string query, string docTypeAliases, string fieldPropertyAliases, string inclusionExclusionFieldPropertyAliases, int pageSize, int pagingGroupSize, bool isIncludePDFContent)
        {
            SearchView model = _searchHelper.GetSearchFormItemsModel(query,
                                                                     docTypeAliases,
                                                                     fieldPropertyAliases,
                                                                     inclusionExclusionFieldPropertyAliases,
                                                                     pageSize,
                                                                     pagingGroupSize,
                                                                     isIncludePDFContent,
                                                                     searchtitleDictionaryAlias: "Title",
                                                                     searchPlaceHolderDictionaryAlias: "PlaceHolder",
                                                                     searchSendButtonDictionaryAlias: "Send Button");

            return PartialView(GetViewPath("_SearchForm"), model);
        }

        [HttpPost]
        public ActionResult SubmitSearchForm(SearchView model)
        {
            if (ModelState.IsValid)
            {
                if (!string.IsNullOrEmpty(model.SearchTerm))
                    // && !string.IsNullOrEmpty(model.Category))
                {
                    model.SearchTerm = model.SearchTerm;
                    model.SearchGroups = _searchHelper.GetSearchGroupsItemsModel(model);
                    model.SearchExcludeGroups = _searchHelper.GetSearchExcludeGroupsItemsModel(model);
                    model.SearchResults = _searchHelper.GetSearchResults(model, Request.Form.AllKeys);
                }
                return RenderSearchResults(model.SearchResults);
            }

            return null;
        }


Partial View

@using Intranet.Library.Models
@model SearchView

@*@using (Html.BeginUmbracoForm("SubmitSearchForm", "Search", FormMethod.Post))*@
@using (Ajax.BeginForm("SubmitSearchForm", "Search", null, new AjaxOptions
{
    HttpMethod = "POST",
    InsertionMode = InsertionMode.Replace,
    UpdateTargetId = "search-results"
}))
{    
    @Html.HiddenFor(m => m.DocTypeAliases)
    @Html.HiddenFor(m => m.FieldPropertyAliases)
    @Html.HiddenFor(m => m.InclusionExclusionFieldPropertyAliases)
    @Html.HiddenFor(m => m.PageSize)
    @Html.HiddenFor(m => m.PagingGroupSize)
    @Html.HiddenFor(m => m.IsIncludePDFContent)


    
    

@Model.Title

@Html.TextBoxFor(m => m.SearchTerm, new { placeholder = Model.SearchPlaceHolder, @class = "form-control" })
@*
@{ Html.RenderAction("RenderCategoryList", "Search");}
*@
@{ Html.RenderAction("RenderSearchResults", "Search", new { Model = Model.SearchResults });}
}

Helper Class
  public SearchResults GetSearchResults(SearchView searchModel, string[] allKeys)
        {
            SearchResults resultsModel = new SearchResults();          
            resultsModel.SearchTerm = searchModel.SearchTerm;
            resultsModel.PageNumber = GetPageNumber(allKeys);

            IOrderedEnumerable<SearchResult> allResults = SearchUsingExamine(searchModel.DocTypeAliases.Split(','), searchModel.SearchGroups, searchModel.SearchExcludeGroups, searchModel.SearchTerm, searchModel.IsIncludePDFContent);
            resultsModel.TotalItemCount = allResults.Count();
            resultsModel.Results = GetResultsForThisPage(allResults, resultsModel.PageNumber, searchModel.PageSize);

            resultsModel.PageCount = Convert.ToInt32(Math.Ceiling((decimal)resultsModel.TotalItemCount / (decimal)searchModel.PageSize));
            resultsModel.PagingBounds = GetPagingBounds(resultsModel.PageCount, resultsModel.PageNumber, searchModel.PagingGroupSize);
            return resultsModel;
        }
     
        private IEnumerable<IPublishedContent> GetResultsForThisPage(IOrderedEnumerable<SearchResult> allResults, int pageNumber, int pageSize)
        {
            return allResults.Skip((pageNumber - 1) * pageSize).Take(pageSize).Select(x => GetPublishedContent(x.Id, x.Fields["__IndexType"]));
        }

        private IPublishedContent GetPublishedContent(int id, string type)
        {
            switch (type)
            {
                case "media":
                    return _uHelper.TypedMedia(id);
                case "content":
                default:
                    return _uHelper.TypedContent(id);                    
            }            
        }
       
        private ISearchResults SearchWebContentUsingExamine(string[] documentTypes, List<SearchGroup> searchGroups, List<SearchGroup> searchExcludeGroups)
        {
            ISearchCriteria searchCriteria = ExamineManager.Instance.CreateSearchCriteria(BooleanOperation.And);
            IBooleanOperation queryNodes = null;

            queryNodes = searchCriteria.GroupedNot(new string[] { "dummy" }, "1");

            //exclude field property alias
            if (searchExcludeGroups != null && searchExcludeGroups.Any())
            {
                foreach (SearchGroup searchGroup in searchExcludeGroups)
                {
                    queryNodes = queryNodes.Not().GroupedOr(searchGroup.FieldsToSearchIn, searchGroup.SearchTerms);
                }
            }

            if (documentTypes != null && documentTypes.Length > 0)
            {
                //only get results for documents of a certain type
                queryNodes = queryNodes.And().GroupedOr(new string[] { _docTypeAliasFieldName }, documentTypes);
            }

            if (searchGroups != null && searchGroups.Any())
            {
                //in each search group it looks for a match where the specified fields contain any of the specified search terms
                //usually would only have 1 search group, unless you want to filter out further, i.e. using categories as well as search terms
                foreach (SearchGroup searchGroup in searchGroups)
                {
                    queryNodes = queryNodes.And().GroupedOr(searchGroup.FieldsToSearchIn, searchGroup.SearchTerms);
                }
            }

            //return all results of the search
            return ExamineManager.Instance.Search(queryNodes.Compile());          
        }

        private ISearchResults SearchPdfContentUsingExamine(List<SearchGroup> searchExcludeGroups, string searchTerm, bool isIncludePDFContent)
        {
            if (isIncludePDFContent)
            {
                var searcher = ExamineManager.Instance.SearchProviderCollection["PDFSearcher"];                

                if (searcher == null)
                    return null;

                var searchCriteria = searcher.CreateSearchCriteria(BooleanOperation.And);
                IBooleanOperation queryNodes = null;

                queryNodes = searchCriteria.GroupedOr(new string[] { "FileTextContent" }, new string[] { searchTerm });

                //exclude field property alias
                if (searchExcludeGroups != null && searchExcludeGroups.Any())
                {
                    foreach (SearchGroup searchGroup in searchExcludeGroups)
                    {
                        queryNodes = queryNodes.Not().GroupedOr(searchGroup.FieldsToSearchIn, searchGroup.SearchTerms);
                    }
                }                

                return searcher.Search(queryNodes.Compile());
            }
            return null;
        }

        public IOrderedEnumerable<SearchResult> SearchUsingExamine(string[] documentTypes, List<SearchGroup> searchGroups, List<SearchGroup> searchExcludeGroups, string searchTerm, bool isIncludePDFContent)
        {
            ISearchResults webPageContentSearchResults = SearchWebContentUsingExamine(documentTypes, searchGroups, searchExcludeGroups);
            ISearchResults pdfContentSearchResults = SearchPdfContentUsingExamine(searchExcludeGroups, searchTerm, isIncludePDFContent);

            IOrderedEnumerable<SearchResult> orderedSearchResultsAll = pdfContentSearchResults != null ? webPageContentSearchResults.Concat(pdfContentSearchResults).OrderByDescending(n => n.Score) : webPageContentSearchResults.OrderByDescending(n => n.Score);

            return orderedSearchResultsAll;
        }

        public List<SearchGroup> GetSearchGroupsItemsModel(SearchView model)
        {
            List<SearchGroup> searchGroups = null;
            if (!string.IsNullOrEmpty(model.FieldPropertyAliases))
            {
                searchGroups = new List<SearchGroup>();
                searchGroups.Add(new SearchGroup(model.FieldPropertyAliases.Split(','), new string[] { model.SearchTerm }));
            }

            if (!string.IsNullOrEmpty(model.Category))
            {
                searchGroups = searchGroups ?? new List<SearchGroup>();                
                searchGroups.Add(new SearchGroup(new string[] { _categoryDocTypeAlias }, new string[] { model.Category }));
            }

            return searchGroups;
        }

        public List<SearchGroup> GetSearchExcludeGroupsItemsModel(SearchView model)
        {
            List<SearchGroup> searchGroups = null;
            if (!string.IsNullOrEmpty(model.InclusionExclusionFieldPropertyAliases))
            {
                Dictionary<string, string> dict = model.InclusionExclusionFieldPropertyAliases.Split(',').Select(item => item.Split(':')).ToDictionary(s => s[0], s => s[1]);
                if (dict != null)
                { 
                    foreach(var item in dict)
                    {
                        searchGroups = searchGroups ?? new List<SearchGroup>();
                        searchGroups.Add(new SearchGroup(new string[] { item.Key }, new string[] { item.Value })); 
                    }
                }
            }

            return searchGroups;
        }        

        public int GetPageNumber(string[] formKeys)
        {
            int pageNumber = 1;
            const string NAME_PREFIX = "page";
            const char NAME_SEPARATOR = '-';
            if (formKeys != null)
            {
                string pagingButtonName = formKeys.Where(x => x.Length > NAME_PREFIX.Length && x.Substring(0, NAME_PREFIX.Length).ToLower() == NAME_PREFIX).FirstOrDefault();
                if (!string.IsNullOrEmpty(pagingButtonName))
                {
                    string[] pagingButtonNameParts = pagingButtonName.Split(NAME_SEPARATOR);
                    if (pagingButtonNameParts.Length > 1)
                    {
                        if (!int.TryParse(pagingButtonNameParts[1], out pageNumber))
                        {
                            //pageNumber already set in tryparse
                        }
                    }
                }
            }
            return pageNumber;
        }
      
        public PagingBounds GetPagingBounds(int pageCount, int pageNumber, int groupSize)
        {
            int middlePageNumber = (int)(Math.Ceiling((decimal)groupSize / 2));
            int pagesBeforeMiddle = groupSize - (int)middlePageNumber;
            int pagesAfterMiddle = groupSize - (pagesBeforeMiddle + 1);
            int startPage = 1;
            if (pageNumber >= middlePageNumber)
            {
                startPage = pageNumber - pagesBeforeMiddle;
            }
            else
            {
                pagesAfterMiddle = groupSize - pageNumber;
            }
            int endPage = pageCount;
            if (pageCount >= (pageNumber + pagesAfterMiddle))
            {
                endPage = (pageNumber + pagesAfterMiddle);
            }
            bool showFirstButton = startPage > 1;
            bool showLastButton = endPage < pageCount;
            return new PagingBounds(startPage, endPage, showFirstButton, showLastButton);
        }

        public SearchView GetSearchFormItemsModel(string query,
                                                  string docTypeAliases,
                                                  string fieldPropertyAliases,
                                                  string inclusionExclusionFieldPropertyAliases,
                                                  int pageSize,
                                                  int pagingGroupSize,
                                                  bool includePDFContent = false)
        {
            SearchView model = new SearchView();
           
            if (!string.IsNullOrEmpty(query))
            {
                model.SearchTerm = query;
                model.DocTypeAliases = docTypeAliases;
                model.FieldPropertyAliases = fieldPropertyAliases;
                model.InclusionExclusionFieldPropertyAliases = inclusionExclusionFieldPropertyAliases;
                model.PageSize = pageSize;
                model.PagingGroupSize = pagingGroupSize;
                model.IsIncludePDFContent = includePDFContent;
                model.SearchGroups = GetSearchGroupsItemsModel(model);
                model.SearchResults = GetSearchResults(model, _httpContext.Request.Form.AllKeys);
            }

            return model;
        }

        



2017年9月5日 星期二

How to include custom properties in examine search result of Umbraco

How to include custom properties in examine search result of Umbraco

Environment
- Umbraco version 7.6.3 assembly: 1.0.6361.21154
- VS2015




1. Add new properties "Exclude From Search" in backoffice



2. Add the custom properties in ExamineIndex.config

  <IndexSet SetName="PDFIndexSet" IndexPath="~/App_Data/TEMP/ExamineIndexes/PDFs">
    <IndexAttributeFields>

    </IndexAttributeFields>
    <IndexUserFields>
      <add Name="excludeFromSearch"/>
    </IndexUserFields>
  </IndexSet>