diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -107,6 +107,8 @@
   rendered verbatim.  (Note that no escaping is done;
   the assumption is that the calling program will escape
   the strings appropriately for the output format.)
+- If the value of the variable is a boolean value, it
+  will be rendered as `true` if true, or as empty if false.
 - If the value is a list, the values will be concatenated.
 - If the value is a map, the string `true` will be rendered.
 - Every other value will be rendered as the empty string.
@@ -116,8 +118,6 @@
 
 - If the value is a number, it will be rendered as an
   integer if possible, otherwise as a floating-point number.
-- If the value is a JSON boolean, it will be rendered as `true`
-  if true, and as the empty string if false.
 
 
 ## Conditionals
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,17 @@
 # doctemplates
 
+## 0.9
+
+  * Add BoolVal constructor to Val.  This gives a smoother
+    interface with JSON and YAML.  [API change]
+
+  * Remove overlapping instances by generalizing
+    `ToContext String String` and `FromContext String String`
+    to `TemplateTarget [a] => ToContext [a] [a]` and
+    `TemplateTarget [a] => FromContext [a] [a]`.
+    Remove the instance `ToContext String (Doc String)`.
+    Remove redundant constraints.  (#9, favonia) [API change]
+
 ## 0.8.3
 
   * Properly handle nested loops (#15).  Previously "it" was
diff --git a/doctemplates.cabal b/doctemplates.cabal
--- a/doctemplates.cabal
+++ b/doctemplates.cabal
@@ -1,5 +1,5 @@
 name:                doctemplates
-version:             0.8.3
+version:             0.9
 synopsis:            Pandoc-style document templates
 description:         This is the text templating system used by pandoc.
                      It supports variable interpolation, iteration,
diff --git a/src/Text/DocTemplates/Internal.hs b/src/Text/DocTemplates/Internal.hs
--- a/src/Text/DocTemplates/Internal.hs
+++ b/src/Text/DocTemplates/Internal.hs
@@ -129,7 +129,7 @@
   mappend = (<>)
 
 type TemplateTarget a =
-  (Monoid a, IsString a, HasChars a, ToText a, FromText a)
+  (HasChars a, ToText a, FromText a)
 
 -- | A 'Context' defines values for template's variables.
 newtype Context a = Context { unContext :: M.Map Text (Val a) }
@@ -141,6 +141,7 @@
     SimpleVal  (Doc a)
   | ListVal    [Val a]
   | MapVal     (Context a)
+  | BoolVal    Bool
   | NullVal
   deriving (Show, Traversable, Foldable, Functor, Data, Typeable)
 
@@ -166,25 +167,19 @@
 instance ToContext a a => ToContext a (Doc a) where
   toVal     = SimpleVal
 
--- This is needed because otherwise the compiler tries to
--- match on ToContext a [b], with a = b = Char, even though
--- we don't have ToContext Char Char.  I don't understand why.
-instance {-# OVERLAPPING #-} ToContext String String where
-  toVal    = SimpleVal . DL.literal
-
-instance {-# OVERLAPPING #-} ToContext String (Doc String) where
-  toVal    = SimpleVal
-
 instance ToContext a b => ToContext a [b] where
   toVal     = ListVal . map toVal
 
+instance {-# OVERLAPPING #-} TemplateTarget [a] => ToContext [a] [a] where
+  toVal    = SimpleVal . DL.literal
+
 instance ToContext a b => ToContext a (M.Map Text b) where
   toVal     = MapVal . toContext
   toContext = Context . M.map toVal
 
 instance TemplateTarget a => ToContext a Bool where
-  toVal True  = SimpleVal "true"
-  toVal False = NullVal
+  toVal True  = BoolVal True
+  toVal False = BoolVal False
 
 instance TemplateTarget a => ToContext a Value where
   toContext x = case fromJSON x of
@@ -212,10 +207,7 @@
   fromVal (SimpleVal x) = Just (DL.render Nothing x)
   fromVal _             = Nothing
 
--- This is needed because otherwise the compiler tries to
--- match on FromContext a [b], with a = b = Char, even though
--- we don't have FromContext Char Char.  I don't understand why.
-instance {-# OVERLAPPING #-} FromContext String String where
+instance {-# OVERLAPPING #-} TemplateTarget [a] => FromContext [a] [a] where
   fromVal (SimpleVal x) = Just (DL.render Nothing x)
   fromVal _             = Nothing
 
@@ -232,7 +224,7 @@
                               case floatingOrInteger n of
                                   Left (r :: Double)   -> show r
                                   Right (i :: Integer) -> show i
-      Bool True   -> return $ SimpleVal "true"
+      Bool b      -> return $ BoolVal b
       Object o    -> MapVal . Context . M.fromList . H.toList <$>
                        mapM parseJSON o
       _           -> return NullVal
@@ -256,7 +248,7 @@
       Scalar _ (SStr t) -> return $ SimpleVal $ fromString . fromText $ t
       Scalar _ (SFloat n) -> return $ SimpleVal $ fromString . show $ n
       Scalar _ (SInt n) -> return $ SimpleVal $ fromString . show $ n
-      Scalar _ (SBool True) -> return $ SimpleVal "true"
+      Scalar _ (SBool b) -> return $ BoolVal b
       _           -> return NullVal
 
 instance TemplateTarget a => FromYAML (Context a) where
@@ -274,6 +266,7 @@
   toJSON (MapVal m) = toJSON m
   toJSON (ListVal xs) = toJSON xs
   toJSON (SimpleVal d) = toJSON $ toText $ DL.render Nothing d
+  toJSON (BoolVal b) = toJSON b
 
 instance TemplateTarget a => ToYAML (Context a) where
   toYAML (Context m) = toYAML m
@@ -283,6 +276,7 @@
   toYAML (MapVal m) = toYAML m
   toYAML (ListVal xs) = toYAML xs
   toYAML (SimpleVal d) = toYAML $ toText $ DL.render Nothing d
+  toYAML (BoolVal b) = toYAML b
 
 mapDoc :: TemplateTarget a => (Doc a -> Doc a) -> Val a -> Val a
 mapDoc f val =
@@ -290,6 +284,7 @@
     SimpleVal d        -> SimpleVal (f d)
     MapVal (Context m) -> MapVal (Context $ M.map (mapDoc f) m)
     ListVal xs         -> ListVal $ map (mapDoc f) xs
+    BoolVal b          -> BoolVal b
     NullVal            -> NullVal
 
 mapText :: TemplateTarget a => (Text -> Text) -> Val a -> Val a
@@ -303,6 +298,7 @@
            SimpleVal d        -> T.length . toText $ DL.render Nothing d
            MapVal (Context m) -> M.size m
            ListVal xs         -> length xs
+           BoolVal _          -> 0
            NullVal            -> 0
 applyPipe ToUppercase val = mapText T.toUpper val
 applyPipe ToLowercase val = mapText T.toLower val
@@ -411,6 +407,8 @@
       | DL.isEmpty d -> []
       | otherwise    -> [removeFinalNl d]
     MapVal _      -> ["true"]
+    BoolVal True  -> ["true"]
+    BoolVal False -> []
     NullVal       -> []
 
 removeFinalNl :: Doc a -> Doc a
@@ -456,12 +454,12 @@
 renderTemp :: forall a . TemplateTarget a
            => Template a -> Context a -> RenderState (Doc a)
 renderTemp (Literal t) _ = updateColumn t
-renderTemp (Interpolate v) ctx = updateColumn $ mconcat $ resolveVariable v ctx
+renderTemp (Interpolate v) ctx =
+  updateColumn $ mconcat $ resolveVariable v ctx
 renderTemp (Conditional v ift elset) ctx =
-  let res = resolveVariable v ctx
-   in case res of
-        [] -> renderTemp elset ctx
-        _  -> renderTemp ift ctx
+  case resolveVariable v ctx of
+    [] -> renderTemp elset ctx
+    _  -> renderTemp ift ctx
 renderTemp (Iterate v t sep) ctx = do
   xs <- withVariable v ctx (renderTemp t)
   sep' <- renderTemp sep ctx
diff --git a/test/boolean.test b/test/boolean.test
new file mode 100644
--- /dev/null
+++ b/test/boolean.test
@@ -0,0 +1,13 @@
+{ "foo": true,
+  "bar": false
+}
+.
+$foo$
+$bar$
+$if(foo)$XXX$else$YYY$endif$
+$if(bar)$XXX$else$YYY$endif$
+.
+true
+
+XXX
+YYY
