How to - Extending nopCommerce v2.0

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.
12 лет назад
webtech4rindia wrote:
using NopSolutions.NopCommerce.BusinessLogic.Infrastructure;

So, could you just let me which version i will able to find the Above refrecne?

1.X versions
12 лет назад
Hi Guys - I have followed the tutorial at: http://csharpwebdeveloper.com/updating-exisiting-nopcommerce-2-entity
completely and have a fairly basic plugin working.  However, I am left with a few questions:

1. It seems that there is a really nice architecture in place for adding existing features like new payment methods, shipping calculations, etc.  However, if I want to create a completely new feature, but allow the user to configure it in the admin console, what is the best way to do that?  

I was able to "almost" get a new dynamic menu item by implementing the IAdminMenuPlugin, using the code below, however when you go to my Configure view, I lose all the admin layout and just get a blank page with my view.  I tried setting the "layout" property at the beginning of the view, but no luck.  I can provide the full code for the view, if it helps.

Any help would be greatly appreciated.



Here is the implementation of IAdminMenuPlugin
        #region IAdminMenuPlugin Members

        public void BuildMenuItem(Telerik.Web.Mvc.UI.MenuItemBuilder menuItemBuilder)
        {
            string actionName, controllerName;
            RouteValueDictionary routeValues;
            this.GetConfigurationRoute(out actionName, out controllerName, out routeValues);

            menuItemBuilder.Text(_localizationService.GetResource("Plugins.SocialMedia.Admin.SocialMedia"));        
            menuItemBuilder.Url("/Admin/SocialMedia/Configure");
        }

        #endregion



Here is the header I tried to use (which should link back to the main AdminLayout template).
@{
    Layout = "~/Administration/Views/Shared/_AdminLayout.cshtml";
}
12 лет назад
ScottMc101 wrote:
Hi Guys - I have followed the tutorial at: http://csharpwebdeveloper.com/updating-exisiting-nopcommerce-2-entity
completely and have a fairly basic plugin working.  However, I am left with a few questions:

1. It seems that there is a really nice architecture in place for adding existing features like new payment methods, shipping calculations, etc.  However, if I want to create a completely new feature, but allow the user to configure it in the admin console, what is the best way to do that?  

I was able to "almost" get a new dynamic menu item by implementing the IAdminMenuPlugin, using the code below, however when you go to my Configure view, I lose all the admin layout and just get a blank page with my view.  I tried setting the "layout" property at the beginning of the view, but no luck.  I can provide the full code for the view, if it helps.

Any help would be greatly appreciated.



Here is the implementation of IAdminMenuPlugin
        #region IAdminMenuPlugin Members

        public void BuildMenuItem(Telerik.Web.Mvc.UI.MenuItemBuilder menuItemBuilder)
        {
            string actionName, controllerName;
            RouteValueDictionary routeValues;
            this.GetConfigurationRoute(out actionName, out controllerName, out routeValues);

            menuItemBuilder.Text(_localizationService.GetResource("Plugins.SocialMedia.Admin.SocialMedia"));        
            menuItemBuilder.Url("/Admin/SocialMedia/Configure");
        }

        #endregion



Here is the header I tried to use (which should link back to the main AdminLayout template).
@{
    Layout = "~/Administration/Views/Shared/_AdminLayout.cshtml";
}


Hi Scott, thanks for reviewing the article. What you're asking is possible I've written 3 plugins already and only 1 was a payment processor everything else was new functionality. Review this post for getting admin themes to work.

https://www.nopcommerce.com/boards/t/11429/using-admin-theme-from-within-a-plugin-v20.aspx
12 лет назад
Hi Skyler - thanks for the quick reply!
One more question ... the tutorial mentions adding the Localization resources to the installer; I assume so that your "default" strings get installed into the localization tables.  Can you provide an example of how to do this?

Thanks again,
Scott
12 лет назад
ScottMc101 wrote:
Hi Skyler - thanks for the quick reply!
One more question ... the tutorial mentions adding the Localization resources to the installer; I assume so that your "default" strings get installed into the localization tables.  Can you provide an example of how to do this?

Thanks again,
Scott


I'll post a primitive way to install the localization settings, but it is a rough draft and can be improved. It is also an enhancement on my original article about creating a plugin for nopCommerce 2.0. Your pricingOptionProvider should look like this. When a user clicks install from the plugin administration view the resources will be created in the database for every language. There is a lot more work to be done here, but this should get you started.



using System.Collections.Generic;
using System.ComponentModel.Design;
using System.Linq;
using Nop.Core.Domain.Localization;
using Nop.Core.Plugins;
using Nop.Services.Localization;

namespace Nop.Plugin.Pricing.RequestQuote {
    public class PricingOptionProvider : BasePlugin {
        private readonly ILanguageService _languageService;
        private readonly ILocalizationService _localizationService;
        private readonly IResourceService _resourceService;

        public PricingOptionProvider(ILocalizationService localizationService, ILanguageService languageService) {
            _localizationService = localizationService;
            _languageService = languageService;
        }


        public override void Install() {
            // All the default resources
            IDictionary<string, string> resources = new Dictionary<string, string>();
            resources.Add("Nop.Plugin.Pricing.RequestQuote.Fields.FirstName.NotNull", "First name is required.");
            resources.Add("Nop.Plugin.Pricing.RequestQuote.Fields.LastName.NotNull", "Last name is required.");
            resources.Add("Nop.Plugin.Pricing.RequestQuote.Fields.Email.NotNull", "E-mail is required.");
            resources.Add("Nop.Plugin.Pricing.RequestQuote.Fields.PhoneNumber.NotNull", "Phone number is required.");

            resources.Add("Nop.Plugin.Pricing.RequestQuote.Fields.Email", "E-mail");
            resources.Add("Nop.Plugin.Pricing.RequestQuote.Fields.PhoneNumber", "Phone Number");
            resources.Add("Nop.Plugin.Pricing.RequestQuote.Fields.Message", "Message");
            resources.Add("Nop.Plugin.Pricing.RequestQuote.Fields.Company", "Company");
            resources.Add("Nop.Plugin.Pricing.RequestQuote.Fields.FirstName", "First Name");
            resources.Add("Nop.Plugin.Pricing.RequestQuote.Fields.LastName", "Last Name");
            resources.Add("Quotes.PriceQuoteFor", "Request Price Quote");
            resources.Add("Common.Submit", "Submit");

            // For each language install the resources
            IList<Language> allLanguages = _languageService.GetAllLanguages();

            foreach (Language language in allLanguages) {
                InstallResources(language, resources);
            }

            //Base installation functionality
            base.Install();
        }

        private void InstallResources(Language language, IEnumerable<KeyValuePair<string, string>> resources) {
            foreach (var resource in resources.Select(kvp => new LocaleStringResource {
                                                                                          Language = language,
                                                                                          ResourceName = kvp.Key,
                                                                                          ResourceValue = kvp.Value
                                                                                      })) {
                _localizationService.InsertLocaleStringResource(resource);
            }
        }
    }
}

12 лет назад
One critical thing! ...

The localization engine will fail if you try to call the
InsertLocalStringResource() 
method and the resource string already exists.  In order to fix this, I have updated the
InstallResources() 
method, which is called from within the
InsertLocalStringResource() 
method.

Here is the updated code:
 private void InstallResources(Language language, IEnumerable<KeyValuePair<string, string>> resources)
        {
            foreach (var resource in resources.Select(kvp => new LocaleStringResource { Language = language, ResourceName = kvp.Key, ResourceValue = kvp.Value }))
            {
                if (_localizationService.GetLocaleStringResourceByName(resource.ResourceName, language.Id) == null)
                    _localizationService.InsertLocaleStringResource(resource);
            }
        }
12 лет назад
ScottMc101 wrote:
One critical thing! ...

The localization engine will fail if you try to call the
InsertLocalStringResource() 
method and the resource string already exists.  In order to fix this, I have updated the
InstallResources() 
method, which is called from within the
InsertLocalStringResource() 
method.

Here is the updated code:
 private void InstallResources(Language language, IEnumerable<KeyValuePair<string, string>> resources)
        {
            foreach (var resource in resources.Select(kvp => new LocaleStringResource { Language = language, ResourceName = kvp.Key, ResourceValue = kvp.Value }))
            {
                if (_localizationService.GetLocaleStringResourceByName(resource.ResourceName, language.Id) == null)
                    _localizationService.InsertLocaleStringResource(resource);
            }
        }


Yeah, hence my comments about it being a rough draft. I only had enough time to slap an example together.

Also my blog has moved, but the old links will start redirecting by the end of this weekend. With an increase in traffic, website maintenance was becoming a hassle and I didn't have any time to fix bugs in the blog software I was using.

http://blog.csharpwebdeveloper.com/
12 лет назад
I've followed the tutorial in   http://blog.csharpwebdeveloper.com/2011/09/10/writing-a-plugin-for-nopcommerce-2-x/

However, when I try to use it in
  _ProductVariantPrice.cshtml
as per
   <a title="Request Quote" href="@Url.RouteUrl("Nop.Plugin.Pricing.RequestQuote")">Request Quote!</a>

Url.RouteUrl returns null.

I put a breakpoint in RouteProvider.cs, and I see the route does get set.

Just as a test, I changed In RouteProvider.cs
from
routes.MapRoute("Nop.Plugin.Pricing.RequestQuote",  "RequestQuote/{productVariantId}",    
to
routes.MapRoute("Nop.Plugin.Pricing.RequestQuote",  "RequestQuote/1",    

Then I see this error

The parameters dictionary contains a null entry for parameter 'productVariantId' of non-nullable type 'System.Int32'
for method 'System.Web.Mvc.ActionResult Index(Int32)'
in 'Nop.Plugin.Pricing.RequestQuote.Controllers.RequestQuoteController'.
An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
Parameter name: parameters
12 лет назад
New York wrote:
I've followed the tutorial in   http://blog.csharpwebdeveloper.com/2011/09/10/writing-a-plugin-for-nopcommerce-2-x/

However, when I try to use it in
  _ProductVariantPrice.cshtml
as per
   <a title="Request Quote" href="@Url.RouteUrl("Nop.Plugin.Pricing.RequestQuote")">Request Quote!</a>

Url.RouteUrl returns null.

I put a breakpoint in RouteProvider.cs, and I see the route does get set.

Just as a test, I changed In RouteProvider.cs
from
routes.MapRoute("Nop.Plugin.Pricing.RequestQuote",  "RequestQuote/{productVariantId}",    
to
routes.MapRoute("Nop.Plugin.Pricing.RequestQuote",  "RequestQuote/1",    

Then I see this error

The parameters dictionary contains a null entry for parameter 'productVariantId' of non-nullable type 'System.Int32'
for method 'System.Web.Mvc.ActionResult Index(Int32)'
in 'Nop.Plugin.Pricing.RequestQuote.Controllers.RequestQuoteController'.
An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
Parameter name: parameters


I copied and pasted the wrong thing into that article. I'll fix it now.

The correct code would be



   <a title="Request Quote" href="@Url.RouteUrl("Nop.Plugin.Pricing.RequestQuote", new { productVariantId = Model.ProductVariantId})">Request Quote!</a>
12 лет назад
Thanks, that worked.  
I was just diff'ing your published extension against what I had got from your atricle, and noticed you made similar correction to index.cshtml
I had some other problems with what I cut/paste form your article - there are missing characters, and extra <pre> and stuff like that. (I wish I had noticed the published ext a few hours ago :)

Also, in the article, you should mention to create a new Class Library project.  I first created an empty MVC3 project, and that would cause two instances of the ASP.NET server to run.
You may also want to mention adding this Reference
  Browse - …src\packages\FluentValidation.2.0.0.0\lib\NET35\FluentValidation.dll

Thanks again.
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.