I'm new to NopCommerce, I've got an issue I want to be able to have an indicator to display on the ProductTemplate.Simple.cshtml to display a product is new. So I'm trying to figure out the best approach, or if there currently is a service on NopCommerce that already provides the solution.
I'm currently stuck on finding a solution for this issue? Does anyone know where to start looking? Or has come across the same issue?
From description of the question, I assume that you want to indicate product is new on detail page, for that you've to modify the code.
Add one new field in Nop.Web > Models > Catalog ProductDetailsModel
public partial class ProductDetailsModel : BaseNopEntityModel
{
...
public bool IsNew { get; set; }
}
Assign value of it from Nop.Web > Factories > ProductModelFactory
public virtual ProductDetailsModel PrepareProductDetailsModel(Product product, ShoppingCartItem updatecartitem = null, bool isAssociatedProduct = false)
{
var model = new ProductDetailsModel {
...
...
IsNew = product.MarkAsNew
};
}
Add condition to display it on view page:
<div class="product-name">
<h1 itemprop="name">
#Model.Name
#if (Model.IsNew)
{
<b>(This is a new product)</b>
//TODO: add your code here
}
</h1>
</div>
To check if it is working or not, mark product as new from admin end (I have used Apple iCam here)
Go and refresh the detail page:
Hope this helps!
You can try to find ribbon plugin over the marketplace of the nopcommerce or you can develop it by yourself. Otherwise You can show a new sticker at presentation==>nop.web==>themes==>your theme==>Shared==>_ProductBox.cshtml depending on the "MarkAsNew" property of the "ProductOverviewModel"
Related
I've got a ASP.net MVC site that authenticates against Azure Active Directory. I have users in Groups in AD and need to be able to show different navbar items and pages depending on what group the user is in.
Currently I have a shared layout .cshtml for everyone for the navbar and am including or excluding navbar items using code like below. I am passing in the logged in user and the group they should be in to a helper and then checking to see if that helper is in the group:
#if (Helpers.AuthenticationHelper.HasPermissions(User, "IT") == true)
{
<span>User has access to IT</span>
}
else
{
<span>User has no access to IT</span>
}
#if (Helpers.AuthenticationHelper.HasPermissions(User, "Accounting") == true)
{
<span>User has access to Accounting</span>
}
else
{
<span>User has no access to Accounting</span>
}
And then for actual web pages I'm essentially doing that same thing but in the controller and redirecting them to a different view if they do not have permissions.
Is this a secure way of doing this or are there security flaws? Could someone smart enough find a way around this? I need to make sure under no circumstance can the users in one group see stuff intended for another group. Thanks. Appreciate any advice.
EDIT: Adding Controller Code on request.
public ActionResult Dashboard()
{
using (Data.WebAppsCoreContext _context = new Data.WebAppsCoreContext())
{
var securityRepo = new SecurityRepository(_context);
var metricBool = securityRepo.Metrics(AuthenticationHelper.GetGroups(User), "Metrics");
if (metricBool == true)
{
//return normal view
return View();
}
else
{
//return alternate view
return View("/Something/Something/");
}
}
}
Firstly, I tried all the questions & answers related to this topic. Additionally and I tried related questions and try to solve it but no success. So please read my question thoroughly.
i refer below Link this topic but not getting solution
override-core-files-using-module-prestashop
override-controller-in-prestashop-1-6
prestashop-translating-overrided-controller
prestashop-1-6-controller-override
i want to this override prestashopbundle controller using my custom module.
my Custom module structure
- mymodule
- controllers
- admin
- prestashop
- override
- views
i want to this controller override
prestashop/src/prestashopbundle/controller/Admin/sell/Customer/CustomerController.php
mymodule path
module/mymodule/
Thanks
After Long Time research in Prestashop after then i got best Solution
Prestashop(1.7.*) say :
As Controllers are not available for override and can be regarded as
internal classes, we don’t consider moving a Controller in another
namespace as a backward-compatibility break.
Controller and Routing
After i created a custom Hook register my custom Module. inside custom hook implement functionality and DONE it :)
public function hookActionViewCustomers($params)
{
$creddit = Configuration::get('Credit_Checkbox_1');
$customerid =$params['request']->attributes->get('customerId');
$Status_HTMl =$this->Get_Status_HTML($customerid);
if(!$creddit)
{
// Checkbox Checked
$ButtonDisable =" <button type=\"submit\" disabled='disabled' title='Not Allow'> Check Status </button>";
}
else{
// Checkbox unChecked
$ButtonDisable =" <button type=\"submit\" title='Click Get Status'> Check Status </button>";
}
return $Status_HTMl.$ButtonDisable;
}
I'm trying to get a breadcrumb navigation to show up just below my main navigation in a NopCommerce theme, so the code to show it needs to be in Views/Shared/header.cshtml, but having it there causes pages that aren't categories to break. Is there any way to do "if is category page, execute code" in nopcommerce? I can't find any good source of documentation for this platform...
Here's my breadcrumb code if it matters:
#if (Model.DisplayCategoryBreadcrumb) {
<nav class="plain">
<ul>
<li>#T("Categories.Breadcrumb.Top")</li>
#for (int i = 0; i < Model.CategoryBreadcrumb.Count; i++)
{
var catBr = Model.CategoryBreadcrumb[i];
<li>#catBr.Name</li>
}
</ul>
</nav>
}
Thanks!
I can't find any good source of documentation for this platform...
nopCommerce runs on MVC, so anything that works in MVC works for nopCommerce too.
Which brings is to MVC basics. You can try go get info about current request (such as current Controller) by using the ViewContext or RequestContext whichever is relevant. For example, you can try to get the current controller by using:
#{
var controller = ViewContext.Controller;
}
:)
Experience Manager (XPM) (user interface update for SDL Tridion 2011 SP1) lets administrators create Page Types, which have component presentations just like pages, but also add rules on how to create and allow additional content types.
For a given page type, I'd like to simplify an author's options by limiting content type choices.
I understand we can:
Limit the content types, so that for a given page type authors can only create certain predefined content types
In the Dashboard, completely restrict the above to just predefined content types, by un-selecting Content Types Already Used on the Page
Use regions which specify combinations of schemas and templates along with quantity restrictions. Authors can only add (drag-and-drop) certain types and quantity of components to these region. For example, we can output the following on Staging to create a region:
<div>
<!-- Start Region: {
title: "Promos",
allowedComponentTypes: [
{
schema: "tcm:2-42-8",
template: "tcm:2-43-32"
},
],
minOccurs: 1,
maxOccurs: 3
} -->
<!-- place the matching CPs here with template logic (e.g. TemplateBeginRepeat/ TemplateBeginIf with DWT) -->
</div>
Authors may still see components they might want to insert (image below), but won’t be able to add them if regions control what’s allowed
However, folder permissions can reduce what components authors can see/use in the Insert Content library
Did I get them all? Any other ways in XPM functionality or possible extensions to consider on how to limit the allowed content for a given Page Type?
Alvin, you pretty much provided most of the options in your question. Another option, if a custom error message is desired or even finer level of control is to use the Event System. Subscribe to a Page's save event Initiated phase and write some validation code that throws an exception if an unwanted component presentation is on the page.
Since Page Types are really a combination of a page template, any metadata on the page and the types of component presentations on the page, we would need to check that we are dealing with the wanted page type and if encounter an CP that doesn't match what we desire, we can simply throw the exception. Here is some quick code:
[TcmExtension("Page Save Events")]
public class PageSaveEvents : TcmExtension
{
public PageSaveEvents()
{
EventSystem.Subscribe<Page, SaveEventArgs>(ValidateAllowedContentTypes, EventPhases.Initiated);
}
public void ValidateAllowedContentTypes(Page p, SaveEventArgs args, EventPhases phases)
{
if (p.PageTemplate.Title != "My allowed page template" && p.MetadataSchema.Title != "My allowed page metadata schema")
{
if (!ValidateAllowedContentTypes(p))
{
throw new Exception("Content Type not allowed on a page of this type.");
}
}
}
private bool ValidateAllowedContentTypes(Page p)
{
string ALLOWED_SCHEMAS = "My Allowed Schema A; My Allowed Schema B; My Allowed Schema C; etc"; //to-do put these in a parameter schema on the page template
string ALLOWED_COMPONENT_TEMPLATES = "My Allowed Template 1; My Allowed Template 2; My Allowed Template 3; etc"; //to-do put these in a parameter schema on the page template
bool ok = true;
foreach (ComponentPresentation cp in p.ComponentPresentations)
{
if (!(ALLOWED_SCHEMAS.Contains(cp.Component.Schema.Title) && ALLOWED_COMPONENT_TEMPLATES.Contains(cp.ComponentTemplate.Title)))
{
ok = false;
break;
}
}
return ok;
}
}
I built a custom module that manages appointments for a service-based company. All of the current functionality is contained in the admin section. I have not used a single ContentItem or ContentPart. All the models are just plain records.
I'm looking to create a widget to expose the ability to sign up for an appointment from the front end. I have a partial view and a controller that handles the display and form submit, but I'm not sure how to tie that into a widget that can be placed in one of the content zones of the front-end.
I've spent quite a bit of time researching this, and can't find a good path to follow. (I've tried a few and got sub-optimal results)
Any suggestions?
The best answer for me was to create a widget Type definition in the migration.cs file of the module:
ContentDefinitionManager.AlterTypeDefinition("CreateAppointmentWidget",
cfg => cfg
.WithPart("WidgetPart")
.WithPart("CommonPart")
.WithSetting("Stereotype", "Widget"));
Then create a handler for that widget at /MyModule/Handlers/CreateAppointmentWidgetHandler.cs:
public class CreateAppointmentWidgetHandler : ContentHandler
{
private readonly IRepository<FieldTechRecord> _repository;
public CreateAppointmentWidgetHandler(IRepository<FieldTechRecord> repository)
{
_repository = repository;
}
protected override void BuildDisplayShape(BuildDisplayContext context)
{
base.BuildDisplayShape(context);
if (context.ContentItem.ContentType == "CreateAppointmentWidget")
{
CreateAppointmentViewModel model = new CreateAppointmentViewModel(_repository.Fetch(x => x.IsActive));
context.Shape.AppointmentModel = model;
}
}
}
Then create a matching widget template at /MyModule/Views/Widget-CreateAppointmentWidget.cshtml that inserts the Partial View:
#Html.Partial("CreateAppointment", (MyModule.Models.Views.CreateAppointmentViewModel)Model.AppointmentModel)
The above code grabs the partial view /MyModule/Views/CreateAppointment.cshtml.
Thanks to Giscard's suggestion, I was able to correct the links rendered from CreateAppointment.cshtml by using #Url.RouteUrl() and defining named routes to point where I needed the action and ajax requests to go.
The nice thing about this solution is that it provided a way to create the widget without having to rework my models to use Orchards ContentPart functionality.
Something is not connecting in my head, because I have been able to create a theme with zones, and then dispatch a shape from my module into that zone without much more than doing #Display.Shape(). So I am curious if it's absolutely necessary to use a handler to override the BuildDisplayShape.
Again, this is in the scenario where you have models as plain records (not using ContentItem or ContentPart - and even if not using them, you've shown an example of creating one through migrations).
Something like this - Controller:
public ShapeResult MyShape()
{
var shape = _orchardServices.New.MyPath1_MyShape();
return new ShapeResult(this, shape);
}
Then create a MyShape.cshtml shape with whatever code I have (no need for example).
NOTE: I use a custom IShapeTemplateHarvester file which adds paths where I can store my shapes (instead of using "Views", "Views/Items", "Views/Parts", "Views/Fields", which is the stock in Orchard). It goes something like this:
NB: I hate that code doesn't automatically wrap in SO.
[OrchardSuppressDependency("Orchard.DisplayManagement
.Descriptors.ShapeTemplateStrategy.BasicShapeTemplateHarvester")]
public class MyShapeTemplateHarvester : BasicShapeTemplateHarvester,
IShapeTemplateHarvester
{
public new IEnumerable<string> SubPaths()
{
var paths = base.SubPaths().ToList();
paths.Add("Views/MyPath1");
paths.Add("Views/MyPath2");
return paths;
}
}
Say I have Index.cshtml in my Theme. I have two choices (I use both and use the Theme as the default presentation).
Index.cshtml in Theme folder:
#*Default Content*#
Index.cshtml in Module folder:
#*Special Content overriding Theme's Index.cshtml*#
Display.MyPath1_MyShape()
Even better for me is that I can do this in the Index.cshtml in Theme folder:
#*Whatever content*#
Display.MyPath1_MySecondShape()
There is no ~/MyPath1/MySecondShape.cshtml in the Theme, but there is one in the Module, which the Theme displays! This is great because I can have a special Theme and have multiple modules (that are placed on separate sites) go back and forth with the theme (think Dashboard for different services in the same profession on different sites).
NOTE: The above may only be possible with IThemeSelector implementation such as:
public class MyThemeSelector : IThemeSelector
{
public ThemeSelectorResult GetTheme(RequestContext context)
{
if (MyFilter.IsApplied(context))
{
return new ThemeSelectorResult { Priority = 200,
ThemeName = "MyDashboard" };
}
return null;
}
}
Just my two bits.