Book Manager for Umbraco 8 ‐ MO - FadiZahhar/umbraco8showandtell GitHub Wiki
This class represents the data structure for a book entity in the application.
- Id: Primary key, auto-incremented.
- Title: Required; maximum length of 150 characters.
- Author: Required; maximum length of 100 characters.
- Year: Must be between 1450 and 2100, ensuring realistic publication years.
-
ISBN: Required; must match the pattern
123-1234567890
.
Data annotations are used for validation, ensuring data integrity before database operations.
Handles direct interactions with the database using NPoco and Umbraco's IScopeProvider.
-
GetAll()
: Retrieves all book records. -
GetById(int id)
: Fetches a single book by its ID. -
Insert(Book book)
: Adds a new book record. -
Update(Book book)
: Updates an existing book record. -
Delete(int id)
: Removes a book record by ID. -
Search(string term, int page, int pageSize)
: Performs a paginated search based on the term across Title, Author, and ISBN fields.
Each method ensures proper scope management, committing transactions where necessary.
Acts as an intermediary between controllers and the repository, encapsulating business logic.
- Delegates CRUD operations to the repository.
- Handles search functionality with pagination.
This separation of concerns promotes maintainability and testability.
An Umbraco API controller exposing endpoints for public access.
-
GetAllBooks()
: Returns a list of all books.
This controller can be extended to include more endpoints as needed.
Registers the custom dashboard within Umbraco's backoffice.
- alias: Unique identifier for the dashboard.
- view: Path to the HTML template.
- sections: Specifies the Umbraco section where the dashboard appears.
- weight: Determines the dashboard's position in the section.
- javascript: Includes the controller script.
- css: Includes styling for the dashboard.
Defines the structure and layout of the dashboard using AngularJS directives.
- Displays a list of books with pagination.
- Provides forms for adding and editing books.
- Includes search functionality.
- Offers CSV export capability.
Manages the dashboard's state and behavior.
-
loadBooks()
: Initializes the book list. -
searchBooks()
: Filters books based on the search term. -
newBook()
: Prepares the form for adding a new book. -
editBook(book)
: Loads a book's data into the form for editing. -
saveBook(form)
: Validates and submits the form data. -
deleteBook(id)
: Removes a book from the list. -
exportBooks()
: Triggers the CSV export.
The controller ensures a responsive and interactive user experience within the Umbraco backoffice.
The Book Manager is a custom backoffice dashboard for Umbraco 8 that allows administrators to manage a collection of books. It supports CRUD operations, search, pagination, validation, and CSV export.
Built with:
- Umbraco 8 (C#, ASP.NET MVC, NPoco)
- AngularJS (v1.8.2)
- W3.CSS for lightweight styling
- List books with pagination
- Search by title, author, or ISBN
- Create, edit, delete book entries
- Client and server-side validation
- CSV export of book list
File: /Models/Book.cs
using System.ComponentModel.DataAnnotations;
using NPoco;
namespace HighlyDeveloped.Core.Models
{
[TableName("Books")]
[PrimaryKey("Id", AutoIncrement = true)]
public class Book
{
public int Id { get; set; }
[Required]
[StringLength(150)]
public string Title { get; set; }
[Required]
[StringLength(100)]
public string Author { get; set; }
[Range(1450, 2100)] // Reasonable year range for books
public int Year { get; set; }
[Required]
[RegularExpression(@"^\d{3}-\d{10}$", ErrorMessage = "ISBN must be in the format 123-1234567890")]
public string ISBN { get; set; }
}
}
File: /Migrations/BooksTableMigration.cs
[Migration("1.0.0", 1, "HighlyDeveloped")]
public class BooksTableMigration : MigrationBase
{
public override void Migrate()
{
if (!_context.Database.TableExists("Books"))
{
Create.Table<Book>().Do();
}
}
}
Composer: Registers the migration.
[RuntimeLevel(MinLevel = RuntimeLevel.Run)]
public class BookComposer : IUserComposer
{
public void Compose(Composition composition)
{
composition.Components().Append<BookComponent>();
}
}
Component: Executes the migration.
public class BookComponent : IComponent
{
private readonly IMigrationPlanExecutor _executor;
private readonly IScopeProvider _scopeProvider;
public BookComponent(IMigrationPlanExecutor executor, IScopeProvider scopeProvider)
{
_executor = executor;
_scopeProvider = scopeProvider;
}
public void Initialize()
{
var plan = new MigrationPlan("HighlyDeveloped");
plan.From(string.Empty).To<BooksTableMigration>("books-table-migration");
_executor.Execute(plan);
}
public void Terminate() { }
}
File: /Repositories/BookRepository.cs
Handles database queries and pagination.
public IEnumerable<Book> GetAll() {...}
public Book GetById(int id) {...}
public void Insert(Book book) {...}
public void Update(Book book) {...}
public void Delete(int id) {...}
public (IEnumerable<Book> Books, int TotalCount) Search(string term, int page, int pageSize) {...}
File: /Services/BookService.cs
Handles business logic and validation.
public IEnumerable<string> Validate(Book book) {...}
public void Save(Book book) {...}
public void Delete(int id) {...}
File: /Controllers/BookApiController.cs
Used by the Angular frontend.
[HttpGet] public IEnumerable<Book> GetAll() {...}
[HttpPost] public IActionResult PostSave([FromBody] Book book) {...}
[HttpPost] public IActionResult PostDelete([FromBody] int id) {...}
[HttpGet] public IActionResult Search(...) {...}
[HttpGet] public IActionResult ExportCsv() {...}
File: /App_Plugins/BookManager/package.manifest
{
"dashboards": [
{
"alias": "bookManagerDashboard",
"view": "/App_Plugins/BookManager/dashboard/dashboard.html",
"sections": [ "content" ],
"weight": 10,
"label": "Book Manager"
}
],
"javascript": [
"~/App_Plugins/BookManager/dashboard/dashboard.controller.js"
],
"css": [
"https://www.w3schools.com/w3css/5/w3.css",
"~/App_Plugins/BookManager/dashboard/dashboard.css"
]
}
File: dashboard.html
Contains:
- Book list table
- Search box and pagination
- Edit/create form with validation
- Export and cancel buttons
File: dashboard.controller.js
.controller("BookManagerDashboardController", function ($scope, $http) {
// vm setup
// loadBooks, searchBooks, goToPage, editBook, saveBook, deleteBook, cancel, exportBooks
});
File: dashboard.css
Custom styling for:
- Input field
- Validation messages
- Pagination controls
Endpoint: /umbraco/backoffice/api/BookApi/ExportCsv
Downloads a CSV file with all book data.
Implementation example:
var sb = new StringBuilder();
sb.AppendLine("Id,Title,Author,Year,ISBN");
foreach (var book in books) {
sb.AppendLine($"{book.Id},{book.Title},{book.Author},{book.Year},{book.ISBN}");
}
return File(Encoding.UTF8.GetBytes(sb.ToString()), "text/csv", "books.csv");
- Required fields: Title, Author, Year, ISBN
- ISBN format:
123-1234567890
- Year: between 1450 and 2100
- Server-side validation using the service layer
- Client-side validation using AngularJS