vsWe've blogged before back in 2010, and again in 2012 about possible VS project structures for developing in Umbraco, however, nowadays we use what we think is a pretty simple structure. The strange thing is, when we tell other developers how we work, we often get some funny looks/comments, mainly because we decide to take a pragmatic approach that works for us, rather than follow "best practise".

Basically, we use one solitary Visual Studio "Website" project to house the whole shibbang (ok, we may move things out to separate DLL's if it warrants it, but this is a special case for us, not the norm). Notice that we said "Website" project not "Web Application" project, this is what usually gets people confused. 

So why do we use websites projects?...simplicity!

By using website projects, all assets are available to us at all times. We don't have to do any clever pre build copying commands, or remember to include a file in the project if we copy anything over. What's on disk, is what's in our project.

But where does the code go?...the App_Code folder

By working direct in the App_Code folder we don't have to bother compiling, instead we let IIS Express take care of that when we reload the browser. Heck, you are going to have to do an app pool recycle anyway, so what harm's one itty-bitty compile going to add? Of course we keep the folder well organised and structured, but we just don't break everything out into a separate DLL's.

Don't you loose compile time checks?...yup

But we'll soon find out when we refresh the browser and get a pretty little YSOD telling us exactly where the error is :) We can still use breakpoints and debug the IIS worker process, we just find the errors in the browser, rather than in VS.

Aren't you worried someone will gain access to your server and change your code?...nope

If someone gets access to your server that shouldn't, then you've probably got bigger things to worry about. We find a daily backup is a good enough fallback to rollback a site should anything untoward happen. 

For us, having the source code on the server is actually a benefit. Ever been on holiday and had a client ringing you that their site is down? Most people's response is "Sorry, I don't have my dev tools with me, I'll have to get back to you in a week", whereas for us, we just jump on any PC, fire up RDP and make the change direct on the server (promptly followed by an email to ourselves to remember to resync when we get home :))

Oh boy!

At the end of the day, we are in the business of making websites. Not missile defence software or space shuttle guidance systems, every day, in the wild, websites. 

Obviously, the way we work isn't going to suite everyone, but for us Visual Studio, Umbraco and everything else we use is just a tool for getting the job done. If deviating from suggested "best practise" enables us to simplify the process of building website whilst still maintaining flexibility and delivering a quality finished project to our end clients on time that is easy to maintain, then we are going to take it.

Depending on how well this post goes down, maybe we'll write another post on why we write logic in our MVC views :) [Hint: Pretty much similar reasons]

imagesFor those developers who have been working in Umbraco for a while, you may be familiar with a great little package called CropUp, which allows you to do some amazing things with images including dynamic cropping based upon a focal point, and more relevant to this post, responsive images.

Unfortunately CropUp only works in Umbraco v6, but thankfully, Umbraco v7 now comes with its own inbuilt image cropper (very much inspired by CropUp) which supports most of the same cropping features as it's predecessor. When it comes to responsive images however, we are left to our own devices :(

Now, thanks to a neat package called Slimsy by Jeavon Leopold, which is based upon a cool JS library called slimmage.js, it is possible to create responsive images using the Umbraco v7 image cropper, though even with this, there is one feature missing that I used all the time with CropUp and just can't live without which is dynamic responsive images.

With dynamic responsive images in CropUp, you were able to define an image area with whatever dimensions you wanted (fixed or fluid) and have CropUp fill that area with the image whilst maintaining the aspect ratio and keeping the focal point as close to central as possible. For those familiar with CSS3, it's kind of like the CSS background size "cover" style, but with a defined focal point (See the CropUp demo page for a couple of examples)

Needing responsive images on a new site we are building in Umbraco v7, I thought I would take it upon myself to see if I could port over the dynamic responsive images functionality to work with the new image cropper, and the good news is, you can :)

The Markup
Having used CropUp for some time, I had a pretty good understanding of how the dynamic responsive images worked which mainly revolved around some specific markup and a complementary JS file to handle the positioning, so to start with I took a look at the markup created by CropUp to see if it could be recreated.

<div class="crop-up" 
    data-gravity="0.2139166,0.2329895" 
    data-box="0,0,1,1" 
    data-zoom="true" 
    data-upscale-url="/media/276815/my-image.jpg?width={w}&height={h}&mode=crop-up&cropUpClientMode=true" 
    data-upscale-step="200"></div>

I then took a look at the value stored in the image cropper property to see what we have access to there

{ 
    "src": "/media/1001/my-image.jpg", 
    "crops": [], 
    "focalPoint": { 
        "left": 0.2139166, 
        "top": 0.2329895 
    } 
}

Looking at these, you can see we can get the image URL as well as the focal point location which matches up perfectly to the data-gravity attribute of the CropUp markup. The only major thing missing really is the info for the data-box attribute which allows you to define a box area as the focal area rather than a single point, but as this isn't available in the new image cropper, I knew a value of 0,0,1,1 means the whole image, so it's pretty safe to just hard code this.

Great, so I knew we could generate the right markup, but the next question was, could we get the JS file to work with the new image cropper.

The JavaScript
The way the JS file works in CropUp is that it includes itself in the page and looks for any items with the crop-up CSS class and converts them into dynamic responsive images.

To test the javascript then, I downloaded a copy of it from the CropUp code repository on CodePlex and dropped it in my script folder and included it at the bottom of the sites master template.

On running the site, everything initially seemed to be working, the image maintained its focal point, however there was some strange jumping between image loads which should really be seamless.

After some investigating, I found the issue to be down to the features of the image croppers image generator. With the built in image cropper, passing it a width / height would return an image of that width / height, whereas with CropUp, setting the cropUpClientMode flag in the images querystring, entered the image cropper into a special mode which passes back an image that is of the same aspect ratio as the original image, but resized such that it would be big enough to fill the are defined by the width / height variables, rather than cropping it to those exact dimensions. In addition to this, the new image cropper also required the focal point coordinates to be passed through to the cropper on the querystring.

After checking the documentation for the Umbraco image cropper, it was clear it wasn't going to be possible to do the same kind of crop as the CropUp cropper was doing, but actually, with a small tweak to the JS, it was possible to replicate it in another way.

By default the CropUp JS will pass the width / height variables through to the image cropper and get it to decide on which dimension to scale, but if we move that calculation to the JS and only pass ONE dimension to the image cropper, we can get the cropper to maintain the aspect ratio and return an image in the size we want.

To accommodate this then (and fix the passing through of the focal point coordinates too), I made a small change to the markup that we generate as follows

<div class="crop-up"
    data-gravity="0.2139166,0.2329895"
    data-box="0,0,1,1"
    data-zoom="true"
    data-upscale-url="/media/276815/my-image.jpg?center=0.2329895,0.2139166&{d}"
    data-upscale-step="200"></div>

 And updated line 341 of the CropUp JS file from

var src = container.data("upscale-url").replace("{w}", requiredSize[0]).replace("{h}", requiredSize[1]);

to

var src = container.data("upscale-url");
if ((requiredSize[0] / size[0]) > requiredSize[1] / size[1]) {
    src = src.replace("{d}", "width=" + requiredSize[0]);
} else {
    src = src.replace("{d}", "height=" + requiredSize[1]);
}

And low and behold, dynamic responsive images using the Umbraco v7 image cropper and a bit of CropUp JS works.

I've left out the details of how I generate the markup as it's pretty straight forward and this post is pretty long already, but I hope this helps others who want to have dynamic responsive images like they did in v6 but who are now using v7.

UmbUKFest LogoIt’s that time of year again, the run up to Christmas, the weather turns cold and we’ve all swapped to our winter wardrobe.  But more importantly it’s time for the Umbraco UK Festival 2013!!

On Thursday 7th November, The Outfield team headed down to London town to meet up with the Umbraco crew.  The annual Umbraco UK Festival is hosted and organised by the team at Cogworks, and what a great job they did. 

The turnout for the event was massive, with lots of new faces and some really inspiring talks.  And, as always, the day was captured by the brilliant Doug Robar of Percipient Studios, with his amazing photography skills.  So good are the photos he took, we’ve borrowed a couple to show you guys, thanks Doug!

UmbUKFest Niels

The first day was dedicated to a Hackathon, a chance for the developers to do a bit of bug bashing.  A whopping 48 bugs were fixed, a new #UmbUKFest record – well done everybody!!!

The second day of the event was dedicated to talks from various Umbraco teams and individuals,  including our very own Matt Brailsford, who gave a great talk (biased!) on the potential solutions for ‘Bridging the Gap’ between frontend and backend development (slides and video presentation coming soon). 

Matt Lucy UmbUKFest

Now as a non-developer (although I am Umbraco level 1 certified – not sure I mentioned that to anyone!), attending this event was just as interesting for me as it was for Matt.  Whilst the majority of the talks were super technical, it gave me more of an insight into what Matt does, enabling me to understand his requirements as a developer, as well as those of our clients, since I take care of project management, sales and accounts.

UmbUKFest Talk

UmbUKFest MerchPerhaps the most important part for me was the chance to meet so many new people and catch up with those whom I have already met.  The warm, friendly and fun atmosphere is always great at an Umbraco event, whether it be training, attending talks or simply taking part in social activities (the pub).  Every time we meet with people and discuss ideas, talk about what we have done and ask advice, it always gets us thinking and inspires us to perhaps do something new, make changes to what we’re currently doing, or in turn help others by imparting the knowledge we have.  It’s great to talk to people, understand their businesses and forge friendships, all the while strengthening connections and the Umbraco community.  

HyperlinkHere at The Outfield we work on quite a few websites for people and so we get to see a lot of common patterns emerging. One such pattern is that of having links in the sites navigation that should link to external web pages.

As you may or may not know, there are some special property aliases in Umbraco that allow you to redirect between pages on the current site, however unfortunately there is no built in method for having a page redirect to an external URL.

After speaking with Lee Kelleher though, I think we came up with a pretty nice way of handling these, so what follows is a short guide on how you can do just this in Umbraco 6.

Create a Property
We start the process by creating a text string property on our doc types (or better yet, just on your master doc type) with an alias of umbracoExternalUrl.

umbracoExternalUrl

Next, go ahead and enter an external URL in the property for one of your content nodes.

property

Create an IUrlProvider
Now that we have our property set up, we now need to let Umbraco know that whenever this property is set it should use this value as a nodes URL instead of the default generated URL. To do this, we will use a cool new feature in Umbraco 6 which is an UrlProvider. The IUrlProvider interface allows us to define our own logic when generating a URL for a given node. With that said then, go ahead and setup a class that implements that interface as follows:

using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core;
using Umbraco.Web;
using Umbraco.Web.Routing;

namespace TheOutfield.Routing
{
    public class ExternalUrlProvider : IUrlProvider
    {
        public string GetUrl(UmbracoContext umbracoContext, int id, Uri current, UrlProviderMode mode)
        {
            var node = umbracoContext.ContentCache.GetById(id);
            return node.HasValue("umbracoExternalUrl") 
                ? node.GetPropertyValue<string>("umbracoExternalUrl") 
                : null;
        }

        public IEnumerable<string> GetOtherUrls(UmbracoContext umbracoContext, int id, Uri current)
        {
            return Enumerable.Empty<string>();
        }
    }
}

The interface itself is pretty simple and all we are doing is implementing the GetUrl method checking whether the current node has an umbracoExternalUrl property and if so, return that as the URL otherwise null (if the response is null then Umbraco will move on to the next UrlProvider it finds and so will eventually fall back to the default UrlProvider and thus the default internal URL).

Now that we have defined our UrlProvider, we need to make Umbraco aware of it, so to do this, create an ApplicationEventHandler like so:

using TheOutfield.Routing;
using Umbraco.Core;
using Umbraco.Web.Routing;

namespace TheOutfield
{
    public class Bootstrapper : IApplicationEventHandler
    {
        public void OnApplicationInitialized(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
        { }

        public void OnApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
        {
            UrlProviderResolver.Current.InsertTypeBefore<DefaultUrlProvider, ExternalUrlProvider>();
        }

        public void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
        { }
    }
}

If you check back to the properties tab of your content node now, you will see that Umbraco does indeed return your external URL as the nodes URL.

url

Create a PublishedContentRequest Event Handler
We could just finish up here, but there is one small problem, which is if you navigate to the internal, Umbraco URL for your node, Umbraco will attempt to render the page rather than redirecting us to the external URL. As that's not what we want, lets go ahead and setup a redirect. To do this we will use a handy event from within the Umbraco request pipline, PublishedContentRequest.Prepared which simply allows us to execute some code after the request context has been created, but before the page is actually executed. We'll declare our event handler in our ApplicationEventHandler class as follows:

using TheOutfield.Routing;
using Umbraco.Core;
using Umbraco.Web;
using Umbraco.Web.Routing;

namespace TheOutfield
{
    public class Bootstrapper : IApplicationEventHandler
    {
        public void OnApplicationInitialized(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
        { }

        public void OnApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
        {
            UrlProviderResolver.Current.InsertTypeBefore<DefaultUrlProvider, ExternalUrlProvider>();
            PublishedContentRequest.Prepared += (sender, args) =>
            {
                // Check to make sure the request is valid
                var request = sender as PublishedContentRequest;
                if (request == null || !request.HasPublishedContent)
                    return;

                // Check for external url
                var url = request.PublishedContent.GetPropertyValue<string>("umbracoExternalUrl");
                if (string.IsNullOrWhiteSpace(url))
                    return;

                // Perform the redirect
                request.SetRedirect(url, 301);
            };
        }

        public void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
        { }
    }
}

So now if you attempt to navigate to your nodes internal URL, you should find Umbraco will happily redirect you away to your external URL as required.

Tada!

Finishing Touches
Now that we have everything working, a nice finishing touch we like to add is to give our editors a bit of feedback to let them know the page is set to redirect. The best way we have found to do this is to use the amazing Page State Icons package by the umBristol gang.

Simply install the package then edit the PageStateIcons.config file as follows:

<pageStateIconsConfigurationSection xmlns="UmBristol.PageStateIcons">
  <rules>
    <add name="umbracoNaviHide" xPath="umbracoNaviHide = '1'" overlayIconPath="/Umbraco/Plugins/PageStateIcons/UmbracoNaviHide.png"
      description="Adds overlay to show the page is hidden from navigation."
      top="7" left="11" />
    <add name="umbracoRedirect" xPath="self::*[@isDoc and (normalize-space(umbracoRedirect) or normalize-space(umbracoExternalUrl))]"
      overlayIconPath="/Umbraco/Plugins/PageStateIcons/UmbracoRedirect.png"
      description="Adds an overlay to show the page is a redirect page."
      top="0" left="22" />
    <add name="umbracoInternalRedirectId" xPath="self::*[@isDoc and normalize-space(umbracoInternalRedirectId) and not(normalize-space(umbracoRedirect) or normalize-space(umbracoExternalUrl))]"
      overlayIconPath="/Umbraco/Plugins/PageStateIcons/umbracoInternalRedirectId.png"
      description="Adds an overlay to show the page is a redirect page."
      top="0" left="22" />
  </rules>
</pageStateIconsConfigurationSection>

And now within the content tree you'll see a nice little arrow overlay on your node to notify you that the page is set to redirect.

icons

As mentioned at the start of the article, this seems to becoming a fairly regualr feature request and we have found this solution to be an effective way to implement external redirects within Umbraco.

We hope you find it handy too.

stripeAfter attending the Tea Commerce training in Manchester a couple of weekd ago we thought we'd do a little exercise to help strech our legs with the new things we'd learnt and give something back at the same time.

One of the simplest ways to give back to the project is to help contribute with the list of supported payment providers (after all, there are millions out there). We had a look at the providers they had and noticed they were missing one for Stripe. As this service has recently launched in the UK, we thought it would be a perfect opportunity for us to contribute and to learn a bit more about Stripe at the same time.

Well, one day later and here it is :)

Installing the Provider
Installing the Stripe payment provider is a little trickier than most of the out of the box providers, but that is because stripe payments are processed inline on your actual website rather than being redirected away to a payment portal. That said, it's only an extra couple of steps and should be more than easy enough for most developers to implement.

(NB If you are using the newly released TeaCommerce 2.2 you can skip ahead to Configuring the Provider as the Stripe provider will be pre-installed for you)

You can find the source for the payment provider over on bitbucket. To install, you can either compile the whole solution and copy over the TeaCommerce.PaymentProviders.dll, Stripe.net.dll and the StripePaymentForm.cshtml file located in the TeaCommerce.PaymentProviders.UI project (this should go in your MacroPartials folder). Or you can just copy out the Stripe.cs file located in the TeaCommerce.PaymentProviders project into your own project, along with the Stripe.net.dll and StripePaymentForm.cshtml files and compile as part of your solution.

Either way, once you have done this, that should be all the files you need, and you should now be able to choose Stripe as a Payment Provider within Tea Commerce.

Payment Provider Dropdown

Configuring the Provider
To begin configuring your stripe provider, start by creating a new payment method in your store settings section selecting Stripe as the payment provider from the dropdown and click the load default settings button.

Payment Provider Settings

Edit the settings by copying your api keys from Stripe and setting up the various required URLS. The form_url parameter should point to the page on your site which will contain the payment form (you'll set this up in a moment). The continue_url should point to the page the user should be sent to after processing payment and the cancel_url should point to the page to redirect to if the user wants to cancel processing the payment at any point. In addition, you can also toggle between test and live modes and decide whether payments should be captured instantly, or whether to just take pre-authorization.

Setting up the Payment Form
Once the payment provider is setup, we'll want to setup the payment form macro. To do this, navigate to the developer section and create a new Macro selecting the StripePaymentForm.cshtml file you copied over earlier as the source script file.

Payment Form Macro

Next, create your checkout process Templates as you normally would in Tea Commerce, however this time be sure to create an additional Template for your payment step and drop in the macro you just created.

Payment Form Template

Finally, create your checkout process including a page for the payment step, using the payment template you just created (making sure the various urls match those in the provider settings) and when a call to the TC.GeneratePaymentForm method is made, it will generate a form which should now redirect you to your payment page.

Payment Form

Filling in the form will automatically submit the entered credit card details to Stripe via javascript over a secure connection and return an encrypted token which is posted back to the payment provider to take the actual payment. Once payment is processed, the provider will then automatically forward you on to the continue url declared in the provider settings.

Job done!

There are of course a few nicities you could and probably should add to this process, like making your checkout process run over https and you might also want to modify the StripePaymentForm.cshtml file to fit in more with your site design. But those things we will leave to you to implement :)

We had great fun implementing the Stripe payment provider, and learnt more about Tea Commerce and Stripe. We hope then that by releasing it freely, it will also help others to add Stripe support to their Tea Commerce solution and maybe encourage some to have a go at creating one themselves.

Newer Posts