-
Notifications
You must be signed in to change notification settings - Fork 60
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merged in issue/OCORE-1 (pull request #6)
OCORE-1: Training Demo átírása - Alapvető .NET Core és OrchardCore elemek bemutatása --HG-- branch : orchard-core
- Loading branch information
Showing
64 changed files
with
7,796 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
obj/ | ||
bin/ | ||
*.user | ||
wwwroot | ||
node_modules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,3 +2,5 @@ syntax: glob | |
obj/ | ||
bin/ | ||
*.user | ||
wwwroot | ||
node_modules |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
.colorField { | ||
.pickr { | ||
margin-top: 12px; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
/* | ||
* Now it's time to save something to the database. Orchard Core uses YesSql to store data in database which is | ||
* document database interface for relational databases. Simply put, you need to design your database as a document | ||
* database but it will be stored in your favorite SQL database. If you want to learn more go to | ||
* https://github.com/sebastienros/yessql and read the documentation. | ||
* | ||
* Here you will see how to store simple data in the database and then query it without actually using Orchard Core | ||
* content management features and practices (i.e. you can store non-Orchard Core content items). | ||
* | ||
* This demonstration will be really simple because more features will be shown later and you can also learn more from | ||
* the YesSql documentation. | ||
*/ | ||
|
||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using Lombiq.TrainingDemo.Indexes; | ||
using Lombiq.TrainingDemo.Models; | ||
using Microsoft.AspNetCore.Mvc; | ||
using Microsoft.AspNetCore.Mvc.Localization; | ||
using OrchardCore.DisplayManagement; | ||
using OrchardCore.DisplayManagement.ModelBinding; | ||
using OrchardCore.DisplayManagement.Notify; | ||
using YesSql; | ||
|
||
namespace Lombiq.TrainingDemo.Controllers | ||
{ | ||
public class DatabaseStorageController : Controller, IUpdateModel | ||
{ | ||
private readonly ISession _session; | ||
private readonly IDisplayManager<Book> _bookDisplayManager; | ||
private readonly INotifier _notifier; | ||
private readonly IHtmlLocalizer H; | ||
|
||
|
||
public DatabaseStorageController( | ||
ISession session, | ||
IDisplayManager<Book> bookDisplayManager, | ||
INotifier notifier, | ||
IHtmlLocalizer<DatabaseStorageController> htmlLocalizer) | ||
{ | ||
_session = session; | ||
_bookDisplayManager = bookDisplayManager; | ||
_notifier = notifier; | ||
H = htmlLocalizer; | ||
} | ||
|
||
|
||
// A page with a button that will call the CreateBooks POST action. | ||
// See it under /Lombiq.TrainingDemo/Store/CreateBooks. | ||
[HttpGet] | ||
public ActionResult CreateBooks() => View(); | ||
|
||
[HttpPost, ActionName(nameof(CreateBooks))] | ||
public ActionResult CreateBooksPost() | ||
{ | ||
// For demonstration purposes this will create 3 books and store them in the database one-by-one using the | ||
// ISession service. Note that you can even go to the database directly, circumventing YesSql too, by | ||
// injecting the IDbConnectionAccessor service and access the underlying connection. | ||
|
||
// Since storing them in the documents is not enough we need to index them to be able to | ||
// filter them in a query. | ||
// NEXT STATION: Indexes/BookIndex.cs | ||
foreach (var book in CreateDemoBooks()) | ||
{ | ||
// So now you understand what will happen in the background when this service is being called. | ||
_session.Save(book); | ||
} | ||
|
||
_notifier.Information(H["Books have been created in the database."]); | ||
|
||
return RedirectToAction(nameof(CreateBooks)); | ||
} | ||
|
||
// This page will display the books written by J.K. Rowling. | ||
// See it under /Lombiq.TrainingDemo/Store/JKRowlingBooks. | ||
public async Task<ActionResult> JKRowlingBooks() | ||
{ | ||
// ISession service is used for querying items. | ||
var jkRowlingBooks = await _session | ||
// First, we define what object (document) we want to query and what index should be used for | ||
// filtering. | ||
.Query<Book, BookIndex>() | ||
// In the .Where() method you can describe a lambda where the object will be the index object. | ||
.Where(index => index.Author == "J.K. (Joanne) Rowling") | ||
// When the query is built up you can call ListAsync() to execute it. This will return a list of books. | ||
.ListAsync(); | ||
|
||
// Now this is what we possibly understand now, we will create a list of display shapes from the previously | ||
// fetched books. | ||
var bookShapes = await Task.WhenAll(jkRowlingBooks.Select(async book => | ||
await _bookDisplayManager.BuildDisplayAsync(book, this))); | ||
|
||
// You can check out Views/Store/JKRowlingBooks.cshtml and come back here. | ||
return View(bookShapes); | ||
} | ||
|
||
// NEXT STATION: Models/PersonPart.cs | ||
|
||
|
||
private IEnumerable<Book> CreateDemoBooks() => | ||
new Book[] | ||
{ | ||
new Book | ||
{ | ||
CoverPhotoUrl = "/Lombiq.TrainingDemo/Images/HarryPotter.jpg", | ||
Title = "Harry Potter and The Sorcerer's Stone", | ||
Author = "J.K. (Joanne) Rowling", | ||
Description = "Harry hasn't had a birthday party in eleven years - but all that is about to " + | ||
"change when a mysterious letter arrives with an invitation to an incredible place." | ||
}, | ||
new Book | ||
{ | ||
Title = "Fantastic Beasts and Where To Find Them", | ||
Author = "J.K. (Joanne) Rowling", | ||
Description = "With his magical suitcase in hand, Magizoologist Newt Scamander arrives in New " + | ||
"York in 1926 for a brief stopover. However, when the suitcase is misplaced and some of his " + | ||
"fantastic beasts escape, there will be trouble for everyone." | ||
}, | ||
new Book | ||
{ | ||
Title = "The Hunger Games", | ||
Author = "Suzanne Collins", | ||
Description = "The nation of Panem, formed from a post-apocalyptic North America, is a country " + | ||
"that consists of a wealthy Capitol region surrounded by 12 poorer districts." | ||
} | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
/* | ||
* In this section you will learn how Orchard Core deals with displaying various information on the UI using reusable | ||
* components called shapes (see: | ||
* https://orchardcore.readthedocs.io/en/latest/OrchardCore/OrchardCore.DisplayManagement/README/#shapes). This is a | ||
* very huge and powerful part of Orchard Core, here you will learn the basics of Display Management. | ||
* | ||
* To demonstrate this basic functionality, we will create two slightly different pages for displaying information | ||
* about a book. | ||
*/ | ||
|
||
using System.Threading.Tasks; | ||
using Lombiq.TrainingDemo.Models; | ||
using Microsoft.AspNetCore.Mvc; | ||
using OrchardCore.DisplayManagement; | ||
using OrchardCore.DisplayManagement.ModelBinding; | ||
|
||
namespace Lombiq.TrainingDemo.Controllers | ||
{ | ||
// Notice that the controller implements the IUpdateModel interface. This interface encapsulates the properties and | ||
// methods related to ASP.NET Core MVC model binding. Orchard Core needs this model binding functionality outside | ||
// the controllers (you will see it later). | ||
public class DisplayManagementController : Controller, IUpdateModel | ||
{ | ||
// The core display management features can be used via the IDisplayManager service. The generic parameter will | ||
// be the object that needs to be displayed on the UI somehow. Don't forget to register this generic class with | ||
// the service provider (see: Startup.cs). | ||
private readonly IDisplayManager<Book> _bookDisplayManager; | ||
|
||
|
||
public DisplayManagementController(IDisplayManager<Book> bookDisplayManager) | ||
{ | ||
_bookDisplayManager = bookDisplayManager; | ||
} | ||
|
||
|
||
// Before we learn how shapes are generated using the display manager let's see what are these shapes actually. | ||
// Ad-hoc shapes can be created anywhere without the display manager. In this example we'll see how to create | ||
// an ad-hoc shape inside a view (or could be another shape). | ||
public ActionResult AdHocShape() => View(); | ||
|
||
// NEXT STATION: Views/DisplayManagement/AdHocShape.cshtml | ||
|
||
// First, create a page that will display a summary and some additional data of the book. | ||
// See it under /Lombiq.TrainingDemo/DisplayManagement/DisplayBook. | ||
public async Task<ActionResult> DisplayBook() | ||
{ | ||
// For demonstration purposes create a dummy book object. | ||
var book = CreateDemoBook(); | ||
|
||
// This method will generate a shape primarily for displaying information about the given object. | ||
var shape = await _bookDisplayManager.BuildDisplayAsync(book, this); | ||
|
||
// We will see how this display shape is generated and what will contain but first let's see how is this | ||
// rendered in the MVC view. | ||
// NEXT STATION: Go to Views/DisplayManagement/DisplayBook.cshtml. | ||
|
||
return View(shape); | ||
} | ||
|
||
// Let's generate another Book display shape, but now with a display type. | ||
// See it under /Lombiq.TrainingDemo/DisplayManagement/DisplayBookDescription. | ||
public async Task<ActionResult> DisplayBookDescription() | ||
{ | ||
// Generate another book object to be used for demonstration purposes. | ||
var book = CreateDemoBook(); | ||
|
||
// This time give an additional parameter which is the display type. If display type is given then Orchard | ||
// Core will search a cshtml file with a name [ClassName].[DisplayType].cshtml. | ||
var shape = await _bookDisplayManager.BuildDisplayAsync(book, this, "Description"); | ||
|
||
// NEXT STATION: Go to Views/Book.Description.cshtml | ||
|
||
return View(shape); | ||
} | ||
|
||
|
||
private Book CreateDemoBook() => | ||
new Book | ||
{ | ||
CoverPhotoUrl = "/Lombiq.TrainingDemo/Images/HarryPotter.jpg", | ||
Title = "Harry Potter and The Sorcerer's Stone", | ||
Author = "J.K. (Joanne) Rowling", | ||
Description = "Harry hasn't had a birthday party in eleven years - but all that is about to change " + | ||
"when a mysterious letter arrives with an invitation to an incredible place.", | ||
}; | ||
} | ||
} | ||
|
||
// If you've finished with both actions (and their .cshtml files as well), then | ||
// NEXT STATION: Controllers/DatabaseStorageController is what's next. |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/* | ||
* In this controller you will see again how to query items but this time items will be of the newly created Person | ||
* content type. It doesn't make too much difference but you need to keep in mind that the ContentItems are stored in | ||
* the documents (which contain the parts and fields serialized) and can have multiple index records referencing a | ||
* content item (e.g. the previously created PersonPartIndex that indexes data in from PersonPart). | ||
* | ||
* Note that there is no custom controller or action demonstrated for displaying the editor for the Person. Go to the | ||
* administration page (/Admin) and create a few Person content items, including ones with ages above 30. | ||
*/ | ||
|
||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using Lombiq.TrainingDemo.Indexes; | ||
using Microsoft.AspNetCore.Mvc; | ||
using OrchardCore.ContentManagement; | ||
using OrchardCore.ContentManagement.Display; | ||
using OrchardCore.DisplayManagement.ModelBinding; | ||
using OrchardCore.Modules; | ||
using YesSql; | ||
|
||
namespace Lombiq.TrainingDemo.Controllers | ||
{ | ||
public class PersonListController : Controller, IUpdateModel | ||
{ | ||
private readonly ISession _session; | ||
private readonly IClock _clock; | ||
private readonly IContentItemDisplayManager _contentItemDisplayManager; | ||
|
||
|
||
public PersonListController( | ||
ISession session, | ||
IClock clock, | ||
IContentItemDisplayManager contentItemDisplayManager) | ||
{ | ||
_session = session; | ||
_clock = clock; | ||
_contentItemDisplayManager = contentItemDisplayManager; | ||
} | ||
|
||
|
||
// See it under /Lombiq.TrainingDemo/PersonList/OlderThan30. | ||
public async Task<ActionResult> OlderThan30() | ||
{ | ||
var thresholdDate = _clock.UtcNow.AddYears(-30); | ||
var people = await _session | ||
// This will query for content items where the related PersonPartIndex.BirthDateUtc is lower than the | ||
// threshold date. Notice that there is no Where method. The Query method has an overload for that | ||
// which can be useful if you don't want to filter in multiple indexes. | ||
.Query<ContentItem, PersonPartIndex>(index => index.BirthDateUtc < thresholdDate) | ||
.ListAsync(); | ||
|
||
// Now let's build the display shape for a content item! Notice that this is not the IDisplayManager | ||
// service. The IContentItemDisplayManager is an abstraction over that and it's specifically for content | ||
// items. The reason we need that is that a ContentItem doesn't have a DisplayDriver but the ContentParts | ||
// and ContentFields attached to the ContentItem have. This service will handle generating all the drivers | ||
// created for these parts and fields. | ||
// NEXT STATION: Drivers/PersonPartDisplayDriver | ||
var shapes = await Task.WhenAll(people.Select(async person => | ||
await _contentItemDisplayManager.BuildDisplayAsync(person, this, "Summary"))); | ||
|
||
// Now assuming that you've already created a few Person content items on the dashboard and some of | ||
// these persons are more than 30 years old then this query will contain items to display. | ||
// NEXT STATION: Views/PersonList/OlderThan30.cshtml | ||
|
||
return View(shapes); | ||
} | ||
} | ||
} |
Oops, something went wrong.