Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


These support forums are now closed for new topics and comments.
Please head on over to http://eureka.ucommerce.net/ for support.

  • Damian Green 452 posts 1433 karma points
    Mar 22, 2012 @ 23:54
    Damian Green
    0

    A little bit of help with getting going with the API and SiteContext and Catalogues please

    Hi,

    I am wanting to rewrite the all the various xslt macros into razor to get a good knowledge of ucommerce - and im not keen on working with xsl... much prefer razor!

    I have looked around for info on getting the site context etc. but im just missing something.  An explanation of the context and getting started with the API would be handy info in the ucommerce docs as the API reference doesnt help much when learning how to use it.

    I have got some things working but have got stuck with creating a breadcrumb for the currently selected product which ought to be pretty simple - however its not happeing for me!

    Questions.. 

    Is the site context set automatically when you call it? 

    Im not sure of the reasons why you have to get the catalogue, catalogueset, category etc.. just to get to a product and its parents.... maybe im going about it wrong? But i keep getting a null reference when using code from examples from Sorens blog.  Why cant i get directly at a product with an ID from the context and get its parents up the tree from that product?

    When working with the API do you have to use the query strings to get at the magix numbers for the category etc of are these pulled in when using the site context?

    This is what ive tried to get the current catalog but catalog end up as null:

    var urlService ObjectFactory.Instance.Resolve<IUrlService>();
        
    var catalogContext SiteContext.Current.CatalogContext;

    ProductCatalogGroup catalogGroup catalogContext.CurrentCatalogSet;
        
    ProductCatalog catalog ProductCatalog.All().SingleOrDefault(pc =pc.Name == catalogContext.CurrentCatalogName);

     

    Sorry if ive rambled a bit... im new to uCommerce and this is my first store so just a bit confused as to the structure of things until i find my way around.

     

  • Damian Green 452 posts 1433 karma points
    Mar 22, 2012 @ 23:58
    Damian Green
    0

    Sorry - the last line should read (but cant edit):

    ProductCatalog catalog = ProductCatalog.SingleOrDefault(x => x.Name == catalogContext.CurrentCatalogName && x.ProductCatalogGroup.Name == catalogGroup.Name);

    -- above line catalog ends up null...

    then i woud go on to getting the product etc..

     

     Category category = Category.SingleOrDefault(x => x.Name == catalogContext.CurrentCategoryName);

        string categoryUrl = urlService.GetUrl(catalog, category);

        Product product = Product.SingleOrDefault(x => x.Sku == catalogContext.CurrentProductSku && x.ParentProductId == null);

     

     

    Sorry if ive rambled a bit... im new to uCommerce and this is my first store so just a bit confused as to the structure of things until i find my way around.

  • Søren Spelling Lund 1797 posts 2786 karma points
    Mar 23, 2012 @ 10:03
    Søren Spelling Lund
    0

    Hi Damian,

    The reason it's bit confusing at the moment is that when we did the high level API for uCommerce the main way of creating Umbraco sites was using XSLT. We never did a set of high level APIs for Razor. Some of the XSLT is pretty usable if you go via the Library class, but it's not at the level of awesomeness we expect from uCommerce :)

    The SiteContext and related CatalogContext and OrderContext are convenience APIs for figure out where you are on the site currently. They are, as you say, fed by strings from the query string by default so they require that you pass around catalog, category, and sku in the URLs for work. If you're using the default nice URLs the values will automatically be added to the URL at the end; in the form of ids instead of names.

    You can override the behavior by registered your own context implementations in the /umbraco/ucommerce/configuration/components.config where you decide how the context should be populated.

    You don't have to use the context though you can manage everything yourself and go straight to the Active Record API like you describe. Just go:

    int productId = Convert.ToInt32(Request.QueryString["productid"]);
    Product product = Product.Get(productId);

    And you're good to go.

    With Razor being the new and only model for doing site in Umbraco 5 we're investing in doing a simpler to understand high level API, which will incorporate all the lessons learned from previous site builds and feedback. Posts like your's will help do an even better job of getting it right, and I dare say that we've got a nice surprise on that front in stock for everybody at this year's Codegarden too :)

    I highly recommend take a look at the XSLT extensions using a tool like dotPeek from Jetbrains. It'll allow you to see the uCommerce source code almost as we do and give you a great understanding on how everything works.

  • Damian Green 452 posts 1433 karma points
    Mar 23, 2012 @ 11:12
    Damian Green
    0

    Hi Soren,

    Thanks for the quick reply.

    I understand what you are saying but still a little confused.  I also had a poke around in the source which helped a little too but i want to get a grip on the basics bfore i dive deep into the guts of the source! Ill do that when i get to extending! :)

    In relation to your example - i dont understand how the following line woudl work when i font have productid in a query string? Its just the url and have no routedata like in mvc for example. 

    int productId =Convert.ToInt32(Request.QueryString["productid"]); 

    The url I am seeing is for example:  /shop/category-name/product-name/c-23/c-72/p-110

    so how would the example work?

    Do you have an example using razor to build a simple breadcrumb using the sitecontext when on a product page? That would probably help me most - or even just the code to get the current product, current category, current catalogue and current catalogue set. If i know how to get those i'll be able to work the rest out i think.  Just need to get my head round setting the current context of where i am in the site so i can use razor to build the pages.

    Thanks again for the help!

    Damian

  • Damian Green 452 posts 1433 karma points
    Mar 24, 2012 @ 11:11
    Damian Green
    0

    Soren,

    I got there in the end! I went back to basics and pulled it all apart and created a debug script that output all the current context, catalogues, categories, products etc and straight away i caould see what was going on!

    What has confues me is the 

    SiteContext.Current.CatalogContext.CurrentCatalogName
    SiteContext.Current.CatalogContext.CurrentCategoryName

    I hadnt noticed that these return the ID not the name! So when i was trying to query and using the name it obviously wasnt finding it!

    Anyhow once i got these values and turned them into ints and did a simple Product.Get(id) it worked a treat.

    Ill post my breadcrumb macroscript below so you can check ive gone about it the right way and also someone else may find it useful.

    @using UCommerce.Catalog;
    @using UCommerce.Infrastructure;
    @using UCommerce.EntitiesV2;
    @using UCommerce.Runtime;

    @{     
        var urlService ObjectFactory.Instance.Resolve<IUrlService>();

        string catalogUrl string.Empty;
        string categoryUrl string.Empty;
        string productUrl string.Empty;
      
        int currentCatalog Int32.Parse(SiteContext.Current.CatalogContext.CurrentCatalogName);
      
        int currentCategory 0;
        Int32.TryParse(SiteContext.Current.CatalogContext.CurrentCategoryNameout currentCategory);
      
        int currentProduct 0;
        Int32.TryParse(SiteContext.Current.CatalogContext.CurrentProductSkuout currentProduct);

        var catalog ProductCatalog.Get(currentCatalog);  
        catalogUrl urlService.GetUrl(catalog);
        
        Category category null;
      
        if (currentCategory 0)
        {
          category Category.Get(currentCategory);    
          categoryUrl urlService.GetUrl(catalogcategory);
        }
        
        Product product null;
      
        if (currentProduct 0)
        {
           product Product.Get(currentProduct);
           productUrl urlService.GetUrl(catalogproduct);  
        }
    }

    <div class="breadcrumb">
       
       <href="/">Home</a\     
                     
       <href="@catalogUrl">@catalog.Name</a\     
       
      @if (category != null)
      {
           @:<href="@categoryUrl">@category.Name</a
      }
      @if (product != null)
      {
           @:<href="@productUrl">@product.Name</a>
      }
    </div>

  • Damian Green 452 posts 1433 karma points
    Mar 24, 2012 @ 11:18
    Damian Green
    0

    I'll also post my script I wrote to squirt out debug to show the underlying data objects of the store.  

    Its pretty basic and raw with very little formatting so apologies for that but its for debug reasons not prettyness!  It helped me no end in understanding catalogues, categories, groups etc. so if you are just getting started with razor, ucommerce or integrating your own store this script may just turn a few lighbulbs on for you!  Just paste it into a macroscript, create a macro and put that macro at the top of a product page.  It will then show whats behind the curtains! :)

    Hope it helps someone anyway.  

    Im still a little unsure about price groups and getting the price but i'll cross that bridge when i get to it!

    @using UCommerce.Catalog;
    @using UCommerce.Infrastructure;
    @using UCommerce.EntitiesV2;
    @using UCommerce.Runtime;

    <h2>Catalogue Group</h2>
    SiteContext.Current.CatalogContext.CurrentCatalogGroupName @SiteContext.Current.CatalogContext.CurrentCatalogGroupName

    <h2>Catalog Contexts</h2>   

    <h3>Current Catalogue Set</h3>
    SiteContext.Current.CatalogContext.CurrentCatalogSet.Name @SiteContext.Current.CatalogContext.CurrentCatalogSet.Name
    <br />
    <ul>
      <li>SiteContext.Current.CatalogContext.CurrentCatalogSet.Id @SiteContext.Current.CatalogContext.CurrentCatalogSet.Id</li>
      <li>SiteContext.Current.CatalogContext.CurrentCatalogSet.ProductCatalogGroupId @SiteContext.Current.CatalogContext.CurrentCatalogSet.ProductCatalogGroupId</li>
      <li>SiteContext.Current.CatalogContext.CurrentCatalogSet.Decription @SiteContext.Current.CatalogContext.CurrentCatalogSet.Description</li>
    </ul>

    <h3>Current Catalogue</h3>
    SiteContext.Current.CatalogContext.CurrentCatalogName @SiteContext.Current.CatalogContext.CurrentCatalogName
    <br />

    <h3>CurrentCategory</h3>

    SiteContext.Current.CatalogContext.CurrentCategoryName @SiteContext.Current.CatalogContext.CurrentCategoryName
    <br />

    <h3>Current Product</h3>
    SiteContext.Current.CatalogContext.CurrentProductSku @SiteContext.Current.CatalogContext.CurrentProductSku
    <br />

    <h2>Product Catalogues</h2>
    SiteContext.Current.CatalogContext.CurrentCatalogSet.ProductCatalogs List
    <br />

    @foreach (var pc in SiteContext.Current.CatalogContext.CurrentCatalogSet.ProductCatalogs)
    {
           @:pc.Name @pc.Name <br/>
           @:pc.Id @pc.Id <br/>
           @:pc.ProductCatalogGroup.Name @pc.ProductCatalogGroup.Name <br/>
           @:pc.ProductCatalogId @pc.ProductCatalogId <br/>

     
           <h4>Catalogue Price Group</h4>   
        
           @:pc.PriceGroup.Name@pc.PriceGroup.Name  <br />
           @:pc.PriceGroup.Id@pc.PriceGroup.Id <br />
           @:pc.PriceGroup.VATRate @pc.PriceGroup.VATRate <br />
           @:pc.PriceGroup.Currency.ISOCode @pc.PriceGroup.Currency.ISOCode <br />
     
        <h3>Categories</h3>   
        
        foreach (var pcCategory in pc.Categories)
        {                    
            <p>
            pcCategory.Name @pcCategory.Name <br />
            pcCategory.Id @pcCategory.Id <br />
            pcCategory.ParentCategoryId @pcCategory.ParentCategoryId <br />
            pcCategory.ProductCatalog.Name @pcCategory.ProductCatalog.Name <br />
            pcCategory.ProductCatalog.ProductCatalogGroup.Name @pcCategory.ProductCatalog.ProductCatalogGroup.Name <br />
            
            ===============================
            </p>        
        
            <h5>Products in cat (@pcCategory.Products.Count()):</h5>
       
            foreach (Product in pcCategory.Products)
            {
                <h5>Product@p.Name Id @p.Id</h5>     
                              
                <p>Product Variants (@p.Variants.Count)</p>
                
                 foreach (var in p.Variants)
                 {
                    <h6>Variant@v.Name Id @v.Id</h6>   
                     <p>Parent productID @v.ParentProductId</p>
                     <p>Price Group</p>
                     <h6>Price Group Prices</h6>
                        foreach (var pgp in v.PriceGroupPrices)
                        {
                            <p>Price group (@pgp.PriceGroup.NamePrice @pgp.Price</p>
                        }
                 }                         
            }
        }
    }    

  • Søren Spelling Lund 1797 posts 2786 karma points
    Mar 29, 2012 @ 14:33
    Søren Spelling Lund
    0

    Thanks for taking the time to post this. I know the naming scheme is a little confusing. It's like that to keep it backwards compatible. It will change for uCommerce 3 to match reality better :)

  • Damian Green 452 posts 1433 karma points
    Mar 29, 2012 @ 21:24
    Damian Green
    0

    No problem! :) Im enjoying building out this site and getting to know UCommerce! Sure it will get more interesting too once i start getting into the pipelines and checkout process as im just building macros, pages, menus and other navigation at the moment.  

    One area I have found cumbersome is getting the price and price of variants and descriptions.  Im thinking of wrapping it with my own API know im getting to grips with it... but i'll hang on till the new version to save a re-write! :)

     

Please Sign in or register to post replies

Write your reply to:

Draft