Sitecore 7, Link manager, alwaysIncludeServerUrl not working - sitecore

I am using sitecore 7 single site instance.
Content editor is generating link to other sitecore pages in this format
Agriculture
after publishing link is not converted to the actual sever related URL.
I have chnaged the link manager setting "alwaysIncludeServerUrl" to true but still not getting proper URL.
I have published the page but still not showing actual URL.
Update: I can't use field control here because there is some additional logic that controls what text needs to be rendered. for example, If there is page data source is defined then use that otherwise use "ContentBlock" field of the current item.
public string ContentBlockContent = "";
Sitecore.Data.Items.Item currentItem;
if (Parent is Sublayout && !string.IsNullOrEmpty(((Sublayout) Parent).DataSource))
{
currentItem = Sitecore.Context.Database.GetItem(((Sublayout) Parent).DataSource);
}
else
{
currentItem = Sitecore.Context.Item;
}
if (currentItem.Fields["ContentBlock"] != null)
{
ContentBlockContent = currentItem.Fields["ContentBlock"].ToString();
}
if (currentItem.Fields["PageContentSource"] != null)
{
var contentPageSource = currentItem.Fields["PageContentSource"];
var sourceItem = Sitecore.Context.Database.GetItem(contentPageSource.ToString());
if (sourceItem != null && sourceItem.Fields["ContentBlock"] != null)
{
ContentBlockContent = sourceItem.Fields["ContentBlock"].ToString();
}
}
and this is how "ContentBlockContnet" property is rendered on the page.
<%= ContentBlockContent %>

>>after publishing link is not converted to the actual sever related URL.
It’s not converted after publishing, it’s converted when page is rendered.
Make sure you render content fields using Sitecore render controls e.g. sc:text, sc:link or FieldRenderer. In this way Sitecore will run the “renderField” pipeline which take care about link conversion.

Related

Attachments moved away from Item after validation and before submit process in Apex

I have multiple File Browser Item fields on one page of Application in Oracle Apex.
What happens: When I miss any Item for which validation error fires, I want to hold that file to the browser but I usually loose it if I get that validation error. Is there a solution for the same like other Items fields hold previous value except File Browser Item field. Please see below ss:
Anshul,
APEX 4.2 is very old and no longer supported. A later (or preferably latest) version of APEX will behave differently as Dan explained above.
Can you import your application into apex.oracle.com (which is running APEX 20.1) and you will probably see better results. Based on this you can hopefully use it as justification to upgrade your environment.
Regards,
David
Go to your page-level attributes and a function like the following in the Function and Global Variable Declaration:
function validateItems(request) {
var $file1 = $('#P68_FILE_1');
var $file2 = $('#P68_FILE_2');
var errorsFound = false;
if ($file1.val() === '') {
errorsFound = true;
// Show item in error state
}
if ($file2.val() === '') {
errorsFound = true;
// Show item in error state
}
if (!errorsFound) {
// I think doSubmit was the name of the function back then. If not, try apex.submit
doSubmit(request);
} else {
// Show error message at top of page, I'll use a generic alert for now
alert('You must select a file for each file selector.');
}
}
Then, right-click the Create button and select Create a Dynamic Action. Set the name of the Dynamic Action to Create button clicked.
For the Action, set Type to Execute JavaScript Code. Enter the following JS in code:
validateItems('CREATE');
Finally, ensure that Fire on Initialization is disabled.
Repeat the process for the Save button, but change the request value passed to validateItems to SAVE.

Sitecore's treelist field not getting updated immediately

I am updating sitecore treelist field type through code in background (when RTE is open for the same item) and it is not reflecting with the new values immediately. I had checked both in database and CMS.
After sometime it reflects in the field and the database as well.
Here are few things I checked:
Cleared sitecore and browser cache.
Added Cachemanager. Enabled=false and Cachemanager.Enabled=true when updating the item.
Checked the eventqueue table if the item save event is called.
Here is the code:
var article = master.GetItem(new ID(data.CurrentItemId));
if (article != null)
{
var referencedValues = article.Fields["Referenced articles"];
using (new SecurityDisabler())
{
//CacheManager.Enabled = false;
article.Editing.BeginEdit();
if (referencedValues != null)
referencedValues.Value = "{5A3D67DF-3917-4AC2-BDAF-69CDA1204C2A}";
article.Editing.EndEdit(true);
//CacheManager.Enabled = true;
}
}

Issue trying to use Datasource Template in Sitecore sublayout; getting empty Sublayout.Datasource

We've been trying to "componentize" our Sitecore solution as we move forward, in prep for transitioning to Page Editor usage (Woot! Finally!), but we're still practically working primarily with Page templates that may be inheritance-based composites of page specific fields, plus 1:many of these componentized templates. An example of how this looks in our solution is below -- Banner Feature Carousel and Featured Cartoon are some of these new components we're creating:
In the interest of trying to move away from using Sitecore.Context.Item (as I was recently reminded by this post) I've started filling in the Datasource template field on the sublayouts for the new components, and it seems like I've got the appropriate connections made between presentation details, the Sitecore sublayout and the .NET code file (as far as I can tell; again, we're newer to working this way).
I've also tried setting up a base class for these components as per this post by Nick Allen, but here's where I'm running into a problem: When I execute my code, this base class is finding the component Sublayout appropriately (the whole "this.Parent as Sublayout" thing) but, when I go to interrogate the Sublayout.Datasource property, it's an empty string. Here's my code (so far) for this base class:
public class ComponentBase : System.Web.UI.UserControl
{
private Sublayout Sublayout { get { return Parent as Sublayout; } }
public Item DataSourceItem
{
get
{
return Sublayout != null && !String.IsNullOrEmpty(Sublayout.DataSource) ?
Sitecore.Context.Database.GetItem(Sublayout.DataSource) : Sitecore.Context.Item;
}
}
}
I'm apparently missing some interplay between the Datasource Template field in the Sitecore sublayout, and how that actually translates to a datasource. Is it because these component templates are being used to compose Page templates? I was thinking that the datasource would just ultimately resolve to the Page template on which the component in question was currently being used, but perhaps that's my misunderstanding.
If anyone could give me any hints of things to check or point me to any resources I might use to get further, I'd appreciate it. I've done quite a bit of asking the Googs, myself, but am just not getting anything that's helping.
Thank you in advance, Sitecore friends!
It looks like you have configured the allowed templates for your sublayout in the steps you describe above. This basically tells Sitecore; 'allow user to select items based on these templates for this sublayout'. This alone does not set up the data source on items using the sublayout. You still need to go into the presentation details for any items using this sublayout, select the sublayout and then set its datasource property (within the content editor go to Presentation > Details > [Sublayout] > Data Source).
My answer to this question gives the source code needed to retrieve the datasource item and to iterate through the sitecore controls on your sublayout setting all of their Item propertys.
Here is the code:
public class SublayoutBase : UserControl
{
private Item _dataSource;
public Item DataSource
{
get
{
if (_dataSource == null)
{
if (Parent is Sublayout)
{
_dataSource =
Sitecore.Context.Database.GetItem(((Sublayout)Parent).DataSource);
}
if (_dataSource == null)
{
_dataSource = Sitecore.Context.Item;
}
}
return _dataSource;
}
}
protected override void OnLoad(EventArgs e)
{
foreach (Control c in Controls)
{
SetFieldRenderers(DataSource, c);
}
base.OnLoad(e);
}
private void SetFieldRenderers(Item item, Control control)
{
if (item != null)
{
var ctrl = control as Sitecore.Web.UI.WebControl;
if (ctrl != null && !string.IsNullOrEmpty(ctrl.DataSource))
{
//don't set the source item if the DataSource has already been set.
return;
}
if (control is FieldRenderer)
{
var fr = (FieldRenderer)control;
fr.Item = item;
}
else if (control is Image)
{
var img = (Image)control;
img.Item = item;
}
else if (control is Link)
{
var link = (Link)control;
link.Item = item;
}
else if (control is Text)
{
var text = (Text)control;
text.Item = item;
}
else
{
foreach (Control childControl in control.Controls)
{
SetFieldRenderers(item, childControl);
}
}
}
}
}
When you start using sublayouts on which you will set your datasource try to use the marketplace "Sublayout Parameter Helper". When you use the class they provide as base class and have set everything up right in your Sitecore Environment you will find yourself having a "this.DatasourceItem" -> which will contain your datasource Item, or the context Item if none is given.
http://marketplace.sitecore.net/en/Modules/Sub_Layout_Parameter_Helper.aspx
To find out more on how datasource works, try searching on http://sdn.sitecore.net. There is alot of documentation available that should get you in the right direction. Generally it will be enough to just add a datasource in the sublayout that you can access in your sublayout.
When you read a datasource from a sublayout all it will do is check if the datasource field on that sublayout is filled and will return you information regarding this datasource. So when you add a new component to a page using the page editor (for example a sublayout for a news article) and you have a datasource template defined and filled in during adding this components, you will see that when you check the presentation details on that page a sublyaout with a datasource has been added. The datasource will point to a folder in which you will find an item based on the datasource template you specified on your sublayout. You should also double check this, cause if no datasource is present on the added sublayout it will be obvious you can't access it from your code.
If you are using Sitecore 7 update 1 you can actually now use the attributes. From the Release Notes:
To make it easier to get the data source for a sublayout from
code-behind, the data source is now transferred to the sublayout
control in a "sc_datasource" attribute. (320768)
To get the data source from code, simply refer to
this.Attributes["sc_datasource"];

How to flag new items as unpublished items?

In sitecore, if I add a new item to the master database(Unpublished), it does not show any indication regarding the published state.
For an example, if a user has added 10 items, he might get confused to figureout the items added by him which are pending for publishing.
Is there a way to identify newly added items as unpublished or in new and display a validation in the "Quick action bar"?
Never thought about this, but it's actually pretty easy to fix.
I created a GutterRenderer that indicates wether an item has been published to at least one, to all, or to none of the publishing targets.
EDIT: Added Click behaviour. When you click the gutter icon, the Publish dialog will be shown for that item.
First I will show you the code that I wrote for this and then I'll show you screenshots of the setup and the result.
Here is the code:
using System.Collections.Generic;
using System.Linq;
using Sitecore;
using Sitecore.Data;
using Sitecore.Data.Items;
using Sitecore.Globalization;
using Sitecore.Shell.Applications.ContentEditor.Gutters;
namespace ParTech.Library.Gutters
{
public class PublicationStatus : GutterRenderer
{
private readonly ID publishingTargetsFolderId = new ID("{D9E44555-02A6-407A-B4FC-96B9026CAADD}");
private readonly ID targetDatabaseFieldId = new ID("{39ECFD90-55D2-49D8-B513-99D15573DE41}");
protected override GutterIconDescriptor GetIconDescriptor(Item item)
{
bool existsInAll = true;
bool existsInOne = false;
// Find the publishing targets item folder
Item publishingTargetsFolder = Context.ContentDatabase.GetItem(publishingTargetsFolderId);
if (publishingTargetsFolder == null)
{
return null;
}
// Retrieve the publishing targets database names
List<string> publishingTargetsDatabases = publishingTargetsFolder.GetChildren()
.Select(x => x[targetDatabaseFieldId])
.ToList();
// Check for item existance in publishing targets
publishingTargetsDatabases.ForEach(delegate(string databaseName)
{
if (Database.GetDatabase(databaseName).GetItem(item.ID) != null)
{
existsInOne = true;
}
else
{
existsInAll = false;
}
});
// Return descriptor with tooltip and icon
string tooltip = Translate.Text("This item has not yet been published");
string icon = "People/16x16/flag_red.png";
if (existsInAll)
{
tooltip = Translate.Text("This item has been published to all targets");
icon = "People/16x16/flag_green.png";
}
else if (existsInOne)
{
tooltip = Translate.Text("This item has been published to at least one target");
icon = "People/16x16/flag_yellow.png";
}
return new GutterIconDescriptor()
{
Icon = icon,
Tooltip = tooltip,
Click = string.Format("item:publish(id={0})", item.ID)
};
}
}
}
And this is how so set it up and how it will look once it's running:
Figure 1: Create a new Gutter item in the Core database:
Figure 2: Switch back to your Master database and activate the Gutter by right-clicking in the gutter area.
Figure 3: The Gutter now indicates the publication status of your items
From the top of my head it's not available out of the box. In the core database however, there's the definitions of the gutter, etc. You could create your own.
There's the 'published' field on items though, but I'm not sure if that takes different versions into account.
Maybe you can check the differences between the item in the master and web (i.e. Item doesn't exist or is different version in web, then it's waiting to be published).
Alternatively, have a read through this: http://webcmd.wordpress.com/2011/08/31/sitecore-ribbon-that-displays-published-state-of-an-item/
It'll explain how to check if an item is published as a ribbon.

How do I utilize the save event in a Sitecore custom Item Editor?

I am creating a custom item editor, and am using the following blog post as a reference for responding to the "save" event in the Content Editor, so that I do not need to create a second, confusing Save button for my users.
http://www.markvanaalst.com/sitecore/creating-a-item-editor/
I am able to save my values to the item, but the values in the normal Content tab are also being saved, overriding my values. I have confirmed this via Firebug. Is there a way to prevent this, or to ensure my save is always after the default save?
I have this in as a support ticket and on SDN as well, but wondering what the SO community can come up with.
Thanks!
Took a shot at an iframe-based solution, which uses an IFrame field to read and save the values being entered in my item editor. It needs to be cleaned up a bit, and feels like an interface hack, but it seems to be working at the moment.
In my item editor:
jQuery(function () {
var parentScForm = window.parent.scForm;
parentScForm.myItemEditor = window;
});
function myGetValue(field) {
var values = [];
jQuery('#myForm input[#name="' + field + '"]:checked').each(function () {
values.push(jQuery(this).val());
});
var value = values.join('|');
return value;
}
In my Iframe field:
function scGetFrameValue() {
var parentScForm = window.parent.scForm;
if (typeof (parentScForm.myItemEditor) != "undefined") {
if (typeof (parentScForm.myItemEditor.myGetValue) != "undefined") {
return parentScForm.myItemEditor.myGetValue("myLists");
}
}
return null;
}
In theory, I could have multiple fields on the item which are "delegated" to the item editor in this way -- working with the content editor save rather than trying to fight against it. I'm a little uneasy about "hitchhiking" onto the scForm to communicate between my pages -- might consult with our resident Javascript hacker on a better method.
Any comments on the solution?
EDIT: Blogged more about this solution