My First Sitecore Module – Google Product Feed

Hello Folks,I have been working on Google Product Feed in one of the Project.

What is Google Product Feed?

It is a feed in XML Format which we can submit to google for listing the products in Google Shopping Tab.

A google product feed xml file has list of product which use groupings of attributes that define each product in a unique way. Attributes, such as ‘condition’ and ‘availability’, can have standardized values, or accepted “answers,” or attributes can be open to fill with your own choice of value, such as ‘id’ or ‘title’. Accurately describing items using these attributes allows users to search and find your items more easily.
Read More

How to encode Trademark symbols ™ in C#

Hello Folks, Sorry was away for a while. As was very busy with Project.Challenge:
We were facing one strange issue with encoding Trademark symbol in C#. If you are also facing such similar issue then this post is for you.It was strange for us see that ™ isn’t encoding with HttpUtility.HttpEncode. As google is my best friend [so as yours], I tried to get the answer.Before we dig into the solution, I tried on following websites which help us to get the result live for the Http.HtmlEncode()http://htmlencode.org/
http://www.opinionatedgeek.com/dotnet/tools/htmlencode/encode.aspx

And we see that HTML Encode isn’t encoding ™.
Read More

How to escape line breaks while creating CSV or TSV file using C#

Hello C# friends.

Are you creating a CSV (Comma Separated Value) or TSV (Tab Separated Value) file in CSharp and you don’t know why your CSV file is breaking when you open it into Excel, then this post is for you.

Mr. Brian has written a very nice article on how to generate CSV file which we referred in our project.
http://www.csharptocsharp.com/generate-csv-from-generic-list

It was difficult to identify the problem. Values in object were html based and we were doing Html.Encode, so i thought that we need to do Html.Decode, but was unlucky.
To get better understanding of Html.Decode and Html.Encode refer: http://www.dotnetperls.com/httputility
Then thought that it can be  Encoding issue so tried to pass different encoding formats to StreamWriter but was unlucky in that too. I tried to identify in depth and reached to the problem and then solution.

Problem:
As my values were in Html format it were containing “t” or “n” or “r” which were creating an issue when writing a file using StreamWriter. As it get “t” or “n” or “r” it was breaking the file.

Read More

Migrate Visual Studio Solution from SVN to TFS

I love to work on Microsoft Technologies and while working with them recently we got a challenge to migrate our project from SVN to TFS. So I would be discussing about:
1) How to migrate visual studio solution from SVN to TFS.
2) Different approaches for migration
3) Challenges faced during migrating our solution.
As it is our basic approach to first always search on google and do some analysis and research before doing any such task, similar way we did and found two approaches – Manual and Automated.
SVN2TFS.EXE – (Automated) we didn’t dig much also read few comments by which we got unhappy.

Read More

Sitecore Smart HTML Cache Clearance

Hello, Folks, I hope you are all doing well.

Smart HTML Cache clearance – As the name suggests it clears HTML Cache for a site in a smarter way.

In Sitecore Content tree if you are building a site for two or more different countries/regions and as you publish any content in any of the sites that you can observe via Cache.aspx that HTML Cache for each site gets cleared. Which should not happen.

So in order to achieve this goal, I did analysis and found that we have to override the default implementation of cache clearance when we publish any item in the content tree. But what if we publish any template or media item or anything other than content than at that time whole HTML cache should get clear. Also when we publish the whole site at that time HTML cache for all the sites should get clear. Smart HTML Cache Clearance will handle all the scenarios efficiently and accurately when you publish any item on local or on remote site. Also when it needs to clear the entire HTML Cache for all the sites than the default implementation, as written by Sitecore, will handle our job.

So whenever we face such challenges we google it, so similarly I did and found the blog of Mark Stiles ( https://markstiles.net/Blog/2011/05/26/partial-html-cache-clearing.aspx ), which helped me to achieve the objective but that was for remote publishing, what if Sitecore is enabled on the production server? Or what if we want to test it in local? So for that, I tried to modify the code and got the solution.

Step 1: Create a class called SmartHtmlCacheClearer in your library.
public class SmartHtmlCacheClearer
    {
        #region Fields
        private readonly ArrayList _sites = new ArrayList();
        #endregion
        #region Properties
        public ArrayList Sites
        {
            get
            {
                return this._sites;
            }
        }
        #endregion
        #region Methods
                
        /// This method is called when publish:end or publish:end:remote events are triggered.
        public void ClearCache(object sender, EventArgs args)
        {
            Assert.ArgumentNotNull(sender, "sender");
            Assert.ArgumentNotNull(args, "args");
            try
            {
                Database database = null;
                Guid emptyGuid = Guid.Empty;
                //This will run on the local targets
                if (args.GetType().ToString().Equals("Sitecore.Events.SitecoreEventArgs",StringComparison.InvariantCultureIgnoreCase))
                {
                    SitecoreEventArgs eventArgs = (SitecoreEventArgs)args;
                    if (eventArgs.Parameters != null)
                    {
                        var publishOptions = ((Sitecore.Publishing.Publisher)(eventArgs.Parameters[0])).Options;
                        database = Factory.GetDatabase(publishOptions.TargetDatabase.Name);
                        ClearHtmlCache(database, publishOptions.RootItem != null ? publishOptions.RootItem.ID.ToGuid() : emptyGuid);
                    }
                }
                //THIS WILL RUN ON THE REMOTE TARGETS
                if (args.GetType().ToString().Equals("Sitecore.Data.Events.PublishEndRemoteEventArgs", StringComparison.InvariantCultureIgnoreCase))
                {
                    PublishEndRemoteEventArgs remoteEventArgs = (PublishEndRemoteEventArgs)args;
                    database = Sitecore.Configuration.Factory.GetDatabase(remoteEventArgs.TargetDatabaseName);
                    ClearHtmlCache(database, remoteEventArgs.RootItemId != null ? remoteEventArgs.RootItemId : emptyGuid);
                }
            }
            catch (Exception ex)
            {
                Log.Error("Error while Clearing HTML Cache : " + ex.Message, this);
            }
        }

        /// This method will verify that whether to clear the HTML cache for any particular site or for all sites and it will also clear the HTML Cache for particular site if verfication is for particular site.
        private void ClearHtmlCache(Database database, Guid ItemGuid)
        {
            if (database != null)
            {
                Item currentItem = database.GetItem(new ID(ItemGuid));
                if (currentItem != null)
                {
                    Item startItem = currentItem.HomeItem();
                    //If startItem is not Site Root item then we will clear full HTML caches
                    if (startItem != null && startItem.TemplateID.ToString().Equals(TemplateIdHelper.TemplateIds.SiteRoot, StringComparison.InvariantCultureIgnoreCase))
                    {
                        bool isSiteHTMLCacheCleared = false;
                        var siteInfo = currentItem.GetSiteInfo();
                        SiteContext siteContext = Factory.GetSite(siteInfo.Name);
                        Log.Info("SmartHtmlCacheClearer started clearing HTML cache of " + siteInfo.Name + " site.", this);
                        if (siteContext != null)
                        {
                            HtmlCache htmlCache = CacheManager.GetHtmlCache(siteContext);
                            if (htmlCache != null)
                            {
                                htmlCache.Clear(true);
                                isSiteHTMLCacheCleared = true;
                            }
                        }
                        if (isSiteHTMLCacheCleared)
                            Log.Info("SmartHtmlCacheClearer successfully cleared HTML cache of " + siteInfo.Name + " site.", this);
                        else
                            Log.Info("SmartHtmlCacheClearer failed while clearing HTML cache of " + siteInfo.Name + " site.", this);
                    }
                    else
                    {
                        //If startItem is anything other than Content Item (e.g. Template Item or Media Library Item) than clear HTML Cache for all sites.       
                        ClearFullCache();
                    }
                }
                else
                {
                    //If currentItem is null. It means user selected Publish Site option.
                    //Clear Full HTML Cache
                    ClearFullCache();
                }
            }
            else
            {
                Log.Warn("SmartHtmlCacheClearer Failed as Target Database is null.", this);
            }
        }

        /// This method will clear the Full HTML Cache
        private void ClearFullCache()
        {
            Log.Info("SmartHtmlCacheClearer clearing HTML caches for all sites (" + this._sites.Count + ").", this);
            for (int iIndex = 0; iIndex < this._sites.Count; iIndex++)
            {
                string siteName = this._sites[iIndex] as string;
                if (siteName != null)
                {
                    SiteContext site = Factory.GetSite(siteName);
                    if (site != null)
                    {
                        HtmlCache htmlCache = CacheManager.GetHtmlCache(site);
                        if (htmlCache != null)
                        {
                            htmlCache.Clear();
                        }
                    }
                }
            }
            Log.Info("SmartHtmlCacheClearer done.", this);
        }
        #endregion
    }

Step 2: Replace publish:end and publish:end:remote handler to refer the SmartHtmlCacheClearer class in web.config

Now we have to add the reference to this class to the events section in web.config file and allow Sitecore to execute this code instead of Sitecore default code.

We just have to modify the handler for publish:end and publish:end:remote.

 <handler method="ClearCache" type="ABC.WCMS.Extensions.Pipelines.PublishItem.SmartHtmlCacheClearer, ABC.WCMS.Extension"></handler>  
 <handler method="ClearCache" type="ABC.WCMS.Extension.Pipelines.PublishItem.SmartHtmlCacheClearer, ABC.WCMS.Extension"></handler>
That’s it.

Note: Please specify the exact method name in handler which should be executed.

Happy Sitecoring.!

Setup SVN on Local Network

Subversioning plays a very vital role for Developers. It keeps track of changes to a file over time. It maintains the history of all the changes. This way you do not end up with millions of copies of the project that you cannot make heads or tails out of.  With a version control system, every time you commit a set of changes you write a comment describing what you did. Then you can look at the log to see what was changed when and by whom. You can easily look at the differences between versions and easily roll back changes if you need to. You also always have easy remote access to the current version of your project without having to remember which file name you used for it: you simply do an update of your working directory or check out the head version. For more information regarding version control please refer: http://en.wikipedia.org/wiki/Revision_control

Read More

Quick way to deploy web application to multiple environment.

Hello, Folks. It’s really interesting to know about MSBuild. Recently while working on one project we found that deploying Project Files on multiple environments consumes a lot of time. So we thought to take the help of MSBuild and deploy project files on live Server(s) automatically.
What is MSBuild?
MSBuild is Microsoft Build Engine for Visual Studio. MSBuild is completely transparent with regards to how to process and build software developed in Visual Studio.
Why MSBuild?
Initially from Visual studio we do publish via Publish Profile(s). MSBuild uses that publish profile and does deployment without the help of visual studio. It can reduce deployment time up to 70%.
This is the basic Dev environment which I have created to demonstrate you on Automatic Build. Developer can publish files to staging as well production Environments.
How MSBuild?
MSBuild command needs few command line options mainly MSBuild.exe, Visual Studio Project Solution File (.sln), and Publish Profile.
First of all, you need to get the path of MSBuild.exe in my case it is located at C:WindowsMicrosoft.NETFramework64v4.0.30319msbuild.exe
Create a new File and enter the below two MSBuild Commands. (Note: You need to change the path according to your project solution directory.)
"C:\Windows\Microsoft.NET\Framework64\v4.0.30319\msbuild.exe"
"C:\Users\npunjabi\Documents\Visual Studio 2013\Projects\DeveloperEnvironment\DeveloperEnvironment.sln"
/p:DeployOnBuild=true /p:PublishProfile "C:\Users\npunjabi\Documents\Visual Studio 2013\Projects\DeveloperEnvironment\DeveloperEnvironment\PropertiesPublish\ProfilesStaging.pubxml"
 
"C:WindowsMicrosoft.NETFramework64v4.0.30319msbuild.exe"
"C:\Users\npunjabi\Documents\Visual Studio 2013\Projects\DeveloperEnvironment\DeveloperEnvironment.sln"
/p:DeployOnBuild=true /p:PublishProfile"C:\Users\npunjabi\Documents\Visual Studio 2013\Projects\DeveloperEnvironment\DeveloperEnvironment\PropertiesPublish\ProfilesProduction.pubxml"
/p:DeployOnBuild=true – This will build the solution before deployment and will throw an error if build fails before it deploys the files.
Save this file with any name and provide extension as “.bat”.
Open Command Prompt in Administrator Mode and execute the MSBuild (.bat) file.
Note: If you are using SVN then before deployment you can also write the SVN Command which will update the solution. After that MSBuild.exe will build the code and then publish.
Please download this file for more user-friendly deployment file which will prompt the user for deployment whether to start deployment or not on particular servers. Thanks to Kiran Sir (http://kiranpatils.wordpress.com/) for helping me in creating deployment file.

To know more about Web Deploy: Click HereIf you have a better idea do share with us.

Have a nice Deployment! 🙂

PHP Mailer script to send Contact Us form email.

If the website is running on PHP Server than it’s just easy to create Form. It will only take fifteen to twenty minutes to build a form on a website. The simple static website can also be customized to have a contact us or any other form.
Let’s begin by writing a simple html code for form.
 <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">  
 <div class="container" style="background-color:grey; text-align:center; ">  
 <h4><u>Send me a message</u></h4>  
 <form id="contactForm" action="send_form_email.php" method="post">  
      <div class="row">  
           <div class="col-md-6 form-group">  
                <span style="background-color: #FFFF00"><input type="text" class="form-control" name="senderName" id="senderName" placeholder="name"></span><br/>  
                <input type="email" class="form-control" name="senderEmail" id="senderEmail" placeholder="e-mail"><br/>  
                <input type="text" class="form-control" name="subject" id="subject" placeholder="Subject">  
           </div>  
           <div class="col-md-6 form-group">  
                <textarea name="message" class="form-control" id="message" placeholder="Message"></textarea>  
           </div>  
           <div class="col-md-12 form-group">  
                <button type="submit">Send Message</button>  
           </div>  
      </div>  
 </form>  
 </div>  
 
Note: Please remember the name that have been given to textboxes and text area. We have to use same name in PHP script. And the file must be located where our .html file is stored as we have directly specified send_form_email.php in action parameter. If you have placed somewhere else then do specify the proper path. 

Now let’s write the PHP script to send an email.
Create a file send_form_email.php

Copy the below code.

 <?   
   $to = "info@yourdomain.com";   
   $from = "";   
   $subject = "";   
   $message = "";  
   if (isset($_POST["senderEmail"])) {  
   $from = $_POST["senderEmail"]; // sender  
      $name = $_POST["senderName"];  
   $subject = $_POST["subject"];  
      $message.="Name: ";  
      $message.=$_POST['senderName'] . "<br/>";  
      $message.="Message: ";  
   $message .= $_POST['message'];  
   $headers = "From: $fromrn";   
   $headers .= "Content-type: text/htmlrn";   
   mail($to, $subject, $message, $headers);   
      }  
   header('Location: http://www.yourdomain.com');  
 ?>  

 

We need to change the $to email id to wherever you want to send an email.
As the form is submitted by the user and the form is successfully sent then we have to redirect the user to any page. So for that we have to change the header location as per requirement. Here we have redirected to our actual domain site.
Note: This will only work on PHP Server. If we try to submit the form on our local machine then we will see the php file appearing but on live server the actual mail will be sent.
 
For seeing the Demo of this application CLICK HERE.
If you were looking for something and this helped? Or if you
have any other better idea? Feel free to share with us!

Happy Coding!

Sitecore Workflow QuickStart Guide: Part-3

This series is divided into three parts:
Part 1 : Sitecore Workflow QuickStart Guide : Part-1
Part 2 : Sitecore Workflow QuickStart Guide : Part-2
Part 3 : Sitecore Workflow QuickStart Guide : Part-3In Part-2, we saw creating roles and users and assigned workflow states based on our requirement.

When the reviewer clicks the Approve command, Sitecore triggers the Validation Action, which checks that the item has no validation errors. This occurs because the Approve command includes a Validation action. The validation action will cancel the movement of the item from the Awaiting Approval state to the Approve and Publish state if it finds errors.
If the validation action finds no errors, the Approve command moves the item to the Approve and Publish state.
Let’s do practical.
We won’t allow the duplicate workflow item name allowed to be published.
So when sitecoreReviewer try to approve any ProductPublishingWorkflow item with duplicate name then the guy will get an
error and reviewer won’t be allowed to approve that item.
Now where do comments go when Editor/Reviewer/Publisher apply comments to a workflow item?
You can see comments in the History section in Review Tab.
Let me know if you face any challenges or if you have any better idea. Suggestions/Comments/Feedback are most welcome.
I am very much thankful to Brijesh Patel (www.techitpro.com), Nilesh Thakkar (www.nileshthakkar.com) and Kiran Patil (sitecorebasics.wordpress.com) for helping me out in understanding the fundas.
References: