• 0

Cool Site I made


Question

I thought you might be interested to check out the site I made that launched this evening.

http://www.letter-photo.com

This site was built for a client of ours (I work for a company called Orajen - http://www.orajen.com). The client goes around and takes pictures of things that look like letters and then lets you assemble a word from their letter collection. There are other sites / companies out there that do the same thing but I think our work is the best of the bunch.

The design work is not mine (it was done by our in house designer), I was 'merely' the developer on the project. The site is built in ASP.NET / c# and the client side stuff leverages scriptaculous. The shopping cart was built in house by me for this project.

There have been hundreds of hours put into this project and I have a lot of pride in the work so I wanted to show it off a little :)

Link to comment
https://www.neowin.net/forum/topic/647112-cool-site-i-made/
Share on other sites

Recommended Posts

  • 0

I would have made the header smaller so I didnt have to scroll to see the stuff down the bottom. But besides that I like it :) Thats at 1280x1024, you could argue no one uses that res anymore and that would be a valid but I guess some people do. Nevertheless, I reiterate that I like it. +2 thumbs up for you.

  • 0
I would have made the header smaller so I didnt have to scroll to see the stuff down the bottom. But besides that I like it :) Thats at 1280x1024, you could argue no one uses that res anymore and that would be a valid but I guess some people do. Nevertheless, I reiterate that I like it. +2 thumbs up for you.

Our designer was never completely satisfied with the header, but it is what is now (he never could arrive on something he liked better). And as an FYI, the site is designed to be usable (IE no horizontal scrolling) at 1024x768.

  • 0
Glad you like it. You're inclusion of that pic reminds me, we are looking at doing some more social / viral features for the site for phase 2, such as building a word and emailing it to a friend.

Good idea, as the site is easy to use and fun, people will want to send things to friends. :yes:

  • 0

What kind of design choices did you use when interacting with your database? Did you just use a SqlReader in each codebehind file for the pages, or did you use a separate class that handles all of the database stuff?

What do you think of the the LinqToSql technology by microsoft?

Nice site btw, I really like how everything fits together.

  • 0
What kind of design choices did you use when interacting with your database? Did you just use a SqlReader in each codebehind file for the pages, or did you use a separate class that handles all of the database stuff?

What do you think of the the LinqToSql technology by microsoft?

Nice site btw, I really like how everything fits together.

With all my projects I prefer to implement a data access layer that obfuscates my database functions. I typically will implement the basic CRUD functions behind appropriately named functions and add additional functions as required (like one for updating or adding a record to a one-to-many relationship). Naturally then I build my objects to adequately represent the things of the domain in code.

For letter-photo I have many objects; Word, Letter, LetterCollection, Attribute (which I inherit from to build things like Orientation, Easels and Color), etc. The shopping cart piece lives in a separate namespace entirely. I wrote it to understand how to handle items of type Product (base class I defined) and then had Word inherit off of product. This way adding those Words was easy and the entirety of my cart code base is quite flexible and reusable.

In regards to Linq and LinqToSql, I unfortunately have not yet made myself work with them in a project yet. We only installed 3.5 in production a few months ago. I must say I am intrigued by what they have to offer, and on my next project I am going to attempt to use the technology as soon as I find an appropriate spot.

Doesn't seem to work in Opera which is a shame..

We don't typically test for compatibility with Opera in house. We check all of our sites in IE6, IE7, Firefox 2 and 3, Safari 2 and 3. That being said I'll look at what I can do to fix this site for opera and perhaps get it added to our test suite.

  • 0
How about a feature where you can type in a word and it randomly selects the letter tiles for you?

This certainly is a good idea. The shame is that since this project was contracted by a client of ours, I can't just go adding features without having them pay for it (I could, but that's not smart business). As much as I like the site, I am biting my tongue when it comes to adding additional functionality until we start a Phase 2 of development with them.

  • 0
Doesn't seem to work in Opera which is a shame..

I've downloaded Opera 9.5 from http://www.opera.com and the site works fine as far as I can tell. I noticed a few non-critical css anomalies, but those were in the cart during the checkout process. What version of Opera are you using and what exactly are you experiencing?

  • 0
With all my projects I prefer to implement a data access layer that obfuscates my database functions. I typically will implement the basic CRUD functions behind appropriately named functions and add additional functions as required (like one for updating or adding a record to a one-to-many relationship). Naturally then I build my objects to adequately represent the things of the domain in code.

For letter-photo I have many objects; Word, Letter, LetterCollection, Attribute (which I inherit from to build things like Orientation, Easels and Color), etc. The shopping cart piece lives in a separate namespace entirely. I wrote it to understand how to handle items of type Product (base class I defined) and then had Word inherit off of product. This way adding those Words was easy and the entirety of my cart code base is quite flexible and reusable.

In regards to Linq and LinqToSql, I unfortunately have not yet made myself work with them in a project yet. We only installed 3.5 in production a few months ago. I must say I am intrigued by what they have to offer, and on my next project I am going to attempt to use the technology as soon as I find an appropriate spot.

We don't typically test for compatibility with Opera in house. We check all of our sites in IE6, IE7, Firefox 2 and 3, Safari 2 and 3. That being said I'll look at what I can do to fix this site for opera and perhaps get it added to our test suite.

How do you deal with links between the objects in your data access layer? I am in the slow process of building an asset tracking system and some of my objects are linked to other objects. For example, an asset is linked to a location, which is then linked to a region. When creating an asset in my data access layer I would have to fill all the properties for that asset and then if a property is an object I would have to fill all the properties of that object and so on. So there is a lot of overhead when sometimes you just need the object to access a few properties so there is a big performance hit on the database.

I looked into something like nhibernate that supports lazy loading, but its not as flexible as building your own data access layer. For example, all collections have to conform to their specification and some other things that cause you to rethink your design a bit. Also, in order to support lazy loading you have to maintain a database session throughout the http request which can be a little tricky to implement. There is not much documentation on the proper way to do this, but the latest alpha relase does make it easy to handle.

I do like LinqToSql, but the problem with that is it enforces a database driven design and it does not support things like multiple table inheritance. I don't need multiple table inheritance in my design, but if I did then I would have to use something else. Another thing with LinqToSql is that it currently only supports MS Sql Server so again, you would have to switch to something else.

Did you encounter any database to object problems like this and what did you do to resolve them? Do you just not have that many links between objects so performance was not much of an issue?

  • 0
I've downloaded Opera 9.5 from http://www.opera.com and the site works fine as far as I can tell. I noticed a few non-critical css anomalies, but those were in the cart during the checkout process. What version of Opera are you using and what exactly are you experiencing?

I'm using Opera 9.27 - one of the last builds before Opera 9.5 was released. I haven't got round to upgrading it on my laptop yet.

If it works in 9.5 you probably don't have to worry about fixing it (the drag and drop didn't work at all).

  • 0
How do you deal with links between the objects in your data access layer? I am in the slow process of building an asset tracking system and some of my objects are linked to other objects. For example, an asset is linked to a location, which is then linked to a region. When creating an asset in my data access layer I would have to fill all the properties for that asset and then if a property is an object I would have to fill all the properties of that object and so on. So there is a lot of overhead when sometimes you just need the object to access a few properties so there is a big performance hit on the database.

I looked into something like nhibernate that supports lazy loading, but its not as flexible as building your own data access layer. For example, all collections have to conform to their specification and some other things that cause you to rethink your design a bit. Also, in order to support lazy loading you have to maintain a database session throughout the http request which can be a little tricky to implement. There is not much documentation on the proper way to do this, but the latest alpha relase does make it easy to handle.

I do like LinqToSql, but the problem with that is it enforces a database driven design and it does not support things like multiple table inheritance. I don't need multiple table inheritance in my design, but if I did then I would have to use something else. Another thing with LinqToSql is that it currently only supports MS Sql Server so again, you would have to switch to something else.

Did you encounter any database to object problems like this and what did you do to resolve them? Do you just not have that many links between objects so performance was not much of an issue?

Links between objects is something I have wrestled with for a long time. In this project the object with the most links is Order. Order has a collection of Products you ordered (and products have Attributes), Address objects for billing and shipping, and then order attributes (for expressing things like a Cart handling fee, etc). So of course that could potentially be a pretty mammoth set of queries to the database when you want to view an order.

I typically try and design what will be the best for my code first, and then later on implement the database stuff. Some simple objects translate nicely to a single row, but many do not. Rather than have these limitations limit my creativity in code, I let my DAL handle these troubles and I attempt to build the best relational design for the task and likewise with my objects.

When deciding how I want to handling the loading of big boys like that, I often let the user interface help me make those decisions. If the information that we'd be viewing can be separated, in a logical manner, over several requests. In my case, showing only the high level order details first, then only let them see the order items if they really ask for it. The part I dislike about this is you are conceding aspects of your design to the necessities of performance, but in reality part of application design should always focus on performance and if your model is affected slightly by it, so be it.

With that aside, there are 3 ways I typically approach my links (usually case-by-case):

1) When I know the O(n) of the queries to build the objects will be something trivial like 2 or 3, I lump them into one request and load. This is mostly things who have a 1 to 1 relationship or 1 to few.

2) If the associated objects are not likely to be needed when viewing the primary information, but there are few of those objects, I will mirror the database in that I actually expose a SomethingId property on my object so I may request them if the end user asks for them.

3) If I don't want to store ID's on the objects like that, and there will be potentially many associated objects, I will write functions in the DAL like List<Product> GetOrderItems(string orderId) So I can provide all that information after the user says they are actually interested in it.

And I always write a full load function just in case.

  • 0

A couple of other things I thought of;

I agree with you in not totally liking tools that emphasize the structure of your database as the model of your domain in code. I definitely see it's merits, but I prefer to to think of the persistence of my objects and data as secondary to the model of the domain. And more often than not on a fresh project neither is totally defined yet, so I usually start with the code.

In instances when I need to load something that I am going to use over and over, I leverage System.Web.Caching. If you are not familiar with this namespace, it allows you to persist items to memory, not unlike Session State. However the nice thing is that items persisted to cache are accessible by all sessions. In context of letter-photo.com, one place I use caching is for the letter's that are populated into the carousel. Here's the function I call to load some letters when someone clicks a category:

public static LetterCollection GetLetters(int categoryId)
	{
		string letterColKey = "LetterCollection" + categoryId.ToString();
		LetterCollection letters = new LetterCollection();

		if (System.Web.HttpContext.Current != null)
		{
			letters = (LetterCollection)System.Web.HttpContext.Current.Cache[letterColKey];

			if (letters == null)
			{
				letters = Letter.LettersFromSql(categoryId, true);
				System.Web.HttpContext.Current.Cache.Insert(letterColKey, letters, null, DateTime.UtcNow.AddMinutes(5d), System.Web.Caching.Cache.NoSlidingExpiration);
			}
		}
		else
		{
			letters = Letter.LettersFromSql(categoryId, true);
		}

		return letters;
	}

So you can see here that I first check to see if I have the object I want in cache, and if so I can return that directly from memory (all of this is transparent to the page level requests as I bundled this into my DAL functions). Only if I don't find what I'm looking for do I ask the database. Here's some more information on Caching http://msdn.microsoft.com/en-us/library/sy...che(VS.80).aspx

There is a nice ebook that is available for free (all you need to do is register on their site), that talking about good domain based modeling of your code. Its called 'Domain Driven Design Quickly' and you can get it here - http://www.infoq.com/minibooks/domain-driven-design-quickly

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Posts

    • "Samsung is shutting down yet another app used by millions" I will fix the clickbait title for you, free-of-charge: "Samsung shutting down it's Max VPN app"
    • Microsoft brings Planner Agent to all Microsoft 365 Copilot users by Ivan Jenic Image: Microsoft Microsoft has announced that Planner Agent in Microsoft 365 Copilot is now generally available to all users with a Microsoft 365 Copilot license. Planner Agent is the latest addition in the string of AI features that Microsoft is implementing across virtually all of its products. The agent lets you manage tasks through natural language prompts directly inside Microsoft 365 Copilot. You can create and update tasks, check priorities, and get insights about current entries without leaving the chat interface. The general availability release comes with a handful of new additions on top of what was available during the initial rollout. A new plan picker lets you search and filter your plans by name, then update task names, statuses, due dates, or priorities through the agent. There's also a goals bucket now, which lets you group tasks under specific goals. This builds on the Goals view, a feature that was introduced as part of the broader Planner refresh that rolled out earlier. Image: Microsoft | Planner Agent in Microsoft 365 Copilot All AI-generated plans and tasks are created in draft mode by default, so you can review and approve changes before anything goes through. This is actually a thoughtful safety feature, because trusting AI to handle all your tasks without a human in the loop is usually a recipe for disaster. Having tasks initially saved as drafts is the best possible middle ground. Microsoft also says that not all tasks are executed equally. Simple tasks get processed quickly, while more complex ones, like building a plan from a Word, Excel, or PowerPoint file, are handed to a more capable model. Microsoft says this approach delivers the best performance, but it could also help with usage management, as you won't have to waste tokens on performing simple tasks. Planner Agent is available now across Teams, Loop, SharePoint, and other Microsoft 365 apps for anyone on a Microsoft 365 Copilot subscription.
    • To be clear I'm anti trump, the bigger point is why review this game at all?
    • Trillion dollar Microsoft has to reduce spending by hurting more people. Good job Microsoft. Good Job Asha.
  • Recent Achievements

    • First Post
      Cosminus earned a badge
      First Post
    • One Year In
      ThatGuyOnline earned a badge
      One Year In
    • Week One Done
      Jeroen Wilms earned a badge
      Week One Done
    • Week One Done
      rolfus earned a badge
      Week One Done
    • One Month Later
      Leroy Jethro Gibbs earned a badge
      One Month Later
  • Popular Contributors

    1. 1
      +primortal
      490
    2. 2
      +Edouard
      191
    3. 3
      PsYcHoKiLLa
      124
    4. 4
      Steven P.
      86
    5. 5
      neufuse
      73
  • Tell a friend

    Love Neowin? Tell a friend!