Component will not delete - tridion

I'm doing a bit tidy of the Content Manager and have a component that won't delete (not the same as my other question).
When I try to delete the component in question I get the following error
(8004032D) This item is in use.
Unable to delete Component (tcm:4-65020).
UtilitiesBL.AssertItemCanBeDeleted
UtilitiesBL.AssertItemCanBeDeleted
ComponentBL.Delete
Component.Delete
Request.Delete
When I use the Where Used tool on the component I get no results in the "Used In" tab, one result in the "Uses" tab, the "Blueprint Hierachy" shows it is not localized in any of my three child publications and no results in the "Published To" tab.
I have had a look in the Content Manager database to see if I can spot what is going wrong but not really found anything.
Any ideas?
Thanks in advance.

It looks like the Where Used tool in R5.3 isn't working correctly. The component in question is used in 15000 other components. I found this by using the TOM API directly.
var componentID = "tcm:4-65020";
TDS.TDSE tdse = new TDS.TDSE();
var component = (TDS.Component)tdse.GetObject(componentID, TDSDefines.EnumOpenMode.OpenModeView);
var whereUsedString = component .Info.GetListUsingItems();
Now comes the task of deleting all these links...

Related

Meteor how to save templates in mongo

I want to give my users the possibility to create document templates (contracts, emails, etc.)
The best option I figured out would be to store these document templates in mongo (maybe I'm wrong...)
I've been searching for a couple of hours now but I can't figure out how to render these document template with their data context.
Example:
Template stored in Mongo: "Dear {{firstname}}"
data context: {firstname: "Tom"}
On Tom's website, He should read: "Dear Tom"
How can I do this?
EDIT
After some researches, I discovered a package called spacebars-compiler that brings the option to compile to the client:
meteor add spacebars-compiler
I then tried something like this:
Template.doctypesList.rendered = ->
content = "<div>" + this.data.content + "</div>"
template = Spacebars.compile content
rendered = UI.dynamic(template,{name:"nicolas"})
UI.insert(rendered, $(this).closest(".widget-body"))
but it doesn't work.
the template gets compiled but then, I don't know how to interpret it with its data context and to send it back to the web page.
EDIT 2
I'm getting closer thanks to Tom.
This is what I did:
Template.doctypesList.rendered = ->
content = this.data.content
console.log content
templateName = "template_#{this.data._id}"
Template.__define__(templateName, () -> content)
rendered = UI.renderWithData(eval("Template.#{templateName}"),{name:"nicolas"})
UI.insert(rendered, $("#content_" + this.data._id).get(0))
This works excepted the fact that the name is not injected into the template. UI.renderWithData renders the template but without the data context...
The thing your are missing is the call to (undocumented!) Template.__define__ which requires the template name (pick something unique and clever) as the first argument and the render function which you get from your space bars compiler. When it is done you can use {{> UI.dynamic}} as #Slava suggested.
There is also another way to do it, by using UI.Component API, but I guess it's pretty unstable at the moment, so maybe I will skip this, at least for now.
Use UI.dynamic: https://www.discovermeteor.com/blog/blaze-dynamic-template-includes/
It is fairly new and didn't make its way to docs for some reason.
There are few ways to achieve what you want, but I would do it like this:
You're probably already using underscore.js, if not Meteor has core package for it.
You could use underscore templates (http://underscorejs.org/#template) like this:
var templateString = 'Dear <%= firstname %>'
and later compile it using
_.template(templateString, {firstname: "Tom"})
to get Dear Tom.
Of course you can store templateString in MongoDB in the meantime.
You can set delimiters to whatever you want, <%= %> is just the default.
Compiled template is essentially htmljs notation Meteor uses (or so I suppose) and it uses Template.template_name.lookup to render correct data. Check in console if Template.template_name.lookup("data_helper")() returns the correct data.
I recently had to solve this exact (or similar) problem of compiling templates client side. You need to make sure the order of things is like this:
Compiled template is present on client
Template data is present (verify with Template.template_name.lookup("data_name")() )
Render the template on page now
To compile the template, as #apendua have suggested, use (this is how I use it and it works for me)
Template.__define__(name, eval(Spacebars.compile(
newHtml, {
isTemplate: true,
sourceName: 'Template "' + name + '"'
}
)));
After this you need to make sure the data you want to render in template is available before you actually render the template on page. This is what I use for rendering template on page:
UI.DomRange.insert(UI.render(Template.template_name).dom, document.body);
Although my use case for rendering templates client side is somewhat different (my task was to live update the changed template overriding meteor's hot code push), but this worked best among different methods of rendering the template.
You can check my very early stage package which does this here: https://github.com/channikhabra/meteor-live-update/blob/master/js/live-update.js
I am fairly new to real-world programming so my code might be ugly, but may be it'll give you some pointers to solve your problem. (If you find me doing something stupid in there, or see something which is better done some other way, please feel free to drop a comment. That's the only way I get feedback for improvement as I am new and essentially code alone sitting in my dark corner).

XPages Dojo DataGrid and REST Service do not save editable columns changes

We have a REST Service and Dojo DataGrid that does not save the changes to editable columns on the initial load -- meaning the XPage loads and changes are made. The only way the changes are saved is after the close() or revert() method for the REST service is called, then the save() method is called. The REST Service is pointing to another database on the same server, and uses the keys property:
<xe:restService id="rsVictims" pathInfo="rsVictimsData">
<xe:this.service>
<xe:viewItemFileService defaultColumns="true"
viewName="InvoiceGridVictims" contentType="application/json"
databaseName="voca\vocadatastore.nsf" keys="k28ts71zrjsw">
</xe:viewItemFileService>
</xe:this.service>
</xe:restService>
Here is the DataGrid:
<xe:djxDataGrid id="djxDataGrid1" storeComponentId="rsVictims"
autoHeight="90">
<xe:djxDataGridColumn id="djxDataGridColumn1"
label="Target" width="35px" field="victimTarget">
</xe:djxDataGridColumn>
<xe:djxDataGridColumn id="djxDataGridColumn2"
label="Oct" width="35px" field="month_10" editable="true">
</xe:djxDataGridColumn>
</xe:djxDataGrid>
It flows like this:
Open the XPage with the REST service and DataGrid
Make changes to the editable columns
Click the Save button which calls this code (code is copied from Brad Balassaitis' demo, 06 Custom Control):
<xp:button value="Save Changes" id="victimsSaveButton">
<xp:eventHandler event="onclick" submit="false">
<xp:this.script><![CDATA[// Save the changes...
editedRows = [-1];
var args = {onError: function() {alert('error!');}};
rsVictims.save(args);
//Refresh the grid
rsVictims.close();
dijit.byId('#{id:djxDataGrid1}')._refresh();]]></xp:this.script>
</xp:eventHandler>
</xp:button>
DataGrid is closed, refreshed, but changes are NOT saved
Make changes again and click the Save button
DataGrid is closed, refreshed, and changes are now saved
What I have noticed is that the DataGrid is loaded twice when the XPage is opened -- I see this is Firebug in the Net tab. On the first GET, it retrieves the grid correctly -- the Response is correct, the JSON is formatted correctly, and the start=0 with a count=25.
On the second GET, it seems to lose the grid -- the Response is empty, the JSON items is empty, and the start=25 with the count=25. I have tried setting the start property in the REST Service to 0, but that does not do anything. I have tried setting the count property to 500 as well, but that does not fix it either.
The interesting fact about this is, when the view is moved inside the current database -- so the databaseName property on the REST Service is not used -- the Save button works perfectly. Also, there is only one GET when loading the DataGrid, not two GETs when pointing to a view in another database on the same server. I know there are some issues when looking to another server, but these databases are on the same server.
I know I have posted about this topic before, but I did not get an answer that worked. I am hoping this sheds some more light on what I may be missing.
Thanks in advance!
Dan,
I have nearly an identical situation in my current project. I have mine working perfect so I think I can help. I assume that you already took Per Lausten's suggestion in your previous SO. You wouldn't be able to save at all if you didn't.
The difference between your code and mine is that I am using a xe:viewJSONService instead of a xe:viewFileItemService. The extention library book says that you have to use the viewFileItem if you want it updatable, but this is NOT true.
I had nothing but trouble with the viewItemFileService, see this blog post for the issues I had (http://notesspeak.blogspot.com/2013/07/going-with-extjs-grid-and-giving-up-on.html) I nearly gave up entirely on the dojo grid, but came back to it because it works on mobile.
Using the viewJSONService just works. Instead of a keys property, use the category filter. For you category have code similar to this:
var category:String = lineItemBean.getThisUNID();
if(category == null){
return "show nothing"
} else {
return lineItemBean.getThisUNID();
}
//prevents all records from being returned
You need to be careful, because if the category is null, all records are returned, which could be a big problem or security hole. In my example, I pull from a bean, but you could put a document reference there as well.

How to get the itemxml of a selected item in Tridion

I would like to get and display the itemxml of the selected item from the Tridion CME.
I was able to get the Itemxml from my VM server when i give the tcm id in the browser.
However, i would like to get the same information from Tridion GUI Extension.
I am able to get the selected item tcm id. Is there any way to get the itemxml using coreservice?
or is there any other way to get this?
At the moment there's no way you can get Item XML through core service. Item XML you have seen was provided to you by TCM Protocol handler that might not be there in future versions. If you want to show item XML in CME - take a look at this extention by Yoaw:
http://sdltridionworld.com/articles/sdltridion2011/tutorials/GUIextensionIn8steps.aspx
Also, keep in mind that not all properties of an item might be exposed in Xml, sometimes you have more info in Data object
Take a look at the PowerTools, it has an ItemXML viewer (written by Robert Curlette) for all items in SDL Tridion
http://code.google.com/p/tridion-2011-power-tools/wiki/ItemXML
The XML is loaded on a tab using JavaScript as follows:
ItemXmlTab.ItemXmlTab.prototype.updateView = function ItemXmlTab$updateView()
{
if (this.isSelected())
{
var xslPath = $ptUtils.expandPath("/PowerTools/Client/ItemXml/ItemXmlTab.xslt", true);
$xml.loadXsltProcessor(xslPath, function (value)
{
var xmlSource = $display.getItem().getXml();
// Filter out all spacing characters
xmlSource = xmlSource.replace(/\t|\n|\r/g, "");
var html = $xml.xsltTransform(value, $xml.getNewXmlDocument(xmlSource), null);
$dom.setOuterHTML($("#itemXml"), html);
});
}
};
You can view the source code of the extension at http://code.google.com/p/tridion-2011-power-tools/source/browse/#svn%2Ftrunk%2FPowerTools.Editor%2FPowerTools%2FClient%2FItemXml%253Fstate%253Dclosed
You can get the item XML via CoreService, but this will get you the Tridion R6 (2011) Xml format, which is not the same you would see before.
Sample code available here.
I tend to have a page "GetItemXml.aspx" on my Tcm servers that I then call with a Uri as a parameter, and then this page would return the Item Xml.
Article written by Yoav Niran (Url in the post of user978511) is perfect for your requirement.
if you are still facing any issue and in hurry to get it working just perform below steps -
1- Download the extension.
2- Apply the steps 7 and 8 of this article to configure this extension.

How can you extend the default behavior of Tridion.Cme.Commands.Open.prototype._execute()?

I have written a GUI extension which adds an additional tab to many of the Item views in the SDL Tridion CME (e.g. Component, Page and Schema etc.). I have also written some JavaScript which loads that tab directly if when the view is loaded with a tab name is specified in the URL.
The result is that if a page is loaded with the tab name added as follows:
http://localhost/WebUI/item.aspx?tcm=64#id=tcm:1-48-64&tab=InfoTab
Rather than the default of
http://localhost/WebUI/item.aspx?tcm=64#id=tcm:1-48-64
The Info Tab will be loaded on top, instead of the General Tab. This is performed with the following code snippet and works very well:
$evt.addEventHandler($display, "start", onDisplayStarted);
// This callback is called when any view has finished loading
function onDisplayStarted() {
$evt.removeEventHandler($display, "start", onDisplayStarted);
var tabname = $url.getHashParam("tab");
if (tabname != '') {
var tabControl = $controls.getControl($("#MasterTabControl"), "Tridion.Controls.TabControl");
tabControl.selectItem(tabname);
}
}
Now I would like to make a context menu item to open items and link to the tabs using my new functionality. My first thought was to construct the Item URL myself and simply open a new window in my execute method. So I looked at the default functionality in the standard Open.prototype_execute() functionality of the GUI. This is stored in the navigation.js file of the CME, and is performed by the Tridion.Cme.Commands.Open.prototype._execute method. The code is a lot more complicated than I had anticipated as it deals with shared items, and permissions etc.
Rather than just copying all of this code to my own function, I was wondering if there is a way to elegantly extend the existing Open.prototype_execute() function and append my “&tab=MyTab” to the $cme.Popups.OPEN_ITEM_OPTIONS.URL constant for my own functions.
Any advice would be greatly appreciated.
At the end the Open command uses $config.getEditorUrl(item_type) to get the url for the item view (item_type - $const.ItemType.COMPONENT, etc). There are no extension points for this part of the functionality, but you could always try to overwrite it on your own risk.

Anguilla - Get the version and user information

I have created a command button on the Ribbon Toolbar. When I select an component an click on "Display Info" button, an popup should open telling me about the latest version of the Component, Modified date, and the User who last modified it.
I do get the component with the following code:
var item = $models.getItem(selection.getItem(0));
How can I get the other information from here.
Part 2:
When I try to see the JS code in Firebug, I see them in one single line. I am unable to put an break point on the execute function within my code.
Any suggestions on the above points. ?
To deminify the JS, to allow you to add breakpoints, and also to allow you to use a JS console to inspect objects that are available, you can follow the instructions at http://code.google.com/p/tridion-2011-power-tools/wiki/DeactivateJSMinifier.
User information can be retrieved using the information at How to get the user Id of the currently logged user in Tridion?
I find that the only way to find anything with Anguilla is to use a JS Console like Chrome's.
Once you get the current item - like you do now - you can do stuff like:
var version = item.getVersion();
var lastModifiedDate = item.getLastModifiedDate();
var lastEditorId = item.getStaticRevisorId();
getStaticRevisorId() gives you the Tridion URI of the last user to change the item, and you can then load this to retrieve further information from it.

Resources