Ver código fonte

Implement Posts feature: controller actions, views (via Codex)

pull/5/head
Nano 6 dias atrás
pai
commit
ac29afed19
6 arquivos alterados com 400 adições e 30 exclusões
  1. +133
    -26
      app/controllers/PostsController.asp
  2. +96
    -4
      app/repositories/PostsRepository.asp
  3. +40
    -0
      app/views/Posts/edit.asp
  4. +62
    -0
      app/views/Posts/index.asp
  5. +36
    -0
      app/views/Posts/new.asp
  6. +33
    -0
      app/views/Posts/show.asp

+ 133
- 26
app/controllers/PostsController.asp Ver arquivo

@@ -38,66 +38,173 @@ Class PostsController_Class
' Action: Index
'---------------------------------------------------------------
Public Sub Index()
' TODO: Implement Index action
Response.Write "Index action called"
Dim posts
Set posts = PostsRepository().FindAllWhere("IsPublished = 1", "PublishedDate DESC", 0, 20)
%>
<!--#include file="../views/Posts/index.asp" -->
<%
End Sub
'---------------------------------------------------------------
' Action: Show
'---------------------------------------------------------------
Public Sub Show(slug)
' TODO: Implement Show action
Response.Write "<strong>Show called</strong><br>"
Response.Write "Parameters:<br>"
Response.Write "slug = " & Server.HTMLEncode(CStr(slug)) & "<br>"
Public Sub Show(ByVal slug)
Dim matches
Set matches = PostsRepository().Find(Array("Slug", slug, "IsPublished", 1), Empty)
If matches.Count = 0 Then
Response.Status = "404 Not Found"
%>
<!--#include file="../views/Error/NotFound.asp" -->
<%
Exit Sub
End If
Dim post
Set post = matches.Front()
%>
<!--#include file="../views/Posts/show.asp" -->
<%
End Sub
'---------------------------------------------------------------
' Action: New
'---------------------------------------------------------------
Public Sub NewForm()
' TODO: Implement NewForm action
Response.Write "NewForm action called"
%>
<!--#include file="../views/Posts/new.asp" -->
<%
End Sub
'---------------------------------------------------------------
' Action: Create
'---------------------------------------------------------------
Public Sub Create()
' TODO: Implement Create action
Response.Write "Create action called"
Dim title : title = Trim(Request.Form("Title"))
If Len(title) = 0 Then
Flash().AddError "Title is required."
Response.Redirect "/posts/new"
Exit Sub
End If
Dim post
Set post = New POBO_Posts
post.Title = title
post.Summary = Request.Form("Summary")
post.Body = Request.Form("Body")
post.CategoryID = FormNumberOrZero(Request.Form("CategoryID"))
post.Slug = BuildSlug(title)
post.CreatedDate = Now()
post.UpdatedDate = Now()
post.IsPublished = 0
PostsRepository().AddNew post
Flash().Success = "Post created."
Response.Redirect "/posts"
End Sub
'---------------------------------------------------------------
' Action: Edit
'---------------------------------------------------------------
Public Sub Edit(id)
' TODO: Implement Edit action
Response.Write "<strong>Edit called</strong><br>"
Response.Write "Parameters:<br>"
Response.Write "id = " & Server.HTMLEncode(CStr(id)) & "<br>"
Public Sub Edit(ByVal id)
Dim post
On Error Resume Next
Set post = PostsRepository().FindByID(id)
If Err.Number <> 0 Then
Err.Clear
On Error GoTo 0
Response.Status = "404 Not Found"
%>
<!--#include file="../views/Error/NotFound.asp" -->
<%
Exit Sub
End If
On Error GoTo 0
%>
<!--#include file="../views/Posts/edit.asp" -->
<%
End Sub
'---------------------------------------------------------------
' Action: Update
'---------------------------------------------------------------
Public Sub Update(id)
' TODO: Implement Update action
Response.Write "<strong>Update called</strong><br>"
Response.Write "Parameters:<br>"
Response.Write "id = " & Server.HTMLEncode(CStr(id)) & "<br>"
Public Sub Update(ByVal id)
Dim post
On Error Resume Next
Set post = PostsRepository().FindByID(id)
If Err.Number <> 0 Then
Err.Clear
On Error GoTo 0
Response.Status = "404 Not Found"
%>
<!--#include file="../views/Error/NotFound.asp" -->
<%
Exit Sub
End If
On Error GoTo 0
Dim title : title = Trim(Request.Form("Title"))
If Len(title) = 0 Then
Flash().AddError "Title is required."
Response.Redirect "/posts/" & Server.URLEncode(CStr(id)) & "/edit"
Exit Sub
End If
post.Title = title
post.Summary = Request.Form("Summary")
post.Body = Request.Form("Body")
post.CategoryID = FormNumberOrZero(Request.Form("CategoryID"))
post.Slug = BuildSlug(title)
post.UpdatedDate = Now()
PostsRepository().Update post
Flash().Success = "Post updated."
Response.Redirect "/posts"
End Sub
'---------------------------------------------------------------
' Action: Delete
'---------------------------------------------------------------
Public Sub Delete(id)
' TODO: Implement Delete action
Response.Write "<strong>Delete called</strong><br>"
Response.Write "Parameters:<br>"
Response.Write "id = " & Server.HTMLEncode(CStr(id)) & "<br>"
Public Sub Delete(ByVal id)
PostsRepository().Delete id
Flash().Success = "Post deleted."
Response.Redirect "/posts"
End Sub
Private Function FormNumberOrZero(ByVal value)
If IsNumeric(value) Then
FormNumberOrZero = CLng(value)
Else
FormNumberOrZero = 0
End If
End Function
Private Function BuildSlug(ByVal value)
Dim raw : raw = LCase(Trim(CStr(value)))
Dim i, ch, slug, previousDash
slug = ""
previousDash = False
For i = 1 To Len(raw)
ch = Mid(raw, i, 1)
If (ch >= "a" And ch <= "z") Or (ch >= "0" And ch <= "9") Then
slug = slug & ch
previousDash = False
ElseIf Not previousDash And Len(slug) > 0 Then
slug = slug & "-"
previousDash = True
End If
Next
Do While Right(slug, 1) = "-"
slug = Left(slug, Len(slug) - 1)
Loop
If Len(slug) = 0 Then slug = "post"
BuildSlug = slug
End Function
End Class
' Singleton instance


+ 96
- 4
app/repositories/PostsRepository.asp Ver arquivo

@@ -27,6 +27,54 @@ Class PostsRepository_Class
Set GetAll = Find(Empty, orderBy)
End Function
Public Function FindAllWhere(ByVal where_clause, ByVal order_by, ByVal offset, ByVal limit)
Dim sql : sql = "Select [Body], [CategoryID], [CreatedDate], [IsPublished], [PostID], [PublishedDate], [Slug], [Summary], [Title], [UpdatedDate] FROM [Posts]"
Dim whereText : whereText = ""
If Not IsEmpty(where_clause) Then
If Not IsNull(where_clause) Then whereText = Trim(CStr(where_clause))
End If
If Len(whereText) > 0 Then
sql = sql & " WHERE " & whereText
End If
sql = sql & BuildOrderBy(order_by, "[PostID]")
Dim offsetCount, limitCount
If IsNumeric(offset) Then
offsetCount = CLng(offset)
Else
offsetCount = 0
End If
If offsetCount < 0 Then offsetCount = 0
If IsNumeric(limit) Then
limitCount = CLng(limit)
Else
limitCount = 0
End If
Dim rs : Set rs = DAL.Query(sql, Empty)
Dim list : Set list = new LinkedList_Class
Dim skipped, added
skipped = 0
added = 0
Do Until rs.EOF
If skipped < offsetCount Then
skipped = skipped + 1
ElseIf limitCount <= 0 Or added < limitCount Then
list.Push Automapper.AutoMap(rs, "POBO_Posts")
added = added + 1
End If
If limitCount > 0 And added >= limitCount Then Exit Do
rs.MoveNext
Loop
Set FindAllWhere = list
Destroy rs
End Function
Public Function Find(where_kvarray, order_string_or_array)
Dim sql : sql = "Select [Body], [CategoryID], [CreatedDate], [IsPublished], [PostID], [PublishedDate], [Slug], [Summary], [Title], [UpdatedDate] FROM [Posts]"
Dim where_keys, where_values, i
@@ -149,21 +197,65 @@ Class PostsRepository_Class
QI = "[" & Replace(CStr(name), "]", "]]") & "]"
End Function
Private Function BuildOrderBy(orderArg, defaultCol)
Private Function BuildOrderBy(ByVal orderArg, ByVal defaultCol)
Dim s : s = ""
If IsEmpty(orderArg) Or IsNull(orderArg) Or orderArg = "" Then
s = " ORDER BY " & defaultCol & " ASC"
ElseIf IsArray(orderArg) Then
If IsArray(orderArg) Then
Dim i : s = " ORDER BY "
For i = 0 To UBound(orderArg)
If i > 0 Then s = s & ", "
s = s & QI(orderArg(i))
Next
ElseIf IsEmpty(orderArg) Then
s = " ORDER BY " & defaultCol & " ASC"
ElseIf IsNull(orderArg) Then
s = " ORDER BY " & defaultCol & " ASC"
ElseIf CStr(orderArg) = "" Then
s = " ORDER BY " & defaultCol & " ASC"
ElseIf IsSafeOrderExpression(orderArg) Then
Dim parts : parts = Split(Trim(CStr(orderArg)), " ")
s = " ORDER BY " & QI(parts(0))
If UBound(parts) = 1 Then s = s & " " & UCase(parts(1))
Else
s = " ORDER BY " & QI(orderArg)
End If
BuildOrderBy = s
End Function
Private Function IsSafeOrderExpression(ByVal orderArg)
Dim raw : raw = Trim(CStr(orderArg))
Dim parts : parts = Split(raw, " ")
IsSafeOrderExpression = False
If UBound(parts) < 0 Or UBound(parts) > 1 Then Exit Function
If Not IsSafeIdentifier(parts(0)) Then Exit Function
If UBound(parts) = 1 Then
If UCase(parts(1)) <> "ASC" And UCase(parts(1)) <> "DESC" Then Exit Function
End If
IsSafeOrderExpression = True
End Function
Private Function IsSafeIdentifier(ByVal value)
Dim i, ch
value = CStr(value)
If Len(value) = 0 Then
IsSafeIdentifier = False
Exit Function
End If
For i = 1 To Len(value)
ch = Mid(value, i, 1)
If Not ((ch >= "a" And ch <= "z") Or _
(ch >= "A" And ch <= "Z") Or _
(ch >= "0" And ch <= "9") Or _
ch = "_") Then
IsSafeIdentifier = False
Exit Function
End If
Next
IsSafeIdentifier = True
End Function
End Class
Dim PostsRepository__Singleton


+ 40
- 0
app/views/Posts/edit.asp Ver arquivo

@@ -0,0 +1,40 @@
<div class="row">
<div class="col-lg-8">
<div class="card shadow-sm">
<div class="card-body">
<h1 class="h3 mb-4">Edit Post</h1>
<form method="post" action="/posts/<%= H(post.PostID) %>">
<div class="mb-3">
<label class="form-label" for="Title">Title</label>
<input class="form-control" type="text" id="Title" name="Title" value="<%= H(post.Title) %>" required>
</div>
<div class="mb-3">
<label class="form-label" for="Summary">Summary</label>
<textarea class="form-control" id="Summary" name="Summary" rows="3"><%= H(post.Summary) %></textarea>
</div>
<div class="mb-3">
<label class="form-label" for="Body">Body</label>
<textarea class="form-control" id="Body" name="Body" rows="10" required><%= H(post.Body) %></textarea>
</div>
<div class="mb-4">
<label class="form-label" for="CategoryID">Category ID</label>
<input class="form-control" type="number" id="CategoryID" name="CategoryID" min="0" value="<%= H(post.CategoryID) %>">
</div>
<div class="d-flex flex-wrap gap-2">
<button class="btn btn-primary" type="submit">Update Post</button>
<a class="btn btn-outline-secondary" href="/posts">Cancel</a>
</div>
</form>
<form method="post" action="/posts/<%= H(post.PostID) %>/delete" class="mt-3">
<button class="btn btn-outline-danger" type="submit">Delete Post</button>
</form>
</div>
</div>
</div>
</div>

+ 62
- 0
app/views/Posts/index.asp Ver arquivo

@@ -0,0 +1,62 @@
<div class="d-flex align-items-center justify-content-between mb-4">
<div>
<h1 class="h3 mb-1">Posts</h1>
<p class="text-muted mb-0">Published articles from ASPBlogBrainOrdure.</p>
</div>
<a class="btn btn-primary" href="/posts/new">New Post</a>
</div>
<%
Dim postIter, postItem, shownCount
Set postIter = posts.Iterator()
shownCount = 0
If posts.Count = 0 Then
%>
<div class="alert alert-secondary">No published posts are available yet.</div>
<%
Else
%>
<div class="row gy-3">
<%
Do While postIter.HasNext And shownCount < 20
Set postItem = postIter.GetNext()
shownCount = shownCount + 1
%>
<div class="col-12">
<article class="card shadow-sm">
<div class="card-body">
<div class="d-flex flex-column flex-md-row justify-content-between gap-2">
<h2 class="h5 mb-1">
<a href="/posts/<%= Server.URLEncode(CStr(postItem.Slug)) %>" class="text-decoration-none">
<%= H(postItem.Title) %>
</a>
</h2>
<%
Dim publishedText
publishedText = ""
If IsDate(postItem.PublishedDate) Then
If CDate(postItem.PublishedDate) > #1/1/1970# Then
publishedText = FormatDateTime(postItem.PublishedDate, vbLongDate)
End If
End If
If Len(publishedText) > 0 Then
%>
<span class="small text-muted"><%= H(publishedText) %></span>
<%
End If
%>
</div>
<p class="text-muted mb-3"><%= H(postItem.Summary) %></p>
<a class="btn btn-sm btn-outline-primary" href="/posts/<%= Server.URLEncode(CStr(postItem.Slug)) %>">Read</a>
</div>
</article>
</div>
<%
Loop
%>
</div>
<%
End If
%>

+ 36
- 0
app/views/Posts/new.asp Ver arquivo

@@ -0,0 +1,36 @@
<div class="row">
<div class="col-lg-8">
<div class="card shadow-sm">
<div class="card-body">
<h1 class="h3 mb-4">New Post</h1>
<form method="post" action="/posts">
<div class="mb-3">
<label class="form-label" for="Title">Title</label>
<input class="form-control" type="text" id="Title" name="Title" required>
</div>
<div class="mb-3">
<label class="form-label" for="Summary">Summary</label>
<textarea class="form-control" id="Summary" name="Summary" rows="3"></textarea>
</div>
<div class="mb-3">
<label class="form-label" for="Body">Body</label>
<textarea class="form-control" id="Body" name="Body" rows="10" required></textarea>
</div>
<div class="mb-4">
<label class="form-label" for="CategoryID">Category ID</label>
<input class="form-control" type="number" id="CategoryID" name="CategoryID" min="0" value="0">
</div>
<div class="d-flex gap-2">
<button class="btn btn-primary" type="submit">Create Post</button>
<a class="btn btn-outline-secondary" href="/posts">Cancel</a>
</div>
</form>
</div>
</div>
</div>
</div>

+ 33
- 0
app/views/Posts/show.asp Ver arquivo

@@ -0,0 +1,33 @@
<article class="card shadow-sm">
<div class="card-body">
<div class="mb-3">
<a href="/posts" class="small text-decoration-none">&larr; Back to posts</a>
</div>
<h1 class="h2 mb-2"><%= H(post.Title) %></h1>
<%
Dim publishedText
publishedText = ""
If IsDate(post.PublishedDate) Then
If CDate(post.PublishedDate) > #1/1/1970# Then
publishedText = FormatDateTime(post.PublishedDate, vbLongDate)
End If
End If
If Len(publishedText) > 0 Then
%>
<p class="text-muted"><%= H(publishedText) %></p>
<%
End If
Dim postBody
postBody = H(post.Body)
postBody = Replace(postBody, vbCrLf, "<br>")
postBody = Replace(postBody, vbCr, "<br>")
postBody = Replace(postBody, vbLf, "<br>")
%>
<div class="fs-5 lh-lg"><%= postBody %></div>
</div>
</article>

Carregando…
Cancelar
Salvar

Powered by TurnKey Linux.