Skip to content

Commit

Permalink
DictionaryAttributePrefix and ModelExplorer support in liquid (Orchar…
Browse files Browse the repository at this point in the history
  • Loading branch information
ns8482e authored and scleaver committed Apr 15, 2020
1 parent e0b0a38 commit 7965ad2
Show file tree
Hide file tree
Showing 12 changed files with 417 additions and 17 deletions.
4 changes: 4 additions & 0 deletions src/OrchardCore.Modules/OrchardCore.Demo/AdminMenu.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ public Task BuildNavigationAsync(string name, NavigationBuilder builder)
.Action("Index", "Admin", new { area = "OrchardCore.Demo" }))
.Add(S["This is Menu Item 3.2"], subItem => subItem
.Action("Index", "Admin", new { area = "OrchardCore.Demo" }))
)
.Add(S["Todo (Liquid - Frontend)"], "0", item => item
.Action("Index", "Todo", new { area = "OrchardCore.Demo" })
)
);

Expand Down
114 changes: 114 additions & 0 deletions src/OrchardCore.Modules/OrchardCore.Demo/Controllers/TodoController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using OrchardCore.Demo.Models;
using OrchardCore.Demo.ViewModels;
using YesSql;

namespace OrchardCore.Demo.Controllers
{
public class TodoController : Controller
{
private readonly ISession _session;
private readonly Entities.IIdGenerator _idGenerator;

public TodoController(ISession session, Entities.IIdGenerator idGenerator)
{
_session = session;
_idGenerator = idGenerator;
}

public async Task<IActionResult> Index()
{
var list = (await _session.Query<TodoModel>().ListAsync())
.Select(m => new TodoViewModel()
{
TodoId = m.TodoId,
Text = m.Text,
DueDate = m.DueDate,
IsCompleted = m.IsCompleted
})
.ToList();

return View(list);
}

public IActionResult Create()
{
var viewModel = new TodoViewModel();
viewModel.TodoId = _idGenerator.GenerateUniqueId();
viewModel.DisplayMode = "Edit";
return View("Edit", viewModel);
}

public async Task<IActionResult> Edit(string todoId)
{
var model = (await _session.Query<TodoModel>().ListAsync())
.Where(m => m.TodoId == todoId)
.FirstOrDefault();

if (model == null)
{
return NotFound();
}

var viewModel = new TodoViewModel()
{
TodoId = model.TodoId,
Text = model.Text,
DueDate = model.DueDate,
IsCompleted = model.IsCompleted,
DisplayMode = "Edit"
};

return View(viewModel);
}

[HttpPost]
public async Task<IActionResult> Update(TodoViewModel viewModel, string returnUrl = "")
{
if (ModelState.IsValid)
{
var model = (await _session.Query<TodoModel>().ListAsync())
.Where(m => m.TodoId == viewModel.TodoId)
.FirstOrDefault();

if (model == null)
{
model = new TodoModel() { TodoId = viewModel.TodoId };
}

model.Text = viewModel.Text;
model.DueDate = viewModel.DueDate;
model.IsCompleted = viewModel.IsCompleted;

_session.Save(model);

if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}

return RedirectToAction("Index", "Todo");
}

return View(viewModel);
}

public async Task<IActionResult> Delete(string todoId)
{
var model = (await _session.Query<TodoModel>().ListAsync())
.Where(m => m.TodoId == todoId)
.FirstOrDefault();

if (model == null)
{
return NotFound();
}

_session.Delete(model);

return RedirectToAction("Index", "Todo");
}
}
}
12 changes: 12 additions & 0 deletions src/OrchardCore.Modules/OrchardCore.Demo/Models/TodoModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;

namespace OrchardCore.Demo.Models
{
public class TodoModel
{
public string TodoId { get; set; }
public string Text { get; set; }
public DateTime DueDate { get; set; }
public bool IsCompleted { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using System;
using System.ComponentModel.DataAnnotations;
using OrchardCore.DisplayManagement.Views;

namespace OrchardCore.Demo.ViewModels
{
public class TodoViewModel : ShapeViewModel
{
public TodoViewModel()
{
Metadata.Type = "Todo";
}

public string TodoId { get; set; }

[Required]
public string Text { get; set; }

[Required]
public DateTime DueDate { get; set; }

public bool IsCompleted { get; set; }

public string DisplayMode
{
get
{
return Metadata.DisplayType;
}
set
{
var alternate = $"Todo_{value}";
if (Metadata.Alternates.Contains(alternate))
{
if (Metadata.Alternates.Last == alternate)
{
return;
}

Metadata.Alternates.Remove(alternate);
}

Metadata.Alternates.Add(alternate);
Metadata.DisplayType = value;
}
}
}
}
50 changes: 50 additions & 0 deletions src/OrchardCore.Modules/OrchardCore.Demo/Views/Todo.Edit.liquid
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{% form action: "Update", method: "post", enctype: "multipart/form-data", route_returnUrl: Request.Query["returnurl"] %}
<table>
<tr>
<td>
{% helper "div", validation_summary: "All"%}
</td>
</tr>
<tr>
<td>
{% helper "label", for: "Text"%}
</td>
<td>
{% helper "input", for: "Text", class: "form-control"%}
</td>
<td>
{% helper "span", validation_for: "Text" %}
</td>
</tr>
<tr>
<td>
{% helper "label", for: "DueDate"%}
</td>
<td>
{% helper "input", for: "DueDate", class: "form-control" %}
</td>
<td>
{% helper "span", validation_for: "DueDate" %}
</td>
</tr>
<tr>
<td>
{% helper "label", for: "IsCompleted" %}
</td>
<td>
{% helper "input", for: "IsCompleted" %}
</td>
<td></td>
</tr>
<tr>
<td>
{% helper "input", for: "TodoId", type: "hidden" %}
<input type="submit" value="Save" class="btn btn-primary"/>
<a href="{{Request.Query["returnUrl"]}}" class="btn btn-secondary">Cancel</a>
</td>
</tr>
</table>
{% endform %}

{% script src:"https://cdn.jsdelivr.net/npm/jquery-validation@1.19.1/dist/jquery.validate.min.js", at: "Foot", dependsOn: "jquery" %}
{% script src:"https://cdn.jsdelivr.net/npm/jquery-validation-unobtrusive@3.2.11/dist/jquery.validate.unobtrusive.min.js", at: "Foot", dependsOn: "jquery" %}
15 changes: 15 additions & 0 deletions src/OrchardCore.Modules/OrchardCore.Demo/Views/Todo.liquid
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<td>
{% a controller: "Todo", action: "Edit", route_todoid: Model.TodoId , route_returnurl: Request.Path %}
{{ Model.Text }}
{% enda %}
</td>

<td>{{ Model.DueDate }}</td>

<td>{{ Model.IsCompleted }}</td>

<td>
{% a action: "Delete" , class: "btn btn-danger", route_todoid: Model.TodoId %}
Delete
{% enda %}
</td>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<h1>Add/Edit Todo (Liquid)</h1>
{{ Model | shape_render }}
17 changes: 17 additions & 0 deletions src/OrchardCore.Modules/OrchardCore.Demo/Views/Todo/Index.liquid
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<h1>List of Todos (Liquid)</h1>
<table class="table table-bordered">
<tr>
<th>Todo</th>
<th>Due Date</th>
<th>Completed?</th>
<th></th>
{% for item in Model %}
<tr>
{{ item | shape_render }}
</tr>
{% endfor %}
</tr>
</table>
{% block "a", controller: "Todo", action: "Create", route_returnurl: Request.Path, class: "btn btn-success" %}
Add
{% endblock %}
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ static LiquidViewTemplate()
Factory.RegisterBlock<HelperBlock>("block");
Factory.RegisterBlock<NamedHelperBlock>("a");
Factory.RegisterBlock<NamedHelperBlock>("zone");
Factory.RegisterBlock<NamedHelperBlock>("scriptblock");
Factory.RegisterBlock<NamedHelperBlock>("form");
Factory.RegisterBlock<NamedHelperBlock>("scriptblock");

// Dynamic caching
Factory.RegisterBlock<CacheBlock>("cache");
Expand Down Expand Up @@ -181,15 +182,16 @@ public ShapeAccessor() : base(_getter)
return shape.Items;
}
// Resolve Model.Content.MyType-MyField-FieldType_Display__DisplayMode
// Resolves Model.Content.MyType-MyField-FieldType_Display__DisplayMode
var namedShaped = shape.Named(n);
if (namedShaped != null)
{
return namedShaped;
}
// Resolve Model.Content.MyNamedPart
// Resolve Model.Content.MyType__MyField OR Resolve Model.Content.MyType-MyField
// Resolves Model.Content.MyNamedPart
// Resolves Model.Content.MyType__MyField
// Resolves Model.Content.MyType-MyField
return shape.NormalizedNamed(n.Replace("__", "-"));
}
Expand Down

0 comments on commit 7965ad2

Please sign in to comment.