Listenerconfigurations in the observation module of magnolia - best practices question - magnolia

I would like to trigger a custom command that extends BaseRepositoryCommand when someone adds, removes or changes a node or property for mgnl:page, mgnl:area and mgnl:component node types.
I was thinking of using the magnolia observation module for this. Do I have to create separate listenerConfigurations for each node type and event type? In my case it would be 6 event-types for 3 node-types or 18 different
listenerConfigurations. Does that have implications on performance?

Please have a look at: info.magnolia.cms.util.WorkspaceObservingManager
There you can use the method #registerChangeListener which you can specify the workspace you want to observe as well as the list of node types you wish.
Performance-wise, it should be smooth since it uses directly JCR observation mechanism under its hood.

Related

How do you manage adding new attributes on existing objects when using firebase?

I have an app using React + Redux and coupled with Firebase for the backend.
Often times, I will want to add some new attributes to existing objects.
When doing so, existing objects won't get the attribute until they're modified with the new version of the app that handles those new attributes.
For example, let's say I have a /categories/ node, in there I've got objects such as this :
{
name: "Medical"
}
Now let's say I want to add an icon field with a default of "
Is it possible to update all categories at once so that field always exists with the default value?
Or do you handle this in the client code?
Right now I'm always testing the values to see if they're here or not, but it doesn't seem like a very good way to go about it. I'd like to have one place to define defaults.
It seems like having classes for each object type would be interesting but I'm not sure how to go about this in Redux.
Do you just use the reducer to turn all categories into class instances when you fetch them for example? I'm worried this would be heavy performance wise.
Any write operation to the Firebase Database requires that you know the exact path to the node that you're writing.
There is no built-in operation to bulk update nodes with a path that is only partially known.
You can either keep your client-side code robust enough to handle the missing properties, or you can indeed run a migration script to add the new property to each relevant node. But since that script will have to know the exact path of each node to write, it will likely first have to read/query the database to determine those paths. Depending on the number of items to update, it could possibly use multi-location updates after that to update multiple nodes in one call. E.g.
firebase.database().ref("categories").update({
"idOfMedicalCategory/icon": "newIconForMedical",
"idOfCommercialCategory/icon": "newIconForCommercial"
"idOfTechCategory/icon": "newIconForTech"
})

Creating blank dummy Components which contain mandatory Fields with the SDL Tridion 2011 Core Service

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.

How to override record table naming to access existing data in Orchard CMS

I need to access data from pre-existing tables. I've started working my way through creating a module to display the data etc. However, Orchard is prefixing the table commands with the 'Table_Prefix' and 'Module Name'.
Is there any way I can specify what table to bind the model, so that I can use the existing IRepository
I'm trying to steer clear of modifying the core code, or implement my own IRepository ( which I've got a feeling is what I'm going to have to do.)
Thanks in advance.
You can create custom table naming convention (so that it would fit your current naming) by altering the core code, in three ways:
Record name mapping is created in BuildRecord method of
CompositionStrategy class
(Orchard.Framework/Environment/ShellBuilders/CompositionStrategy), so you can simply modify the code here.
By altering the Apply method of Orchard.Data.Conventions.RecordTableNameConvention class. This is where the record table name mappings (built in point 1.) get pushed to NHibernate.
Create your own implementation of FluentNHibernate.Conventions.IClassConvention (similar to RecordTableNameConvention mentioned above and replace the default one used by AutoMap in Orchard.Data.Providers.AbstractDataServicesProvider's CreatePersistenceModel(...) method with it.
You could also create your own IDataServicesProvider implementation, but that would surely be an overkill if you only need to change the table naming convention.
I was modifying CompositionStrategy and discovered that you have to modify the following
1. SetupService.cs (Modules\Orchard.Setup\Services):
Tables hardcoded in the Setup method are
"Orchard_Framework_DataMigrationRecord" and
"Settings_ShellDescriptorRecord"
2. InfosetController.cs (Modules\Upgrade\Controllers):
Multiple tables were hardcoded in this class which need to be updated.
3. DataMigrationManager.cs (Data\Migration):
Replace the SchemaBuilder parameters to the contructor.

Add extra field in story content type using hook without CCK

I want to add extra field in story content type using hook, I don't want to use CCK, because am trying something different.
Please tell some suggestion with hook method.
If you do not use CCK, you will have to create your database table and code to add the form field, validate the form field, capture the data and save it in your field. I know cck can be a monster, but it does all this for you. I'd be happy to give you more info on all of this, but it is quite lengthy
There are lots of reasons that you may want to do this without CCK or Fields, and the best example is found at the node_example module in the examples project which can be found at: http://drupalcode.org/project/examples.git/tree/refs/heads/6.x-1.x:/node_example. You can also view the documentation on api.drupal.org.
The short version is that you're going to have to define your own node type using hook_node_info() and then define all the hooks for _load(), _insert(), _update(), _delete(), _access(), _validate(), and _view() in addition to defining your schema in your hook_schema and managing your tables on your own.
Sadly there is no good example for Drupal 7 as the node_example module for 7 was converted to use fields instead of the hooks listed above, which are still fully documented on api.drupal.org (they do now typically act on an array of nodes instead of a single node, but are otherwise identical).

Create multiple CCK nodes with single custom form in Drupal

I need a form which will allow creation of several related nodes at the same time. All of the nodes involve CCK fields.
I would like to use as much of CCK's built-in validation, submission, input widget, and security functionality as possible/practical.
What is the best way to accomplish this in Drupal 6? Are there 'best practices' or docs anywhere?
Here are 3 possibilities I can see. I would love feedback on whether any of these would work, or if there are even better options.
1.
start with the standard node creation form for content type foo.
modify the form by adding fields for content type bar, using hook form_alter [can cck widgets for content type bar be inserted directly?]
use a custom submit handler to create node of type bar when the form is submitted
[can the standard cck handler be called? or do i need to 'manually' construct the node object, do my own validation, and use node_save?]
2.
create a new, custom form that concatenates the 'normal' node creation forms for the relevant content types.
then use hook form_alter to modify the forms as necessary.
allow standard cck submit handlers to do the work of creating the nodes.
3.
create a custom form from scratch
create the nodes in my own submit handlers, using node prepare, node save, etc.
If found documentation on re-using the standard node creation form, but creating multiple nodes at the same time is not mentioned.
Using hook nodeapi and hook form_alter is documented in a post on advomatic's site, but the particular method descrube seems to require polluting one of the content types with 'dummy' fields.
Thank you very much for your help!
The advomatic guys posted a nice solution to this.
http://www.advomatic.com/blogs/jonathan-delaigle/multiple-nodes-single-node-submission
why not just use hook_nodeapi to handle the node creation for certain content types.
just set up a test condition to see if $node->type = 'foo', and then run a function to create two nodes or however many, using the values from the predefined fields. you can even set hook_nodeapi to only run when the $op is almost ready to insert the node into the database, thus ensuring the object has been run through appropriate validation before being passed on to the new nodes that need to be created.
http://api.drupal.org/api/function/hook_nodeapi/6 this page has a list of all available operations for the $op variable and what they do.
I hope that helps
If the 2nd type bar needs only one or two additional inputs (fields) from the user, I would go with your approach one.
But given your clarification it seems that foo and bar are sufficiently different and complex, so your approach two seems more reasonable.
Concatenate both forms into one and hide the bar fields that you want to populate from the foo fields (or node, after you created it). In the forms validate and submit functions, you'll have to separate the forms again so that you can call the standard validation/submit handlers for both separately.
I have not done this yet, so I'm not sure how well this will play with the cck functionality, but I would expect it to work reasonably well to give it a try.

Resources