Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for DictionaryAttributePrefix and ModelExplorer property in liquid #5099

Merged
merged 32 commits into from
Apr 12, 2020
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
007a648
Added support for DictionaryAttributePrefix in liquid as per comments…
ns8482e Dec 21, 2019
012c200
Added form block
ns8482e Dec 21, 2019
258f250
remove extra space
ns8482e Dec 21, 2019
a90c0a1
Added Support for Model expressions, possibly fixes #4426
ns8482e Dec 24, 2019
82c5b4a
Merge branch 'dev' of https://github.com/OrchardCMS/OrchardCore into …
ns8482e Jan 8, 2020
2902e2b
reverted to simplified type
ns8482e Jan 8, 2020
22c9ff2
created FastGetterProperty for getter
ns8482e Jan 8, 2020
6cd48e9
review feedback
ns8482e Feb 15, 2020
cb27e8e
Merge branch 'dev' of https://github.com/OrchardCMS/OrchardCore into …
ns8482e Feb 15, 2020
d162855
Added Liquid CRUD samples that use asp-for, asp-validation-for, asp-r…
ns8482e Feb 18, 2020
3f71acb
Merge branch 'dev' of https://github.com/OrchardCMS/OrchardCore into …
ns8482e Feb 18, 2020
c4d7fad
Updated document
ns8482e Feb 19, 2020
bd21669
docus for route-data
ns8482e Feb 19, 2020
cd0d8f6
Merge branch 'dev' into ns8482e/liquid-idictonary-support
sebastienros Mar 5, 2020
1935f0c
Update after merging dev
jtkech Mar 5, 2020
4cad1ec
Merge branch 'dev' of https://github.com/OrchardCMS/OrchardCore into …
ns8482e Mar 21, 2020
9fd64b8
Review feedback
ns8482e Mar 21, 2020
3d989e2
EOL
ns8482e Mar 21, 2020
dd9d68e
Update AdminMenu.cs
jtkech Mar 22, 2020
9785a97
Create TodoViewModel.cs
jtkech Mar 22, 2020
d542940
Update TodoModel.cs
jtkech Mar 22, 2020
154eb09
Update TodoController.cs
jtkech Mar 22, 2020
f54d7d6
Update Todo.Edit.liquid
jtkech Mar 22, 2020
0841c14
Update Todo.liquid
jtkech Mar 22, 2020
dc8448c
Update Edit.liquid
jtkech Mar 22, 2020
bee53d6
Update Index.liquid
jtkech Mar 22, 2020
cbebd49
Update LiquidViewTemplate.cs
jtkech Mar 22, 2020
899431c
Update LiquidTagHelperActivator.cs
jtkech Mar 22, 2020
728d2c7
Update StringExtensions.cs
jtkech Mar 22, 2020
7f95cb5
Update README.md
jtkech Mar 22, 2020
1c0a553
Update README.md
jtkech Mar 22, 2020
94167de
Update README.md
ns8482e Mar 23, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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