A oddity we tripped across when upgrading sites from Plone 3 to Plone 4:
We define a number of custom portlets. One of these is a "Jobs" portlet which is a lightly customised News Portlet. This was subclassed from the News portlet, as suggested by:
http://plone.org/documentation/manual/developer-manual/portlets/appendix-practicals/subclassing-new-portlets.
That is:
<plone:portlet
name="falcon.JobsPortlet"
interface=".portlets.IFalconJobsPortlet"
...
renderer=".portlets.FalconJobsRenderer"
/>
where IFalconJobsPortlet subclasses from INewsPortlet:
from plone.app.portlets.portlets.news import INewsPortlet
class IFalconJobsPortlet(INewsPortlet):
"""Interface for Jobs portlet uses the same schema as News Portlet"""
We also (separately) want to replace the render class on the standard INewsPortlet, in
order to provide a custom template:
<plone:portletRenderer
portlet="plone.app.portlets.portlets.news.INewsPortlet"
class=".portlets.FalconNewsRenderer"
layer=".interfaces.IThemeSpecific"
/>
This works fine in Plone 3. This might just have been blind luck, or it
might be case that <plone:portletRenderer> used to run before
<plone:portlet>, and now run afterwards.
In Plone 4, falcon.JobsPortlet is set up correctly, but then <plone:portletRenderer>
kicks in and replaces the renderer clause, so that
".portlets.FalconJobsRenderer" (correct) is replaced with
".portlets.FalconNewsRenderer" (incorrect)
A solution/workaround in this case was simple: I stopped subclassing from
INewsPortlet, and just copied the schema across by hand from the original superclass:
class IFalconJobsPortlet(IPortletDataProvider):
"""Interface for Jobs portlet uses the same schema as News Portlet"""
count = ...
state = ...
My question, for future reference:
Is there a way to safely combine <plone:portlet> and
<plone:portletRenderer> when subclassed portlets are in play?
If you're not using layer="..." in your <plone:portlet name="falcon.JobsPortlet"...> registration, then this is probably the root. The ZCA, which this ZCML uses to register adapters, gives one lookup precedence over another based on interface specificity. So I'm guessing the since you give a layer in your <plone:portletRenderer> but not in your <plone:portlet> then the renderer in <plone:portletRenderer> matches the portlet interface of both and the layer is more specific and so it wins.
Since only <plone:portletRenderer> supports the layer specification, I would just add a <plone:portletRenderer> registration for the FalconJobsRenderer that is registered for the same layer and that will assure correct precedence. That way you can revert your workaround and subclass INewsPortlet. It is much more appropriate to subclass INewsPortlet.
Related
So there are several parts to this question.
The 2 example endpoints (in simplest form):
user/{id}/profile
movie/{id}/info
I expect to create 2 controllers (UserController & MovieController).
How do I implement a view area before controller name?
Both of these are what I would consider a view. Therefore I would like to append a "view" in the url before the controller, as both controllers ONLY supply views. I later expect to also have a user controller in a different place that does NOT return views.
However, ALL my endpoints should start with /api/.
i.e. I want this:
api/view/user/{id}/profile
api/view/movie/{id}/info
But how do I register an area (/view/) while using "custom routing" (i.e.: httpConfiguration.MapHttpAttributeRoutes())? Any examples of this I couldn't find?
Where should I put versioning?
The client is an app, and will require versioning, so that we can make changes to the methods without breaking old versions of the app.
We are unsure where it would be best to place the versioning, and how the placement affects the development of new versions (if it does so at all?).
Possibilities:
1. api/v1/view/user/{id}/profile
2. api/view/v1/user/{id}/profile
3. api/view/user/{id}/profile/v1
version the whole API. This would upgrade the whole API to a new version, even if we only required a single method/endpoint to make an app-breaking change.
Are there any advantages to this that I am not seeing?
version the area. Same as above, just slightly fewer controllers affected.
version the method. Seems like the simplest, as only the single changed method is affected. But the url is very ugly.
Does anyone have an example of versioning in an MVC or Web Api structure that doesn't upgrade the whole API, but still keeps a somewhat nice structure in their URLs?
I ended up using https://github.com/Microsoft/aspnet-api-versioning as suggested by NightOwl888.
1.
Made my 2 controllers extend another controller with a const field that defined the routeprefix that they should share:
protected const string RoutePrefix = "api/view/v{version:apiVersion}";
...
[RoutePrefix(RoutePrefix + "/user")]
2.
The placement of the /v1/ doesn't matter with this Library. And allowed for either updating the controller or individuals methods, as seen fit per case basis.
I wanted to create a blank Component in SDL Tridion 2011 using the Core Service. The only information I have at the start of the process is the Schema URI. The Schema may contain any kind of field (text, rtf, number date, embedded etc), some of which may be mandatory.
I understand that for the mandatory fields, I will need to save some dummy value in them, and this is acceptable as they will be changed manually later.
How can i achieve this?
First - you make sure all fields are set to optional in the schema, otherwise this will never work.
Second - You save.
When an optional field has no value, it will have no XML representation. If you have a schema that defines a component like this:
Field1
Field2
Field3
When all fields are optional and you save a value in Field 2, Tridion will store the following:
<Content xmlns="yourNamespace"><Field2>SomeValue</Field2></Content>
If one of your fields is not mandatory, then you'll have to provide a value. If you're using the CoreService then you can use ReadSchemaFields class to get the fields and some information about them - what type, mandatory/optional, etc.
Looking at your question/requirement to understand what you're exactly looking for, so we can answer the best possible and relevant.
Are you asking for "How can you write a generic code for component creation using core service?" instead of creating a component with a specific schema knowing all the fields upfront.
If that is what you are looking for, here is what you need to do:
You need to read the schema fields with CoreService (since you know the schema URI)
Now you know what type of fields (embedded/component link etc) you need to create content for
use the links pointed by "Puf" in his answer.
Please note that, if the field is marked as required in Tridion Schema you must have to fill a value and it has to match the field type defined in schema.
Reading schema fields via Core Service sample code can be found here
Updating a Component's field through the Core Service is already answered here: Updating Components using the Core Service in SDL Tridion 2011
That post points to a helper class you can find here: Updating Components using the Core Service in SDL Tridion 2011
If those don't help you in creating a Component, I suggest you post your code instead of asking us to write it for you.
We ask about use case, because code to fill in specific fields for a specific schema only works in one environment. Code that can automatically determine fields is re-usable.
If the use case is for an Tridion setup that has Inline Editing (Experience Manager or SiteEdit), then the correct approach is content/component types. These define a reference component with "junk defaults," instructions to the author, and even save location context.
If the use case is to allow authors the ability to create dummy components, this is out-of-the box with:
CTRL+C
CTRL+V
One-time setup required to create a "reference component." Of course we can mimic this behavior (in case "Copy of Untitled" isn't an appropriate name) by copying items with the core service.
In that case, I'll also do a copy--see a general solution for creating Tridion items using the Core Service.
Fields that require a default can have an actual default in the schema.
"Junk values" don't help authors much, always consider good defaults such as an appropriate selection or instructions in the case of fields (maybe). A 10 second change costs development practically nothing, but impacts all future components and the authors that create them.
The Nlog has some ASP.NET logging features (see the list of layout renderers), for example
${aspnet-request}
For log form item, I need to know name of item.
${aspnet-request:form=myVariable}
But how to log all from items, which hames in unknown?
For example
${aspnet-request:form}
I'd write my own LayoutRenderer, myself (in fact, just did something nearly identical, recently) - one of the best parts about NLog is how extensible the framework is. Depending on how you're doing configuration will determine how you reference/load your custom layoutrenderer, but the sky is really the limit in terms of what you can do.
Off the top of my head, you could take one of two approaches with a custom renderer: wrap/extend the existing asp request renderer and just proxy all calls, or get a hook to the request object the same way the nlog one does (which is tricky; it calls out to grab the COM instance, if memory serves).
The approach I took was to embed the NameValueCollection in the outgoing LogEventInfo object itself (in the properties dictionary), then use a custom layout renderer to extract that collection and render it.
It seems that toolset.xml goes only half way. Ideally it should be able to do away with the ToolInit call in initialize() in __init__.py. But I could not get the tool icon to show in the ZMI without the ToolInit call.
The ToolInit call in the initialize function registers the tool class as something that can be added to OFS based folders in the database - primarily it register a factory for creating instances of the class. This is basically the same that ContentInit does for normal content classes.
Once the class is registered and its meta_type is known, instances of the class can be added to OFS based Folders. GenericSetup steps are responsible for managing persistent content and can be used to add tool instances to the database.
If we wanted to avoid the code in the initialize function, we would need to create some custom ZCML directives instead and use these in a configure.zcml to register the type and its factory. Dexterity has gone this route, but its not available for Archetypes based content types or general classes like tools.
The goal of toolset.xml is to instantiate tools into the database. It can also be used to remove tools; this is very useful in upgrade steps for example.
Example toolset.xml:
<?xml version="1.0"?>
<tool-setup>
<required tool_id="portal_foo" class="dotted.path.to.FooTool" />
<forbidden tool_id="portal_spam" />
</tool-setup>
This example toolset.xml would instantiate the FooTool class as portal_foo in it's context, and remove any object with id portal_spam if present.
Note that you can use a toolset.xml in any GenericSetup profile, not just in the package that defines the tool in the first place, for example, in general policy packages for a site you develop.
I was going through Unity 2.0 to check if it has an effective use in our new application. My application is a Windows Forms application and uses a traditional bar menu (at the top), currently.
My UIs (Windows Forms) more or less support Dependency Injection pattern since they all work with a class (Presentation Model Class) supplied to them via the constructor. The form then binds to the properties of the supplied P Model class and calls methods on the P Model class to perform its duties. Pretty simple and straightforward.
How P Model reacts to the UI actions and responds to them by co-ordinating with the Domain Class (Business Logic/Model) is irrelevant here and thus not mentioned.
The object creation sequence to show up one UI from menu then goes like this -
Create Business Model instance
Create Presentation Model instance with Business Model instance passed to P Model constructor.
Create UI instance with Presentation Model instance passed to UI constructor.
My present solution:
To show an UI in the method above from my menu I would have to refer all assemblies (Business, PModel, UI) from my Menu class. Considering I have split the modules into a number of physical assemblies, that would be a dificult task to add references to about 60 different assemblies. Also the approach is not very scalable since I would certainly need to release more modules and with this approach I would have to change the source code every time I release a new module.
So primarily to avoid the reference of so many assemblies from my Menu class (assembly) I did as below -
Stored all the dependency described above in a database table (SQL Server), e.g.
ModuleShortCode | BModelAssembly | BModelFullTypeName | PModelAssembly | PModelFullTypeName | UIAssembly | UIFullTypeName
Now used a static class named "Launcher" with a method "Launch" as below -
Launcher.Launch("Discount");
Launcher.Launch("Customers");
The Launcher internally uses data from the dependency table and uses Activator.CreateInstance() to create each of the objects and uses the instance as constructor parameter to the next object being created, till the UI is built. The UI is then shown as a modal dialog. The code inside Launcher is somewhat like -
Form frm = ResolveForm("Discount");
frm.ShowDialog();`
The ResolveForm does the trick of building the chain of objects.
Can Unity help me here?
Now when I did that I did not have enough information on Unity and now that I have studied Unity I think I have been doing more or less the same thing. So I tried to replace my code with Unity.
However, as soon as I started I hit a block. If I try to resolve UI forms in my Menu as
Form customers = myUnityContainer.Resolve<Customers>();
or
Form customers = myUnityContainer.Resolve(typeof(Customers));
Then either way, I need to refer to my UI assembly from my Menu assembly since the target Type "Customers" need to be known for Unity to resolve it. So I am back to same place since I would have to refer all UI assemblies from the Menu assembly. I understand that with Unity I would have to refer fewer assemblies (only UI assemblies) but those references are needed which defeats my objectives below -
Create the chain of objects dynamically without any assembly reference from Menu assembly. This is to avoid Menu source code changing every time I release a new module. My Menu also is built dynamically from a table.
Be able to supply new modules just by supplying the new assemblies and inserting the new Dependency row in the table by a database patch.
At this stage, I have a feeling that I have to do it the way I was doing, i.e. Activator.CreateInstance() to fulfil all my objectives. I need to verify whether the community thinks the same way as me or have a better suggestion to solve the problem.
The post is really long and I sincerely thank you if you come til this point. Waiting for your valuable suggestions.
Rajarshi
As I can see from this code
Form customers = myUnityContainer.Resolve<Customers>();
all your code need to know about the customer - is that it's a Form class. So if you use xml configuration for unity you can do the following:
<type type="Form" mapTo="Customer" name="Customer">
</type>
And then you'll be able to resolve it like this:
Form customers = myUnityContainer.Resolve<Form>("Customer");
and there is no need to refference your UI assembly. Offcourse it should be presented in the bin directory or GAC. In this case if you'll develop new Assembly - all you need is to change config and put in in bin or gac.
If you want to make unity configuration from db then you'll have to add referrence to your ui, becouse you'll have to call Register("Customer").