Welcome to the Sitefinity 13.2 training course!
PLEASE DOWNLOAD:
https://github.com/Sitefinity/Telerik.Sitefinity.Samples.Quantum
https://sitefinitystore.blob.core.windows.net/files/Telerik.Sitefinity.Samples.Quantum/QuantumDB_v_132.zip
**Terminology**
Page
Page Template
Page Editor
-Zone editor
-Toolbox
Widgets
-Content Widget
-Grid Widget
-----------------------
**People who have VS, SQL Server and Sitefinity**
Abdullah S Aljaiban
Doha A Alawdah
Ruwaida I Mirdad
Abdullah M Mogren
Abdulrahman F Alloaihan
Khalil I Shehab
Maha R Onaizi
Riaz Ebrahim Pagarkar
Sahar S Khogeer
Ghada S Sundbul
**People who don't have development environment locally**
Monirah M Aldraiweesh
Maha A Almaneea
Mark Jamieson C Leonardo
Fatima Althuwaiqeb
Alaa Garni
----------
DRY principle
Do Not Repeat Yourself principle
Home Page
-1.1. Footer with breadcrumbs Page Template
-1.2. Header and footer Page Template
-1.3. Header Page Template
-1.4. Base Page Template
-........
i.e. the same as inheritance in C#
----------
http://23.100.229.188:8088
http://23.100.229.188:8088/Sitefinity
U1: user1@admin.com - Monirah M Aldraiweesh
U2: user2@admin.com - Mark Jamieson C Leonardo
U3: user3@admin.com - Maha A Almaneea
U4: user4@admin.com - Fatima Althuwaiqeb
U5: user5@admin.com - Alaa Garni
P: admin@2
NuGet package sources
-----------
Nuget Office
https://api.nuget.org/v3/index.json
Sitefinity Nuget
https://nuget.sitefinity.com/nuget
-----
https://dotnet.microsoft.com/download/dotnet-framework/thank-you/net48-developer-pack-offline-installer
---
https://drive.google.com/file/d/1NwHBSsp-VXpKRjn5fdKwe9IDTimrgiAP/view?usp=sharing
------
"https://api.spacexdata.com/v3/launches/latest"
----------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Web;
namespace SitefinityWebApp.Mvc.Models
{
public class FlightDataModel
{
public LaunchViewModel GetViewModel()
{
var getNextLaunchTask = System.Threading.Tasks.Task.Run(() => this.GetLaunchAsync());
getNextLaunchTask.Wait();
return getNextLaunchTask.Result;
}
private async System.Threading.Tasks.Task<LaunchViewModel> GetLaunchAsync()
{
using (var client = new System.Net.Http.HttpClient())
{
var jsonString = await client.GetStringAsync("https://api.spacexdata.com/v3/launches/latest");
return Newtonsoft.Json.JsonConvert.DeserializeObject<LaunchViewModel>(jsonString);
}
}
}
}
-----------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace SitefinityWebApp.Mvc.Models
{
public class LaunchViewModel
{
[Newtonsoft.Json.JsonProperty(PropertyName = "details")]
public string Details { get; set; }
[Newtonsoft.Json.JsonProperty(PropertyName = "mission_name")]
public string MissionName { get; set; }
}
}
----------
using SitefinityWebApp.Mvc.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Telerik.Sitefinity.Mvc;
namespace SitefinityWebApp.Mvc.Controllers
{
[ControllerToolboxItem(Name = "SpaceX_MVC", Title ="SpaceX", SectionName ="Aramco")]
public class FlightDataController : Controller
{
public ActionResult Index()
{
var model = new FlightDataModel();
var viewModel = model.GetViewModel();
return View("Index", viewModel);
}
public string Message { get; set; }
}
}
---------------
@model SitefinityWebApp.Mvc.Models.LaunchViewModel
<div class="jumbotron">
<h1>@Model.MissionName</h1>
<p>@Model.Details</p>
</div>Welcome
---------------
<p>@Model.Item.Fields.PublishedFirstIn</p>
-------------
Helpulf materials:
https://www.progress.com/documentation/sitefinity-cms/install-sitefinity
https://www.progress.com/documentation/sitefinity-cms/configure-and-start-a-project
https://www.progress.com/documentation/sitefinity-cms/licenses
https://www.progress.com/documentation/sitefinity-cms/login
https://www.progress.com/documentation/sitefinity-cms/dashboard-and-navigation
---------------
REMEBER to change the name of the namespace!!
using System;
using System.Collections.Generic;
using System.Linq;using SitefinityWebApp.Mvc.Models;
using System;
using System.Web;
using Telerik.Microsoft.Practices.Unity;
using Telerik.Sitefinity.Abstractions;
using Telerik.Sitefinity.Data;
using Telerik.Sitefinity.Frontend;
using Telerik.Sitefinity.Frontend.Mvc.Infrastructure.Routing;
using Telerik.Sitefinity.Frontend.News.Mvc.Models;
using Telerik.Sitefinity.Mvc;
using Telerik.Sitefinity.Services;
namespace SitefinityWebApp
{
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
Bootstrapper.Initialized += Bootstrapper_Initialized;
Bootstrapper.Bootstrapped += Bootstrapper_Bootstrapped;
}
private void Bootstrapper_Initialized(object sender, ExecutedEventArgs e)
{
if (e.CommandName == "Bootstrapped")
{
FrontendModule.Current.DependencyResolver.Rebind<INewsModel>().To<CategoryFilterNewsModel>();
}
}
protected void Bootstrapper_Bootstrapped(object sender, EventArgs e)
{
FeatherActionInvokerCustom.Register();
}
}
}
using System.Web;
namespace SitefinityWebApp.Controllers
{
public class TimeController: System.Web.Mvc.Controller
{
public string Index()
{
return DateTime.UtcNow.ToShortDateString();
}
}
}
-----
REMEBER to change the name of the namespace!!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;
namespace SitefinityWebApp
{
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
Telerik.Sitefinity.Abstractions.
Bootstrapper.Bootstrapped += Bootstrapper_Bootstrapped; ;
}
private void Bootstrapper_Bootstrapped(object sender, EventArgs e)
{
System.Web.Mvc.RouteCollectionExtensions.MapRoute(
System.Web.Routing.RouteTable.Routes,
"AramcoClassic",
"aramco/{controller}/{action}",
new { controller = "Time", action = "Index" });
}
protected void Session_Start(object sender, EventArgs e)
{
}
protected void Application_BeginRequest(object sender, EventArgs e)
{
}
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
}
protected void Application_Error(object sender, EventArgs e)
{
}
protected void Session_End(object sender, EventArgs e)
{
}
protected void Application_End(object sender, EventArgs e)
{
}
}
}
----
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Telerik.Sitefinity.Frontend.Mvc.Models;
using Telerik.Sitefinity.Model;
using Telerik.Sitefinity.News.Model;
namespace SitefinityWebApp.Mvc.Models
{
public class AramcoNewsModel: Telerik.Sitefinity.Frontend.News.Mvc.Models.NewsModel
{
protected override IQueryable<IDataItem> GetItemsQuery()
{
var items = base.GetItemsQuery();
var baselineDate = DateTime.UtcNow.AddMinutes(-30);
var filteredItems = items.Cast<NewsItem>()
.Where(n => n.DateCreated > baselineDate);
return filteredItems;
}
}
}
------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;
namespace SitefinityWebApp
{
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
Telerik.Sitefinity.Abstractions.
Bootstrapper.Bootstrapped += Bootstrapper_Bootstrapped; ;
}
private void Bootstrapper_Bootstrapped(object sender, EventArgs e)
{
System.Web.Mvc.RouteCollectionExtensions.MapRoute(
System.Web.Routing.RouteTable.Routes,
"AramcoClassic",
"aramco/{controller}/{action}",
new { controller = "Time", action = "Index" });
Telerik.Sitefinity.Frontend.
FrontendModule.Current.
DependencyResolver.
Rebind<Telerik.Sitefinity.Frontend.News.Mvc.Models.INewsModel>().
To<Mvc.Models.AramcoNewsModel>();
}
protected void Session_Start(object sender, EventArgs e)
{
}
protected void Application_BeginRequest(object sender, EventArgs e)
{
}
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
}
protected void Application_Error(object sender, EventArgs e)
{
}
protected void Session_End(object sender, EventArgs e)
{
}
protected void Application_End(object sender, EventArgs e)
{
}
}
}
-----
|||IMPORTANT API!!!
@Html.StyleSheet(Url.WidgetContent("assets/magnific/magnific-popup.css"), "head", true)
@Html.Script(Url.WidgetContent("assets/magnific/jquery.magnific-popup.min.js"), "bottom", true)
@Html.Script(Url.WidgetContent("Mvc/Scripts/ImageGallery/overlay-gallery.js"), "bottom", true)
-----
FEATHER PROJECT
https://github.com/Sitefinity/feather - This repository contains the core infrastructure related to the Feather project.
https://github.com/Sitefinity/feather-widgets - This repository contains custom MVC widgets which are part of the Feather project.
https://github.com/Sitefinity/feather-packages - This repository contains front-end packages for the Feather project.
https://github.com/Sitefinity/mvc-samples - This repository contains code samples related to the Feather project.
-------
using SitefinityWebApp.Mvc.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Telerik.Sitefinity.Mvc;
namespace SitefinityWebApp.Mvc.Controllers
{
[ControllerToolboxItem(Name = "SpaceX_MVC",
Title ="SpaceX",
SectionName ="Aramco",
CssClass = "sfMvcIcn")]
public class FlightDataController : Controller
{
public ActionResult Index()
{
var model = new FlightDataModel(this.SpacexServiceUrl);
var viewModel = model.GetViewModel();
if (string.IsNullOrWhiteSpace(this.ListTemplateName))
{
this.ListTemplateName = "Index";
}
var fullTemplateName = "List." + this.ListTemplateName;
return View(fullTemplateName, viewModel);
}
public string Message { get; set; }
public string SpacexServiceUrl { get; set; }
public string ListTemplateName { get; set; }
}
}
-------------------
@using Telerik.Sitefinity.Frontend.Mvc.Helpers;
<uib-tabset class="nav-tabs-wrapper">
<uib-tab heading="SpaceX">
<span>Web service url</span>
<input ng-model="properties.SpacexServiceUrl.PropertyValue" type="text" />
<div class="row">
<select id="flightDataTemplateName"
ng-model="properties.ListTemplateName.PropertyValue" class="form-control">
@foreach (var viewName in Html.GetViewNames("FlightData", @"List\.(?<viewName>[\w\s]*)$"))
{
<option value="@viewName">@viewName.SplitCamelCase()</option>
}
</select>
</div>
</uib-tab>
</uib-tabset>
-------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Web;
namespace SitefinityWebApp.Mvc.Models
{
public class FlightDataModel
{
public FlightDataModel(string spacexServiceUrl)
{
this.spacexServiceUrl = spacexServiceUrl;
}
public LaunchViewModel GetViewModel()
{
var getNextLaunchTask = System.Threading.Tasks.Task.Run(() => this.GetLaunchAsync());
getNextLaunchTask.Wait();
return getNextLaunchTask.Result;
}
private async System.Threading.Tasks.Task<LaunchViewModel> GetLaunchAsync()
{
if (string.IsNullOrWhiteSpace(this.spacexServiceUrl))
{
return new LaunchViewModel();
}
else
{
using (var client = new System.Net.Http.HttpClient())
{
var jsonString = await client.GetStringAsync(this.spacexServiceUrl);
return Newtonsoft.Json.JsonConvert.DeserializeObject<LaunchViewModel>(jsonString);
}
}
}
private string spacexServiceUrl;
}
}
-----------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Telerik.Sitefinity.Modules.News;
using Telerik.Sitefinity.Mvc;
namespace SitefinityWebApp.Mvc.Controllers
{
[ControllerToolboxItem(Name ="NewsCounter_MVC", Title ="News Counter", SectionName ="Aramco")]
public class NewsCounterController : Controller
{
public string Index()
{
var nManager = NewsManager.GetManager();
var newsCount = nManager.GetNewsItems()
.Where(n => n.Status == Telerik.Sitefinity.GenericContent.Model.ContentLifecycleStatus.Live)
.Count();
return newsCount.ToString();
}
}
}
----------
public override ContentDetailsViewModel CreateDetailsViewModel(IDataItem item)
{
var nManager = NewsManager.GetManager();
using (ElevatedModeRegion elRegion = new ElevatedModeRegion(nManager))
{
var newsItem = item as NewsItem;
var hCount = newsItem.GetValue("HitsCount");
if (hCount == null)
{
hCount = 0;
}
var hitsCount = Convert.ToInt32(hCount);
hitsCount += 1;
newsItem.SetValue("HitsCount", hitsCount);
nManager.SaveChanges();
}
return base.CreateDetailsViewModel(item);
}
----------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Telerik.Sitefinity.Localization;
namespace SitefinityWebApp.Localization
{
public class FlightDataResource: Telerik.Sitefinity.Localization.Resource
{
[ResourceEntry("NextFlights", Value ="Upcomming flights", Description = "This label is used by the FlightData widget",
LastModified = "2021/02/03")]
public string NextFlights
{
get
{
return this["NextFlights"];
}
}
}
}
---------
[Localization(typeof(FlightDataResource))]
[ControllerToolboxItem(Name = "SpaceX_MVC",
Title ="SpaceX",
SectionName ="Aramco",
CssClass = "sfMvcIcn")]
public class FlightDataController : Controller
{
......
}
---------
@using Telerik.Sitefinity.Frontend.Mvc.Helpers;
@Html.Resource("NextFlights")
---------
Sample: OData
https://www.progress.com/documentation/sitefinity-cms/tutorial-call-odata-services-in-browser-based-javascript-applications
https://github.com/IdentityModel/oidc-client-jsA2
---------
https://www.geeksforgeeks.org/analysis-algorithms-big-o-analysis/
---------
private async System.Threading.Tasks.Task<LaunchViewModel> GetLaunchAsync()
{
if (string.IsNullOrWhiteSpace(this.spacexServiceUrl))
{
var flightConfig = Telerik.Sitefinity.Configuration.Config.Get<FlightConfig>();
this.spacexServiceUrl = flightConfig.SpacexUrl;
}
using (var client = new System.Net.Http.HttpClient())
{
var jsonString = await client.GetStringAsync(this.spacexServiceUrl);
return Newtonsoft.Json.JsonConvert.DeserializeObject<LaunchViewModel>(jsonString);
}
}
---------
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Web;
namespace SitefinityWebApp
{
public class FlightConfig: Telerik.Sitefinity.Configuration.ConfigSection
{
[ConfigurationProperty("SpacexUrl", DefaultValue = "https://api.spacexdata.com/v3/launches")]
public string SpacexUrl
{
get
{
return (String)this["SpacexUrl"];
}
set
{
this["SpacexUrl"] = value;
}
}
}
}
--------
protected void Application_Start(object sender, EventArgs e)
{
Telerik.Sitefinity.Abstractions.
Bootstrapper.Bootstrapped += Bootstrapper_Bootstrapped;
}
private void Bootstrapper_Bootstrapped(object sender, EventArgs e)
{
Telerik.Sitefinity.Configuration.Config.RegisterSection<FlightConfig>();
}
--------
Questions:
1- How to send an item for approval using already configured workflow in the code
A: WorkflowManager.MessageWorkflow(item.Id, typeof(NewsItem), null, "Publish", false, new Dictionary<string, string>());
More info: https://www.progress.com/documentation/sitefinity-cms/for-developers-default-workflow
2- Uploading docuements using API outside Sitefinity? can we have a real example
A: https://knowledgebase.progress.com/articles/Article/Sitefinity-REST-to-upload-an-image
More info: https://www.progress.com/documentation/sitefinity-cms/tutorial-postman-sample-odata-queries?_ga=2.9189367.395345776.1612140318-800962634.1612039386
3- What type of application is Sitefinity good at other than content based applications?
is it good for dashboards for example.
A: Not that it can't be used for dashboards, but the question is what will be the value for the
development team to use it as a dashboard. Usually Sitefinity is for building corporate websites,
web business systems (e.g. we have built such systems for large insurance providers and they use these
systems to run their run their business, e.g. to enable insurance brokers to manage their insurance policies quotas).
It is also good for building portals and as a headless CMS.
4- When it's not recommoneded to use Sitefinity
A: It's not recommended to use it in case you have not through a traning and/or the documentation.
5- What's the best practice in Sitefinity to read items with the same concept of details/list Widget
from a database outside sitefinity. I have used a query string but sometime the widget data get
cached and not updated even when the query string is changed.
A1 (cache integration so it varies by query string): https://www.progress.com/documentation/sitefinity-cms/configure-cache-variation-by-query-string
A2: look at the Details action method => https://github.com/Sitefinity/feather-widgets/blob/master/Telerik.Sitefinity.Frontend.News/MVC/Controllers/NewsController.cs
More information: https://www.progress.com/documentation/sitefinity-cms/implement-master-detail-content-controllers-mvc
Even more information: https://www.progress.com/documentation/sitefinity-cms/82/feather-use-the-relative-routes-api
6- What previelages should we grant content editor?
A: They usually need permissions only to create/update/delete content (i.e. content and pages - pages should be restricted)/
7- is it recommended to customize adding an item from front-end? is there a way to minimize it?
A: Use the backend pages and extend the backend by creating a backend page with custom widgets.
8- Where is the best place to trigger search indexing?
A: The place is http://localhost:8088/Sitefinity/Administration/Search
A2; To index data from external data source you should extend the Sitefinity SearchService class in Sitefinity
so your custom code will trigger indexing when user hirs the "Reindeixng" button from the link above
A3: The best practice is to use external search egnine service. I would recommend going with
http://hawksearch.com as it has the best integration with Sitefinity. It supports multi-source indeixng
out of the box and also many other features (plus it can find results in millions of records for milisenconds).
Contact me in case you want to prepare a demo for you.
9- is there a way to have approval for adding taxonomy?
A: This is not supported OOB. Eventually you can try to build your workflow where to itnegrate the processing of taxonomies.
This will take decent amount of development time and it will be complex as a solution.
A2: Better send feature request to Porgress asap.
10- we face razor generator error when build the application hosted in the developement server
A: I can't recall somehing. It will be best to contact the Progress support via ticket.

A2: https://knowledgebase.progress.com/articles/Article/RazorCodeGen-error
11 - can we do an example of scheduled tasks in sitefinity
A: https://www.progress.com/documentation/sitefinity-cms/for-developers-scheduled-tasks
12- web service to create and update dynamic content via jQuery or other frameworks
A:
https://www.progress.com/documentation/sitefinity-cms/tutorial-call-odata-services-in-browser-based-javascript-applications
https://github.com/IdentityModel/oidc-client-js
13-can we configure approvals requests workflow?
A: We are going to have a session for configuring the approval workflow via the UI.
14- Do we have design tool for website before implemented ? and can we design a full website without coding ?
A: No, there is no design tool that can be used to generated a design for Sitefinity website and to integrate it.
You will neeed to use third-party software to generated designs, then to turn them to HMTL/CSS/JavaScript
and then integrate them by hand in Siteifnity.
1- How to send an item for approval using already configured workflow in the code
2- Uploading docuements using API outside Sitefinity? can we have a real example
3- What type of application is Sitefinity good at other than content based applications? is it good for dashboards for example.
4- When it's not recommoneded to use Sitefinity
5- What's the best practice in Sitefinity to read items with the same concept of details/list Widget from a database outside sitefinity. I have used a query string but sometime the widget data get cached and not updated even when the query string is changed.
6- What previelages should we grant content editor?
7- is it recommended to customize adding an item from front-end? is there a way to minimize it?
8- Where is the best place to trigger search indexing?
9- is there a way to have approval for adding taxonomy?
10- we face razor generator error when build the application hosted in the developement server
11 - can we do an example of scheduled tasks in sitefinity
12- web service to create and update dynamic content via jQuery or other frameworks
13-can we configure approvals requests workflow?
14- Do we have design tool for website before implemented ? and can we design a full website without coding ?