How to Minify CSS using YUI Compressor

Posted On // 1 comment
Problem:
When you analyze your page speed with Google PageSpeed Insights you can see this suggestion "Compacting CSS code can save many bytes of data and speed up download and parse times".

You could refer to Google's Minify Resources (HTML, CSS, and JavaScript)
Solution:

  1. Download YUI Compressor
  2. Ensure install the latest JVM
  3. Run this command line to minify CSS

java -jar yuicompressor-[version].jar --type css -v [input file path] -o [output file path]
[Read more]

Compressing resources with gzip or deflate can reduce the number of bytes sent over the network

Posted On // Leave a Comment
Problem:
Using Google PageSpeed Insights to measures the performance of a page for mobile devices and desktop devices.

There is a suggestion "Compressing resources with gzip or deflate can reduce the number of bytes sent over the network."

You could refer to Google's "Enable compression" suggestion

Solution:
To resolve this problem on Apache server, please try to enable gzip compression by modifying your .htaccess file.


# ######################################################################
# # WEB PERFORMANCE                                                    #
# ######################################################################

# ----------------------------------------------------------------------
# | Compression                                                        |
# ----------------------------------------------------------------------

<IfModule mod_deflate.c>

    # Force compression for mangled `Accept-Encoding` request headers
    # https://developer.yahoo.com/blogs/ydn/pushing-beyond-gzipping-25601.html

    <IfModule mod_setenvif.c>
        <IfModule mod_headers.c>
            SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding
            RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding
        </IfModule>
    </IfModule>

    # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    # Compress all output labeled with one of the following media types.
    #
    # (!) For Apache versions below version 2.3.7 you don't need to
    # enable `mod_filter` and can remove the `<IfModule mod_filter.c>`
    # and `</IfModule>` lines as `AddOutputFilterByType` is still in
    # the core directives.
    #
    # https://httpd.apache.org/docs/current/mod/mod_filter.html#addoutputfilterbytype

    <IfModule mod_filter.c>
        AddOutputFilterByType DEFLATE "application/atom+xml" \
                                      "application/javascript" \
                                      "application/json" \
                                      "application/ld+json" \
                                      "application/manifest+json" \
                                      "application/rdf+xml" \
                                      "application/rss+xml" \
                                      "application/schema+json" \
                                      "application/vnd.geo+json" \
                                      "application/vnd.ms-fontobject" \
                                      "application/x-font-ttf" \
                                      "application/x-javascript" \
                                      "application/x-web-app-manifest+json" \
                                      "application/xhtml+xml" \
                                      "application/xml" \
                                      "font/eot" \
                                      "font/opentype" \
                                      "image/bmp" \
                                      "image/svg+xml" \
                                      "image/vnd.microsoft.icon" \
                                      "image/x-icon" \
                                      "text/cache-manifest" \
                                      "text/css" \
                                      "text/html" \
                                      "text/javascript" \
                                      "text/plain" \
                                      "text/vcard" \
                                      "text/vnd.rim.location.xloc" \
                                      "text/vtt" \
                                      "text/x-component" \
                                      "text/x-cross-domain-policy" \
                                      "text/xml"

    </IfModule>

    # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    # Map the following filename extensions to the specified
    # encoding type in order to make Apache serve the file types
    # with the appropriate `Content-Encoding` response header
    # (do note that this will NOT make Apache compress them!).
    #
    # If these files types would be served without an appropriate
    # `Content-Enable` response header, client applications (e.g.:
    # browsers) wouldn't know that they first need to uncompress
    # the response, and thus, wouldn't be able to understand the
    # content.
    #
    # https://httpd.apache.org/docs/current/mod/mod_mime.html#addencoding

    <IfModule mod_mime.c>
        AddEncoding gzip              svgz
    </IfModule>

</IfModule>

The following snippet code extracted from sample configuration files of Apache HTTP server boilerplate configs project
Next, you can also use this Gzip compression test tool to check if gzip compression is enabled on your site or not.
[Read more]

Install log4net in SharePoint 2007

Posted On // Leave a Comment

Step 1 Download the latest version of log4net library
Step 2 Add log4net reference to your project
Step 3 Add log4net assembly to GAC
Step 4 Select your SharePoint web application. E.g.
C:\inetpub\wwwroot\wss\VirtualDirectories\88
Choose one of following steps (Step 5, Step 6):
Step 5 Add below line in your AssemblyInfo.cs file.
 
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "C:\\inetpub\\wwwroot\\wss\\VirtualDirectories\\88\\web.config", Watch = true)]
 
Step 6 Modify your SharePoint web application’s global.asax
 
C:\inetpub\wwwroot\wss\VirtualDirectories\88\global.asax
 
<%@ Assembly Name="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821" %>
<%@ Import Namespace="log4net" %>
<%@ Import Namespace="log4net.Config" %>
<%@ Import Namespace="System.IO" %>

<script language="C#" runat="server">
void Application_Start(object sender, EventArgs e)
    {   
    //string currentFolder = HttpContext.Current.Request.PhysicalApplicationPath;//Context.Request.PhysicalApplicationPath;
    //log4net.Config.XmlConfigurator.Configure(new FileInfo(currentFolder + "web.config"));
    log4net.Config.XmlConfigurator.Configure(new FileInfo("C:\\inetpub\\wwwroot\\wss\\VirtualDirectories\\88\\web.config"));     
    }
</script>
 
Step 7 Add below sections in your SharePoint web application’s web.config
 
C:\inetpub\wwwroot\wss\VirtualDirectories\88\web.config
 
<configSections>
  <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
  …
</configSections>
<log4net debug="true">
  <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
    <file value="[set your file path log here]" />
    <appendToFile value="true" />
    <rollingStyle value="Size" />
    <maxSizeRollBackups value="10" />
    <maximumFileSize value="10MB" />
    <staticLogFileName value="true" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%-5p %d %5rms %-22.22c{1} %-18.18M - %m%n" />
    </layout>
  </appender>
  <root>
    <level value="ALL" />
    <appender-ref ref="RollingLogFileAppender" />
  </root>
</log4net>
</configuration>

Snippet code using log4net in SharePoint Webpart
 
[Guid("857bb65a-fd9c-4294-9ddf-7f090d777267")]
    public class log4netWebPartTest : Microsoft.SharePoint.WebPartPages.WebPart
    {
        #region log4net
        private static readonly ILog _log = LogManager.GetLogger(typeof(log4netWebPartTest).Name);
        #endregion

        private bool _error = false;
        private string _myProperty = null;


        [Personalizable(PersonalizationScope.Shared)]
        [WebBrowsable(true)]
        [System.ComponentModel.Category("My Property Group")]
        [WebDisplayName("MyProperty")]
        [WebDescription("Meaningless Property")]
        public string MyProperty
        {
            get
            {
                if (_myProperty == null)
                {
                    _myProperty = "Hello SharePoint";
                }
                return _myProperty;
            }
            set { _myProperty = value; }
        }


        public log4netWebPartTest()
        {
            this.ExportMode = WebPartExportMode.All;
        }

        /// <summary>
        /// Create all your controls here for rendering.
        /// Try to avoid using the RenderWebPart() method.
        /// </summary>
        protected override void CreateChildControls()
        {
            if (!_error)
            {
                try
                {

                    base.CreateChildControls();

                    // Your code here...
                    this.Controls.Add(new LiteralControl(this.MyProperty));
                }
                catch (Exception ex)
                {
                    HandleException(ex);
                }
            }
        }

        /// <summary>
        /// Ensures that the CreateChildControls() is called before events.
        /// Use CreateChildControls() to create your controls.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnLoad(EventArgs e)
        {
            if (!_error)
            {
                try
                {
                    base.OnLoad(e);
                    this.EnsureChildControls();

                    try
                    {                       
                        File.ReadAllBytes(@"fileDoesNotExist.txt");
                    }
                    catch (FileNotFoundException ex)
                    {
                        if (_log.IsErrorEnabled)
                        {
                            _log.Error("OnLoad error: " + ex.Message);
                        }

                    }
                }
                catch (Exception ex)
                {
                    HandleException(ex);
                }
            }
        }

        /// <summary>
        /// Clear all child controls and add an error message for display.
        /// </summary>
        /// <param name="ex"></param>
        private void HandleException(Exception ex)
        {
            this._error = true;
            this.Controls.Clear();
            this.Controls.Add(new LiteralControl(ex.Message));
        }
    }



















[Read more]

Hotfix KB2731284 or later update is not installed, will zero -out data files

Posted On // Leave a Comment
Problem:
There is an error while I am trying to start MongoDB server
Hotfix KB2731284 or later update is not installed, will zero -out data files
My environment:

  • Windows 7 64 bit
  • MongoDB version 3.0.3
Solution:
Try to run mongod.exe --dbpath [your path to data folder]
I did not install this Hotfix KB2731284. You can install this hotfix if it does not work for you.
[Read more]

“Instruments failed to start the app”

Posted On //
Problem:
When you are running tests using Xamarin UITest against an iOS physical device, there might be an error “Instruments failed to
start the app.”
Solution:
To resolve this problem, you could follow these steps to enable UIAutomation from your computer
  1. Ensure iOS SDK version in OS X is greater or equal to iOS version on real device
  2. Disconnect your iOS real device from your computer
  3. Open XCode > Open Devices 
  4. Connect your iOS device to your computer, and then Select your real device
  5. This step might apply to iOS 8.x, please look at this Device Configuration link on Xamarin site
  6. Open Instruments: Open Xamarin Studio > Tools > Launch Instruments

  7. Choose Automation
  8. Choose the app that you want to run UI automation on you real device
  9. Press Record button
  10. Wait a minute for the app running and then quit without saving
  11. Now you could run your Xamarin UITest using Xamarin Studio
[Read more]

Add workflow association to specific list in SharePoint 207

Posted On // 2 comments
Here is my snippet code how to create a workflow association that can then be added to a list.
/// <summary>
        /// Add workflow association to specific list
        /// </summary>
        /// <param name="siteId">Site collection object</param>
        /// <param name="webId">SharePoint website object</param>
        /// <param name="strWorkflowAssociateToListTitle">List title of SPList object will be associated workflow</param>
        /// <param name="workflowName">The name of the desired workflow association.</param>
        /// <param name="workflowId">Workflow template based on template ID</param>
        /// <param name="workflowHistoryListTitle">List title of Workflow History list</param>
        /// <param name="taskListTitle">List title of Task List</param>
        /// <param name="autoStartWorkflowCreate">A Boolean that represents whether the workflow starts 
        /// automatically when a new item is created.</param>
        public static void AssociateWorklowToList(Guid siteId, Guid webId, string strWorkflowAssociateToListTitle, string workflowName,
                 Guid workflowId, string workflowHistoryListTitle, string taskListTitle, bool autoStartWorkflowCreate)
        {
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (SPSite siteCollection = new SPSite(siteId))
                {
                    siteCollection.AllowUnsafeUpdates = true;
                    using (SPWeb site = siteCollection.OpenWeb(webId))
                    {
                        bool allowUnsafeUpdates = false;
 
                        allowUnsafeUpdates = site.AllowUnsafeUpdates;
                        site.AllowUnsafeUpdates = true;
 
                        SPListCollection lists = site.Lists;
                        ////a workflow association that can then be added to a this list.
                        SPList workflowAssociateToList = lists[strWorkflowAssociateToListTitle];
                        ////workflow history list
                        SPList workflowHistoryList = lists[workflowHistoryListTitle];
                        ////task list
                        SPList taskList = lists[taskListTitle];
 
                        SPWorkflowAssociation 
                                existingAssociation = workflowAssociateToList.WorkflowAssociations
                                        .GetAssociationByName(workflowName, 
                                                System.Globalization.CultureInfo.CurrentCulture);
                        if (existingAssociation == null)
                        {
                            SPWorkflowManager workflowManager = siteCollection.WorkflowManager;
                            SPWorkflowTemplateCollection templates = workflowManager.GetWorkflowTemplatesByCategory(site, null);
                            SPWorkflowTemplate template = templates.GetTemplateByBaseID(workflowId);
                            SPWorkflowAssociation association = SPWorkflowAssociation.CreateListAssociation(template, workflowName, taskList, workflowHistoryList);
 
                            ////the key solution
                            site.Update();
 
                            association.AllowManual = true;
                            association.AutoStartCreate = false;
 
                            workflowAssociateToList.AddWorkflowAssociation(association);
                            workflowAssociateToList.Update();
                            association.Enabled = true;
                        }
 
                        site.AllowUnsafeUpdates = allowUnsafeUpdates;
                    }
                }
            });
 
        }
[Read more]

Update SPListItem in workflow SharePoint

Posted On // Leave a Comment

Problem:

In workflow SharePoint context
SPListItem itemAssociateWithWorkflow =  this.workflowProperties.Item;
itemAssociateWithWorkflow["Your field name"] = "your value";
itemAssociateWithWorkflow.Update();
After update successfully, that item will be modified by “System Account” that means field Modified By has value System Account

Solve:

SPUser currentUser = GetCurrentUserInWorkflow(this.workflowProperties);
////impersonate real current user
using (SPSite site = new SPSite(this.workflowProperties.Web.Site.ID, currentUser.UserToken))
{
    using (SPWeb webCurrentUser = site.OpenWeb(this.workflowProperties.Web.ID))
    {
     SPListItem itemCurrentUser = webCurrentUser.Lists  [this.workflowProperties.ListId].GetItemById(this.workflowProperties.ItemId);
        itemCurrentUser["your field name"] = "your value";
        itemCurrentUser.Update();
    }
}
[Read more]