Fix: Error uploading an attachment.
New: Added courses to article view and set up configuration settings.
New: Added NotEnrolled
status to property MyStatus
on courses, modules and activities.
New: Property Group.Courses
.
Update: Moved pages used for method views to templates.
Fix: Application.GenerateHTMLMenu(MenuItem, Depth, IncludeURLWithSubMenus)
did not include the URL menus with sub-menus when requested.
Fix: Error in new process path when parameters attribute passed in URL.
Fix: Error when confirmation message included an apostrophe.
Fix: When an attachment is deleted the file is deleted if it is in the item's local folder.
New: Base styles.
Fix: After adding a new item via BusinessCollection.AddNew
the system now redirects back to the collection view.
New: Learning management system: Courses, Modules, Activities, Enrolments and Results. Courses inherit trading items so together with the order management systems they can be ordered and paid for creating an enrolment. A course can have many modules which are used to group activities. Activities are currently simply video tutorials but future development will include assessments or other activities to be determined. A student (user) must be enrolled in a course before they can start it. Results are currently only record the status of the activity (in progress or completed). Future developments may include assessment results.
New: Articles (pages, blog posts, testimonials, courses, etc.) can have a video.
Fix: Adding a new item with a file/image did not upload the file/image to the correct folder.
Fix: When resetting the parent membership expiry also reset the auto renew in child memberships.
Fix: Allow edit on Membership.AutoRenew
.
Shortcuts will match the business objects structure starting from the application (website). For example, any application object property or method accessible by the user can be accessed as follows:
/login will return a form for the Website.Login
method
/register will return a form for the Website.Register
method
/configure-components will return a form for the Website.ConfigureComponents
method
/user will return the logged in user profile from Website.User
/licensee will return the licensee profile from Website.Licensee
From there we can add properties to the application (website). For example, Add a property called Shop which returns a collection of products filtered to only published products sorted by date published descending. Now I can access it as:
/shop
Now say I want to filter it by a category. First, I need to create a category filter method on the products collection as Products.FilterByCategory(Category)
returns Products (self). The Category parameter can be an ID, FileName or Category object. So, we can now return a filtered shop as:
/shop/filter-by-category/furniture
Which will in essence run Website.Shop.FilterByCategory(“furniture”)
Now /filter-by-category is not very nice in the URL so for each property and method you will be able to set an alternative filename. For this one I would simple call it category. So now it can be accessed:
/shop/category/furniture
Now we can add more filter methods to products for tags, brands, authors, etc.
/shop/category/shoes/tag/white/brand/nike
They can be in any order and end up with the same result, for example:
/shop/brand/nike/category/shoes/tag/white
You could also call the same filter method multiple times:
/shop/tag/large/tag/round/tag/white
You can also add methods to a collection to sort, for example, say I create a sort method which simply set the sort order on price as Products.SortByLowestPriceFirst()
returns Products (self). I would give it a filename lowest-price-first. Then it could be called via:
/shop/lowest-price-first
To access an item in the shop it would be simply:
/shop/item/widget
Which will return Website.Shop.Item(“widget”)
Again, it is not very nice to have /item in the URL so I will make it the default method of the collection. So now you can access as:
/shop/widget
Which will return Website.Shop(“widget”)
which is the same as Website.Shop.Item(“widget”)
If you want to use an ID, you can similarly say:
/shop/1234
Which will return Website.Shop(1234)
or Website.Shop.Item(1234)
Note: to edit an object/item you need to add /edit to the URL. For example:
/shop/widget/edit
Note: any filename of an item in a collection cannot be the filename of a property or method in a collection. For example, say you name a product “tag” then /shop/tag will bring up Website.Shop.FilterByTag
method, not the product Website.Shop(“tag”)
, as the FilterByTag method has a filename of tag. Filenames are searched for in properties first, then methods and if not found applied to the default method which in this case is Item. Alternatively, the product tag in this case, you would have to call via the item method or ID as follows:
/shop/item/tag
/shop/1234
Here are a few more examples:
list all the related items of the widget product | /shop/widget/related-items |
|
list other products the supplier of the widget | /shop/widget/supplier/products |
|
Add widget to cart | /shop/widget/add-to-cart |
|
List all with price less than 1000 | /shop/price-less-than/1000 |
|
Let’s examine a few URLs:
/user |
|
/register |
|
/contact-us |
|
/countries |
|
/members |
|
/members/rules |
|
/members/board-members |
|
The system will first check the properties for the filename, then methods and finally and if not found will apply to the default method.
/user was found in properties
/register was found in methods
Notice /contact-us, /members and /countries were all found in the default method. We could set up a default method on the application called Item and in that method we search for the filename first in pages then groups and finally collections. So:
/contact-us returns a page
/countries returns a collection
/members returns a group
With /members/rules and /members/board-members we would also need to set up a default method on Group and call it Item which we search for the filename first in pages then subgroups. So:
/members/rules would return a page
/members/board-members would return a subgroup
The template name will match the calling properties/methods firstly otherwise the outputs type then any inherited types.
URL | Template Name Used in Priority |
/login | website.login method |
/shop /shop/category/furniture /shop/brand/nike/tag/white/lowest-price-first Note: Due to the filter and sort methods returning the | website.shop products trading-items articles items business-collection business-object |
/shop/widget/supplier/products | website.shop.item.supplier.products user.products products trading-items articles items business-collection business-object |
/shop/widget | website.shop.item product trading-item article item business-collection-item business-object |
/shop/widget/edit | website.shop.item.edit product.edit trading-item.edit article.edit item.edit business-collection-item.edit business-object.edit method |
The system should have at least the following templates:
New: Currently under construction is a new way to process the path (URL). When Application.ProcessPathVersion
is set to 2, new shortcuts and template selection for objects and methods are processed via this new method. See Proposed New Shortcuts and Template Selection. Currently only some paths for HTML and JSON output are available with XML and CSV output in future versions.
New: BusinessObject.ToHTML
will return HTML form based on the current user access rights to the object and its properties and methods.
New: BusinessObject.MethodToHTML(Method)
will return HTML form based on the current user access rights to the object's method and its parameters.
New: BusinessObject.ToJSON
will return JSON based on the current user access rights to the object and its properties.
New: Object and method view form design when PageType=ObjectView
or PageType=MethodView
and Application.ProcessPathVersion
set to 2.
New: Application.GenerateMembershipRenewalOrders
- When Membership.AutoRenew
is set, an order will be generated Membership.Subscription.AutoRenewDue
time period before it expires. If the member has stored payment methods then the system will attempt to take payment for the subscription and process the renewal otherwise an invoice is sent to the member.