Showing posts with label tips and tricks. Show all posts
Showing posts with label tips and tricks. Show all posts

15 December 2010

5 worst code smells in Sitecore

Last year I wrote a blog post on doing code reviews on Sitecore. While dealing with conceptual issues it doesn’t really say what to look for in code, when evaluating the quality or to evaluate if any wrong decisions have been made when developing the solution.  Therefore I wanted to wright a post about the top 5 code smells I look for, when I am trying to evaluate or trouble shoot a Sitecore solution. These code smells often indicate that the developers have gone down the wrong road and there is something fundamentally wrong in the architecture.
So here goes:
1) Using the descendant axes in xpath expressions:
This one I especially look for, when I am looking at a site which doesn’t perform. It may be used in some cases, but very often I find that a developer has used this to generate relations between content and thereby iterating over the complete content tree. This works fine in development where there are a few hundred content items. However in production where thousands of items are created this simply breaks the performance of the site – especially after publishing which clears the HTML cache.
The descendants can be accessed in multiple ways. In XSLT it normally looks like this:
<xsl:for-each select=”$sc_currentitem/descendant-or-self::item”>
</xsl:for-each>Or like this:
<xsl:for-each select=”$sc_currentitem//item”>
</xsl:for-each>
In C# using the Sitecore API it is most often accessed like this:
item.Axes.GetDescendants()
2) XSLT Import:
This is related to a point in the post about code reviews on Sitecore, where I argue that overcomplicated functionality and logic in XSLTs, is a problem. If you need to do an import of another XSLT in your rendering, you probably do it to call a method or in another way try and reuse functionality. If you want to do this, don’t use XSLTs! XSLTs should only – if you really want to use them at all – hold simple presentations.
XSLTs can be imported like this:
<xsl:import href=”YourOtherXslt.xslt” />
3) Explicitly accessing the master database
Although this can be needed in some cases and especially in scheduled tasks or other backend functionality, most often it is because the developer haven’t thought the issue through or if they have made a wrong decision of how data entered by the user should be stored.
The master database is most often used like this in c#
Database masterDatabase = Database.GetDatabase(“master”);
If you see a call like this, your solution is most likely not ready for staging, where there is no access to the master database from the content delivery server. You should generally use something like this:
Database database = Sitecore.Context.Database ?? Sitecore.Context.ContentDatabase;
This means you operate on the context database and on the content delivery databases this will be the web database and in preview you will use the master database, which is probably what you want.
If you need to write something to the master database, you first need to decide if this is a good idea at all. If you write to the master database from your frontend, you make yourself vulnerable for malicious attack, as people from the outside can enter data into the master database. Normally we handle user entered data in a custom database or parse all user created content to ensure that the master database won’t be flooded with data.
If you really need to access the master database, you should create a service that handles access to the master database, so that your solution is ready for staged environments.
4) XSLT extension over 100 lines of code:
This point is closely related to point number 2, but I really see a lot of issues with XSLTs which have been used wrong and this creates a lot of issues later on in the project lifecycle. If you have an XSLT extension with over a hundred lines of code, chances are, that the developer made a wrong decision when creating the XSLT; instead he/she should have created a sublayout.
XSLT extensions are functional programming and you should use an object oriented approach, so my advice is not to use XSLTs at all, unless you are doing something really simple. Otherwise your solution will become harder and harder to maintain, as utility methods like the XSLT extensions are very hard to understand and couplings in the renderings themself are difficult to map.
You can find all registered XSLT extensions in the web.config under xslExtension and it looks something like this:


   1:  <xslExtensions>
   2:   
   3:    <extension mode=”ontype=”MyNamespace.XslHelper, MyAssemblynamespace=”http://www.example.net/helpersingleInstance=”true/>
   4:  </xslExtensions>
5) Clearing of cache
This may seem obvious to some, but I have seen surprisingly many methods, which cleared the entire Sitecore cache including the data and item cache. If you see this in your code and it is needed, chances are, that you have an architectural issue in your solution. It should most rarely be needed to clear the cache, unless it is after a publish and Sitecore handles this automatically. I have heard many reasons for clearing the cache including an issue, where the developer argued that it was necessary, as he wrote directly to the Sitecore database with a SQL statement, and then Sitecores cache wasn’t updated.
If you experience something like this, the issue is of cause not the cache, but that you don’t use the Sitecore API to read and write data from the database.
The caching is most often cleared like this:
CacheManager.ClearAllCaches();
This is just some of the things I have seen many times, but I know there are many other bad code smells when developing Sitecore solution. Do you have any other code smells to share?
~ by Jens Mikkelsen
Source:- http://mcore.wordpress.com/2010/08/03/5-worst-code-smells-in-sitecore/

Sitecore friendly html, css and javascript

Disclaimer: While some of these guidelines may be applied to other Content Management Systems, or .net web forms in general, this is based on my experience with Sitecore.
A common approach of having a CMS based web site implemented usually goes as follows:
  1. Company X (aka 'The Client') approaches a design firm.
  2. Said design firm paints a lot of pretty pictures (also known as wire-frames, mock-ups, etc..), which the client gets sold on
  3. The design firm (or a subcontractor) will cut up those pretty pictures into HTML/CSS/JS files.
  4. That design firm chooses a Sitecore partner to do the implementation of their super clean front-end work.
While I am greatly generalizing, this is a common approach. The point I am hoping to address is that design firms (who aren't familiar with .net or Sitecore) are very likely to make things difficult for the implementation team. Here are a few issues I have seen over the last few projects.
ID attribute on html elements
This is another broad statement, but take it at face-value to avoid problems. Front end developers will reference an element via the id attribute for css styling as well as jQuery (or any other client side framework) manipulations. While this sounds like a very normal approach it can lead to issues when that element gets converted into a .NET Server control and this tag:
1
<input name="q" id="q" type="text" />
is now this tag:
1
<input name="ctl00_Main_q" id="ctl00_Main_q" type="text" />
This annoying rewrite of the id attribute will break all pre-written css and javascript written for that id. As back-end developers we know that only id's of server controls (or regular tags with runat="server") will be rewritten, but is easier to have front-end dev's avoid referencing elements by id them all together.
HTML Patterns
In general, repeating patterns are very easy to program. Avoid throwing unnecessary id's and classes on elements. A perfect example would be for navigation elements; a side menu should be a simple nested unordered list with no extra classes. Having classes that change based on content, depth in site, etc... it will require logic, which takes time to implement.
Do this:




 

    

<h1>Nav Header</h1>

    <ul>

        <li><a href="#">Level 1a</a>

            <ul>

                <li><a href="#">Level 2a</a></li>

                <li><a href="#">Level 2b</a></li>

                <li><a href="#">Level 2c</a></li>

            </ul>

        </li>

         <li><a href="#">Level 2a</a>

            <ul>

                <li><a href="#">Level 2a</a></li>

                <li><a href="#" class="selected">Level 2b</a></li>

                <li><a href="#">Level 2c</a></li>

            </ul>

        </li>

    </ul>

Not this:

 

    

<h1>Nav Header</h1>

    <ul class="mainNav">

        <li class="first"><a href="#">Level 1a</a>

            <ul class="subnav">

                <li class="first"><a href="#">Level 2a</a></li>

                <li><a href="#">Level 2b</a></li>

                <li class="last"><a href="#">Level 2c</a></li>

            </ul>

        </li>

         <li class="last"><a href="#">Level 2a</a>

            <ul class="subnav">

                <li class="first"><a href="#">Level 2a</a></li>

                <li><a href="#" class="selected">Level 2b</a></li>

                <li class="last"><a href="#">Level 2c</a></li>

            </ul>

        </li>

    </ul>




Obviously this is an overly simplistic menu system that cannot always be accomplished. My main point here is to avoid classes on elements that aren't absolutely necessary. We can use basic css selectors to get at elements without having to provide more classes to denote first and subnav.
Modularity
If you have ever seen a Sitecore sales demo you have undoubtedly seen the presenter effortlessly change the layout of the page. Possibly adding some 'widgets' to the side or changing the entire layout from two to three columns? Sitecore allows renderings and sublayouts to be placed within placeholders. This introduces a lot of flexibility for the design of site, however, it does require a lot of forethought to make sublayouts look nice in multiple locations.
In order to make your sublayouts (or any other custom 'widgeting' system) work and look great you should follow a couple guidelines.
  1. Keep your html super lean and clean.
  2. Object Oriented Css
Design Images
This is just my preference on how to organize the file system of a Sitecore site and you may have your own system and that is fine. Whatever system you choose, just be consistent as sites can grow big quickly and managing these little files can become daunting.
  • Images referenced from css files should go in an "images" directory underneath the css directory. Furthermore, keep image paths relative to the css file.
  • Any leftover images required for the design should go in a /images directory.
  • Placeholder images should be prefixed with "fpo_" which makes it easy to identify these images as being good candidates to be moved into Sitecore media library.
Multi-Lingual Considerations
Manipulating the DOM with Javascript is trivial with the introduction of client libraries such as jQuery. A potential issue will arise when a developer hard codes in a language specific string (such as 'open,' 'close,' etc...) in a javascript function. In order to avoid this pitfall have the translatable text reside in a hidden span on the page, not in the javascript code.

Author:- Sean Kearney
Source:- http://seankearney.com/post/Sitecore-friendly-html-css-and-javascript.aspx