I'm trying to create a custom deployer in Tridion 2011 SP1 that can index a component to a solr instance once published. Everything is working fine but I've come across a bit of a problem with the way it indexes the components fields.
I can access the meta data fields okay by using the Component.getCustomMeta() method and parsing the XML. Accessing the normal fields however does not seem to be possible without reading in the file that is being output and parsing the output. This is not entirely feasible as the markup may change and it seems to be a long way around doing what should (hopefully) be a simple thing.
I've had a trawl through the docs and there doesn't seem to be anything available to get the field values so am I at a loss here and will need to parse the output or am I missing something somewhere?
Content fields are not exposed as such on the delivery side, content is exposed as, not surprisingly, "content".
If you really need the fields, you need to:
Produce a "parseable" output for your component presentations
Parse the component presentations as they get published.
Look at implementations like DD4T for similar approaches.
In short - you cannot do it, because Tridion does not expose it Out of the Box. The only way to do it is by changing the content output format through a template.
We have done an alternative workaround to achieve for the similar requirement. One down side with the implementation is extra rendering of Component Presentations in XML and duplicate of xml storage in broker.
Here is what we have done:
Created a Dynamic CT (XML representation of content) GetComponentAsXML and mapped to all schemas
All the Page Templates has a C# TBB that looks up the content that we need to push to SOLR
C# TBB does the RenderComponentPresentation with above Dynamic CT GetComponentAsXML, this pushes the XML (engine.RenderComponentPresentation(component.Id, componentTemplateURI)
Deployer now gets the content in xml format, in addition to the other type of component presentations (like ascx, emebedded on page etc..)
Hope this information helps.
Related
We are building a Page with dynamic functionality using ASP.NET + Sitecore 7.0.
Is it practical and appropriate use Sitecore templates for:
SQL Stored Procedure Name to be invoked
JavaScript to be invoked
ColumnNames to be used etc (related to coding customization)
Or should these configuration properties remain inside the ASP.NET Project itself?
What is the primary purpose of Data Templates in Sitecore?
Are they for developer customization or customer-level customization?
The purpose of a data template in Sitecore is to define the set of fields for content items which inherit from that template. - Think of a data template as a class and the content items (pages) as instances of that class.
Templates are usually used to define the user-editable content of pages within a site, that being said you can have items to store information which is not managed by regular content editors. The question is where do you draw the line between things which should be put into Sitecore and things which should be a part of the solution. My advice is only put things in Sitecore if they need to be there. If you have to have the ability for editors or admins to configure those settings/properties.
I would say that putting SQL/ColumnNames is probably a bad idea unless you are building some sort of report builder interface in which case it may be essential?
Likewise with placing JavaScript into Sitecore; this can be OK in moderation (e.g. snippets of analytics code which content editors may want control over?). If you're placing whole libraries of JavaScript into Sitecore, you're probably doing it wrong.
One final point to note is findability/re-factorability of code: if you have code spread between Sitecore and your solution, it can make it very difficult to maintain as it is difficult to get a complete overview of code involved.
We often need specific items (schemas, templates, or components) in Tridion-related code. Template, Content Delivery, Workflow, or the Business Connector (Core Service) regularly need references to Tridion Content Manager URIs. We can link to components, but I typically see either hard-coded values or WebDAV URLs for everything else.
Hard-coded values
I understand hard-coding Tridion Content Manager (Native) URI's is a bad practice except for a few scenarios:
To simplify example code and make it clear what a variable is
When generated for use in Content Delivery (CD) API logic
Whenever possible we use the given API or WebDAV URLs to reference items, otherwise we must avoid using Content Porter on anything that references TCM URIs (or somehow make these references "configurable" outside of Tridion).
WebDAV URLs
WebDAV URLs seem to be better for a few reasons:
Hard-coded values in design template building blocks (TBBs) or other template formats remain intact with SDL Content Porter (breaking a relationship when moved through CMS environments, with an exception described below)
"Configuration" components that refer to specific items also do better with SDL Content Porter, though differently-named paths can "break" relationships
Use cases
In addition to having template that work well with Content Porter, I would like to localize folders and/or structure groups in lower publications. This can help with:
CMS authors that read different languages
translate item names and paths to appropriate languages
maybe help users navigate better (e.g. I suspect different-named folders may reduce confusion for where authors are in the BluePrint)
One Approach
To make references "Content Porter-friendly," at least for Template Building Blocks, I know we can use WebDAV Urls in components making sure to localize each path to the right locations in children publications. For example:
Code checks Publication Metadata
Publication Metadata points to a "config component"
Config component has paths as WebDAV URLs
As long as we set the Publication Metadata and localize the fields to the correct paths per publication, this will work for most scenarios.
Questions
Did I get this right? Is there a simpler or easier-to-maintain setup?
I believe we can alternatively use includes or map unmanaged URI in template code.
Anyone have an example of the #include approach? Do I use that at the top of a TBB and/or DWT and do references get replaced regardless of Template Mediator (e.g. will this work with XSLT Mediator, Razor Mediator, etc?)
Does the included reference work in lower publications or is this just for Content Porter? In other words, if I reference "tcm:5-123" will the template correctly reference "tcm:17-123" in publication 17?
I tend to follow a few simple rules...
There is no single valid reason to ever use a TCM ID in anything - template code, configuration components, configuration files.
If I need webdav URLs in configuration, I try to always make them "relative", usually starting at "/Building%20Blocks" instead of the publication name. At runtime I can use Publication.WebDavUrl or PublicationData.LocationInfo.WebDavUrl to get the rest of the URL
Tridion knows what to do with managed links, so as much as possible, use them. (managed links are the xlink:href stuff you see a bit all over Tridion XML).
I also tend to use a "configuration page" for content delivery, with a template that outputs the TCM IDs I may need to "know" from the content delivery application. This is then either loaded at run time as a set of configuration variables or as dictionary or as a set of constants (I guess it depends how I'm feeling that day).
Although we commonly refer to a Template Type implementation as a Template Mediator, that's not the whole story. A Template Type implementation consists of both a Template Mediator, and a Template Content Handler, although the latter is optional. Whether a given implementation will process "includes" correctly depends not on the mediator but the handler.
A good starting point in the documention can be found by searching for AbstractTemplateContentHandler.
SDL Tridion's own Dreamweaver Templating implementation has such a handler. I've just looked at the Razor implementation, and it currently makes use of the Dreamweaver content handler. Obviously, YMMV for the various XSLT template type implementations that exist.
As this is an extensibility point of SDL Tridion, whether included references will work "correctly" in lower publications depends on the implementer's view of what that would mean.
One interesting possibility is to implement your own custom handler that behaves as you wish. The template type configuration (in the Tridion Content Manager configuration file) allows for the mediator and content handler for a given template type to be specified independently, which means you could potentially customise the content handling behaviour for an existing template type.
I am having a problem using the UGC framework in conjunction with dynamic component presentations.
When I publish a CP as 'embedded on page', my UGC tags are converted from to nicely and I am able to leave ratings etc. However, if I create a dynamic version of the same CT/CP, what gets deployed to the Broker, is the same component presentation, with the stripped out.
Is there a limitation here that I am not aware of, or maybe some missing configuration?
Any thoughts would be very welcome.
I think you will need to check the output format of your Dynamic CT - Make sure it is set to the same as your target (REL, ASP.NET, JSP etc), and not set to None or HTML
I am newbie in Tridion. I am looking for some sample code for a TBB to get all components for a component template. I have seen examples of how to get components of a page or from a folder but not for this.
I could get the count by using object.GetListUsingItems(filter).SelectNodes(*).Count in my template, but I need a way to iterate all components and get Title or other attributes of Components.
Please advise.
You cannot get all components for a template in one go, you need to look first at which Schemas are associated with this component template, then get all components for each schema. Be aware of Blueprint contexts when doing this.
I'm slightly confused as to what you're trying to achieve with this, if you want to do this as part of a publishing action you would very quickly end up with massive publish transactions with many components in it.
If you want more attributes than exposed in Lists, then use GetUsingItems instead - but be aware that this is a considerably slower operation with a lot more database interactions than getting a list.
I need to attach specific XML to a word document so the elements will show up in the right places. This I can do with OpenXML SDK.
The thing is I want too be able to define the Content Controls already bounded in some sort of template so other people can create the real document template the xml will be attached to. Ok not sure people will undestand what I mean so I will explain further.
There may be many different document templates that will use the same XML data and so the same Content Controls. It's up to someone else to create the document.
Scenario: Some dude that's not a programmer needs to create a new form for the usual info because of some changes ( new layout or somehting ). This has nothing to do with the XML info, that stays the same.
Optimal solution for "some dude" would be to create the document in Word and drag the Content Controls into place ( or some solution similiar). Then when the XML gets added to the document there is no problem as the Content Controls are pre-binded.
Now there are a few points here:
1) Can Content Controls be pre-binded? If there is no XML at the path won't it just stay empty without problems?
2) Will binding Content Controls to CustomXML's like this still work in future versions of Word because of the i4i lawsuit?
3) Is there perhaps another optimal solution better then this?
Thanks in advance.
EDIT:
To be more clear. I wan't to create Content Controls that would have some name to identify them and a databound xpath. However at that moment there is nothing at the path.
Another user comes in and creates a form, decides the layout on so on, and then adds the Content Controls into the places he wants the info to be.
Later on the info for item X is requested using the new form. So a copy of that form will be taken and the CustomXML will be added into the Docx file. Now because the XML shchema was known beforehand and used when deciding the paths for the CC's this XML data will be bound to the Content Controls.
One great option would be to use VSTO (Visual Studio for Office) to build a set of document templates that have your prebinding code attached. These two articles provide a good start into looking into this type of a solution:
Creating a Template By Using Content
Controls
Binding Content Controls to Custom
XML Parts
There are two threads that discuss some details of this: 1 and 2.
One of the benefits about using VSTO is that you can hook the Content Control events: Content Control Event Model in Word 2007.
If VSTO is not an option, you can always look at Add Custom XML Parts to Documents Without Starting Microsoft Office.
This should be very straightforward. Custom controls are not impacted by the i4i lawsuit and you can name them using the tag property in each control (warning - it is limited to 64 characters).