diff --git a/Text/Hamlet.hs b/Text/Hamlet.hs
--- a/Text/Hamlet.hs
+++ b/Text/Hamlet.hs
@@ -118,12 +118,46 @@
 bindingPattern (BindConstr (Ident con) is) = do
     (patterns, scopes) <- fmap unzip $ mapM bindingPattern is
     return (ConP (mkName con) patterns, concat scopes)
-bindingPattern (BindRecord (Ident con) fields) = do
+bindingPattern (BindRecord (Ident con) fields wild) = do
     let f (Ident field,b) =
            do (p,s) <- bindingPattern b
               return ((mkName field,p),s)
     (patterns, scopes) <- fmap unzip $ mapM f fields
-    return (RecP (mkName con) patterns, concat scopes)
+    (patterns1, scopes1) <- if wild
+       then bindWildFields con $ map fst fields
+       else return ([],[])
+    return (RecP (mkName con) (patterns++patterns1), concat scopes ++ scopes1)
+
+-- Wildcards bind all of the unbound fields to variables whose name
+-- matches the field name.
+--
+-- For example: data R = C { f1, f2 :: Int }
+-- C {..}           is equivalent to   C {f1=f1, f2=f2}
+-- C {f1 = a, ..}   is equivalent to   C {f1=a,  f2=f2}
+-- C {f2 = a, ..}   is equivalent to   C {f1=f1, f2=a}
+bindWildFields :: String -> [Ident] -> Q ([(Name, Pat)], [(Ident, Exp)])
+bindWildFields conName fields = do
+  fieldNames <- recordToFieldNames conName
+  let available n     = nameBase n `notElem` map unIdent fields
+  let remainingFields = filter available fieldNames
+  let mkPat n = do
+        e <- newName (nameBase n)
+        return ((n,VarP e), (Ident (nameBase n), VarE e))
+  fmap unzip $ mapM mkPat remainingFields
+
+-- Important note! reify will fail if the record type is defined in the
+-- same module as the reify is used. This means quasi-quoted Hamlet
+-- literals will not be able to use wildcards to match record types
+-- defined in the same module.
+recordToFieldNames :: String -> Q [Name]
+recordToFieldNames conStr = do
+  -- use 'lookupValueName' instead of just using 'mkName' so we reify the
+  -- data constructor and not the type constructor if their names match.
+  Just conName                <- lookupValueName conStr
+  DataConI _ _ typeName _     <- reify conName
+  TyConI (DataD _ _ _ cons _) <- reify typeName
+  [fields] <- return [fields | RecC name fields <- cons, name == conName]
+  return [fieldName | (fieldName, _, _) <- fields]
 
 docToExp :: Env -> HamletRules -> Scope -> Doc -> Q Exp
 docToExp env hr scope (DocForall list idents inside) = do
diff --git a/Text/Hamlet/Parse.hs b/Text/Hamlet/Parse.hs
--- a/Text/Hamlet/Parse.hs
+++ b/Text/Hamlet/Parse.hs
@@ -319,6 +319,8 @@
 
     white = skipMany $ char ' '
 
+    wildDots = string ".." >> white
+
     isVariable (Ident (x:_)) = not (isUpper x)
     isVariable (Ident []) = error "isVariable: bad identifier"
 
@@ -351,12 +353,21 @@
                       guard (isConstructor c)
                       return c
         choice
-          [ fmap (BindRecord c) (braces (recordField `sepBy` comma))
+          [ record c
           , fmap (BindConstr c) (guard allowArgs >> many apat)
           , return (BindConstr c [])
           ]
        <?> "constructor"
 
+      record c = braces $ do
+        (fields, wild) <- option ([], False) $ go
+        return (BindRecord c fields wild)
+        where
+        go = (wildDots >> return ([], True))
+           <|> (do x         <- recordField
+                   (xs,wild) <- option ([],False) (comma >> go)
+                   return (x:xs,wild))
+
       recordField = do
         field <- ident
         p <- option (BindVar field) -- support punning
@@ -644,7 +655,7 @@
 
 data Binding = BindVar Ident | BindAs Ident Binding | BindConstr Ident [Binding]
              | BindTuple [Binding] | BindList [Binding]
-             | BindRecord Ident [(Ident, Binding)]
+             | BindRecord Ident [(Ident, Binding)] Bool
     deriving (Eq, Show, Read, Data, Typeable)
 
 spaceTabs :: Parser String
diff --git a/hamlet.cabal b/hamlet.cabal
--- a/hamlet.cabal
+++ b/hamlet.cabal
@@ -1,5 +1,5 @@
 name:            hamlet
-version:         1.1.5
+version:         1.1.6
 license:         MIT
 license-file:    LICENSE
 author:          Michael Snoyman <michael@snoyman.com>
diff --git a/test/HamletTest.hs b/test/HamletTest.hs
--- a/test/HamletTest.hs
+++ b/test/HamletTest.hs
@@ -2,6 +2,8 @@
 {-# LANGUAGE TemplateHaskell #-}
 module HamletTest (spec) where
 
+import HamletTestTypes (ARecord(..))
+
 import Test.HUnit hiding (Test)
 import Test.Hspec
 
@@ -76,6 +78,8 @@
     it "hamlet tuple" caseTuple
     it "complex pattern" caseComplex
     it "record pattern" caseRecord
+    it "record wildcard pattern #1" caseRecordWildCard
+    it "record wildcard pattern #2" caseRecordWildCard1
 
 
 
@@ -945,13 +949,27 @@
         #{a} #{b} #{c} #{e} #{f} #{g}
     |]
 
-data ARecord = ARecCon { field1 :: Int, field2 :: Bool }
-
 caseRecord :: Assertion
 caseRecord = do
-  let z = ARecCon 10 True
+  let z = ARecord 10 True
   helper "10" [hamlet|
-    $with ARecCon { field1, field2 = True } <- z
+    $with ARecord { field1, field2 = True } <- z
+        #{field1}
+    |]
+
+caseRecordWildCard :: Assertion
+caseRecordWildCard = do
+  let z = ARecord 10 True
+  helper "10 True" [hamlet|
+    $with ARecord {..} <- z
+        #{field1} #{field2}
+    |]
+
+caseRecordWildCard1 :: Assertion
+caseRecordWildCard1 = do
+  let z = ARecord 10 True
+  helper "10" [hamlet|
+    $with ARecord {field2 = True, ..} <- z
         #{field1}
     |]
 
