RSS
Added first cut of RSS feed; added links to head of default theme's layout template
This commit is contained in:
		
							parent
							
								
									d3712dc562
								
							
						
					
					
						commit
						7538b9ef26
					
				src
myWebLog.Data
myWebLog.Web
myWebLog/views/themes/default
@ -138,6 +138,24 @@ let tryFindPostByPriorPermalink conn (webLogId : string) (permalink : string) =
 | 
			
		||||
  |> await
 | 
			
		||||
  |> Seq.tryHead
 | 
			
		||||
 | 
			
		||||
/// Get a set of posts for RSS
 | 
			
		||||
let findFeedPosts conn webLogId nbr : (Post * User option) list =
 | 
			
		||||
  findPageOfPublishedPosts conn webLogId 1 nbr
 | 
			
		||||
  |> List.map (fun post -> { post with categories = r.Table(Table.Category)
 | 
			
		||||
                                                      .GetAll(post.categoryIds |> List.toArray)
 | 
			
		||||
                                                      .OrderBy("name")
 | 
			
		||||
                                                      .Pluck("id", "name")
 | 
			
		||||
                                                      .RunListAsync<Category>(conn)
 | 
			
		||||
                                                    |> await
 | 
			
		||||
                                                    |> Seq.toList },
 | 
			
		||||
                           (match r.Table(Table.User)
 | 
			
		||||
                                  .Get(post.authorId)
 | 
			
		||||
                                  .RunAtomAsync<User>(conn)
 | 
			
		||||
                                 |> await
 | 
			
		||||
                                 |> box with
 | 
			
		||||
                           | null -> None
 | 
			
		||||
                           | user -> Some <| unbox user))
 | 
			
		||||
 | 
			
		||||
/// Save a post
 | 
			
		||||
let savePost conn post =
 | 
			
		||||
  match post.id with
 | 
			
		||||
 | 
			
		||||
@ -11,8 +11,10 @@ open Nancy.Security
 | 
			
		||||
open Nancy.Session.Persistable
 | 
			
		||||
open NodaTime
 | 
			
		||||
open RethinkDb.Driver.Net
 | 
			
		||||
open System
 | 
			
		||||
open System.ServiceModel.Syndication
 | 
			
		||||
 | 
			
		||||
/// Routes dealing with posts (including the home page, /tag, /category, and catch-all routes)
 | 
			
		||||
/// Routes dealing with posts (including the home page, /tag, /category, RSS, and catch-all routes)
 | 
			
		||||
type PostModule(conn : IConnection, clock : IClock) as this =
 | 
			
		||||
  inherit NancyModule()
 | 
			
		||||
 | 
			
		||||
@ -31,6 +33,7 @@ type PostModule(conn : IConnection, clock : IClock) as this =
 | 
			
		||||
    this.Get .["/category/{slug}/page/{page:int}"] <- fun parms -> this.CategorizedPosts (downcast parms)
 | 
			
		||||
    this.Get .["/tag/{tag}"                      ] <- fun parms -> this.TaggedPosts (downcast parms)
 | 
			
		||||
    this.Get .["/tag/{tag}/page/{page:int}"      ] <- fun parms -> this.TaggedPosts (downcast parms)
 | 
			
		||||
    this.Get .["/feed"                           ] <- fun parms -> this.GenerateFeed (downcast parms)
 | 
			
		||||
    this.Get .["/posts/list"                     ] <- fun _     -> this.PostList 1
 | 
			
		||||
    this.Get .["/posts/list/page/{page:int}"     ] <- fun parms -> this.PostList (getPage <| downcast parms)
 | 
			
		||||
    this.Get .["/post/{postId}/edit"             ] <- fun parms -> this.EditPost (downcast parms)
 | 
			
		||||
@ -133,6 +136,39 @@ type PostModule(conn : IConnection, clock : IClock) as this =
 | 
			
		||||
    model.subtitle  <- Some <| sprintf "Posts tagged \"%s\"" tag
 | 
			
		||||
    this.ThemedView "index" model
 | 
			
		||||
 | 
			
		||||
  /// Generate an RSS feed
 | 
			
		||||
  member this.GenerateFeed (parameters : DynamicDictionary) =
 | 
			
		||||
    let format = match parameters.ContainsKey "format" with // FIXME: format not coming through on query string
 | 
			
		||||
                 | true -> parameters.["format"].ToString ()
 | 
			
		||||
                 | _    -> "rss"
 | 
			
		||||
    let posts  = findFeedPosts conn this.WebLog.id 10
 | 
			
		||||
    let feed   =
 | 
			
		||||
      SyndicationFeed(
 | 
			
		||||
        this.WebLog.name, defaultArg this.WebLog.subtitle null,
 | 
			
		||||
        Uri(sprintf "%s://%s" this.Request.Url.Scheme this.WebLog.urlBase), null,
 | 
			
		||||
        (match posts |> List.tryHead with
 | 
			
		||||
         | Some (post, _) -> Instant(post.updatedOn).ToDateTimeOffset ()
 | 
			
		||||
         | _              -> System.DateTimeOffset(System.DateTime.MinValue)),
 | 
			
		||||
        posts
 | 
			
		||||
        |> List.map (fun (post, user) ->
 | 
			
		||||
            let item =
 | 
			
		||||
              SyndicationItem(
 | 
			
		||||
                BaseUri         = Uri(sprintf "%s://%s/%s" this.Request.Url.Scheme this.WebLog.urlBase post.permalink),
 | 
			
		||||
                PublishDate     = Instant(post.publishedOn).ToDateTimeOffset (),
 | 
			
		||||
                LastUpdatedTime = Instant(post.updatedOn).ToDateTimeOffset (),
 | 
			
		||||
                Title           = TextSyndicationContent(post.title),
 | 
			
		||||
                Content         = TextSyndicationContent(post.text, TextSyndicationContentKind.Html))
 | 
			
		||||
            user
 | 
			
		||||
            |> Option.iter (fun u -> item.Authors.Add
 | 
			
		||||
                                       (SyndicationPerson(u.userName, u.preferredName, defaultArg u.url null)))
 | 
			
		||||
            post.categories
 | 
			
		||||
            |> List.iter (fun c -> item.Categories.Add(SyndicationCategory(c.name)))
 | 
			
		||||
            item))
 | 
			
		||||
    let stream = new IO.MemoryStream()
 | 
			
		||||
    Xml.XmlWriter.Create(stream)
 | 
			
		||||
    |> match format with | "atom" -> feed.SaveAsAtom10 | _ -> feed.SaveAsRss20
 | 
			
		||||
    stream.Position <- int64 0
 | 
			
		||||
    upcast this.Response.FromStream(stream, sprintf "application/%s+xml" format)
 | 
			
		||||
 | 
			
		||||
  // ---- Administer posts ----
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -148,6 +148,7 @@
 | 
			
		||||
    <Reference Include="System.ComponentModel.DataAnnotations" />
 | 
			
		||||
    <Reference Include="System.Core" />
 | 
			
		||||
    <Reference Include="System.Numerics" />
 | 
			
		||||
    <Reference Include="System.ServiceModel" />
 | 
			
		||||
    <Reference Include="System.Web.Razor">
 | 
			
		||||
      <HintPath>..\packages\FSharp.Formatting.2.14.4\lib\net40\System.Web.Razor.dll</HintPath>
 | 
			
		||||
      <Private>True</Private>
 | 
			
		||||
 | 
			
		||||
@ -8,6 +8,8 @@
 | 
			
		||||
  <link rel="stylesheet" type="text/css" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" />
 | 
			
		||||
  <link rel="stylesheet" type="text/css" href="/default/bootstrap-theme.min.css" />
 | 
			
		||||
  <link rel="stylesheet" type="text/css" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" />
 | 
			
		||||
  <link rel="alternate" type="application/atom+xml" href="//@Model.webLog.urlBase/feed?format=atom" />
 | 
			
		||||
  <link rel="alternate" type="application/rss+xml" href="//@Model.webLog.urlBase/feed" />
 | 
			
		||||
  @Section['Head'];
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user