I have seen a post in Stackoverflow regarding how to hide the "Publish sub items" from Sitecore publish pop up by overriding the visibility of the checkbox. This is really good which can avoid so many performance issues when there is large amount of content in the content tree.
Is it possible to dynamically hide this checkbox? Coz, as a developer I need to publish other Sitecore items (Templates, Settings etc.) when it comes to deployments. Therefore "Publish sub items" is a essential feature for me. Still I need it to be hidden from content editors.
How can I achieve this task?
(If there was a security configuration to control access to this feature it would have been ideal)
First of all you need to change Publish.xml file from Folder:
\web\sitecore\shell\Applications\Dialogs\Publish\
You need to change CodeBeside it will look like this :
<WizardForm CodeBeside="YourNameSpace.CustomPublishForm,YourAssembly">
Your class will be :
class CustomPublishForm:PublishForm
{
public CustomPublishForm()
: base()
{
}
protected override void OnLoad(System.EventArgs e)
{
base.OnLoad(e);
//you need to change here with users that you want to see CheckBox
if (Sitecore.Context.User.Name.Equals("lorenipsum"))
{
base.PublishChildren.Visible = true;
}else
{
base.PublishChildren.Visible = false;
}
}
}
I tested and it's working fine this solution you have just to do minor changes to your requirements.
Here is the post: Sitecore - Hide "Publish Subitems" from publish pop up
You'll want to alter the CodeBeside attribute from Sitecore.Shell.Applications.Dialogs.Publish.PublishForm,Sitecore.Client to your own class that wraps that one. In your own class override any methods you need to in order for the logic to show or hide the box per your needs, e.g. user is in a certain role.
Be aware that such modifications make upgrades a bit harder.
Copying the Publish.xml and triggering this from a new button makes it clear for everyone, that this is not Sitecore but your own logic.
Related
I am trying to upgrade the old project(based on storefront for Sitecore 8.0) to version Sitecore 8.1(latest one at the moment).
During this process I faced with a problem when I see the same products for all categories. So, for example, I select a category first time and see correct products. After that I choose any other category, but still see the same products(from the first category).
These data are returned by ProductList rendering(a controller rendering) and it is not run after the first call anymore(tried to reach corresponding action in a CatalogController in debug mode).
If we clear all caches(..sitecore/admin/cache.aspx) - then it works again, but only first time.
I understand that I can't disable caching for the whole site, I need to do it for this generic page(with "*" in item name) where the commerce data are shown - so for all categories and product pages. I checked this rendering in design mode and can see that all checkboxes related to cache are unchecked at the moment. Don't know what I have missed.
Thank you in advance for the help.
I believe you have caching enabled on control/sublayout defintion level which will cause to cache that rendering on every page on the site, a while ago i was able to come up with a solution to disable caching for a specific rendering/sublayout on specific pages, while keeping it caching on other pages.
I basically created a new rendering parameter template with checkbox "Cancel Cache Settings", then in my rendering definition item, I set the parameter template to the new template, if your site runs on Sitecore MVC, do the following:
Create a class called 'SetCacheability'
namespace Sitecore.SharedResources.Pipelines.Rendering
{
public class SetCacheability : Sitecore.Mvc.Pipelines.Response.RenderRendering.SetCacheability
{
protected override bool IsCacheable(Sitecore.Mvc.Presentation.Rendering rendering, Sitecore.Mvc.Pipelines.Response.RenderRendering.RenderRenderingArgs args)
{
if (!String.IsNullOrEmpty(rendering.Parameters["Cancel Cache Settings"])
&& rendering.Parameters["Cancel Cache Settings"] == "1")
{
return false;
}
return base.IsCacheable(rendering, args);
}
}
}
Create the patch config file in your include folder:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<pipelines>
<mvc.renderRendering>
<processor patch:instead="processor[#type='Sitecore.Mvc.Pipelines.Response.RenderRendering.SetCacheability, Sitecore.Mvc']"
type="Sitecore.SharedResources.Pipelines.Rendering.SetCacheability, [YOUR ASSEMBLY NAME]"/>
</mvc.renderRendering>
</pipelines>
</sitecore>
</configuration>
Here is the blog i wrote on this: http://www.sitecorecoding.com/2014/09/disabling-caching-for-rendering-on-some.html
Hope this helps
The caching settings you've disabled are located in the presentation details on the control level:
Additionally, you should ensure that caching is disabled on your sublayout (or rendering) definition (under /sitecore/Layout/Sublayouts):
We have three states in workflow Draft, Editorial and Final.
Content authors on save of an item goes to Draft State and once they submit it goes to Editorial state and publisher can approve or reject it.
We have Content Authors who should not be able to delete pages (for this I removed delete access for home and all pages under it) in the site but should be able to delete the pages in draft state. Can this be achieved?
I feel that since I removed delete access for home and all pages under it, author is not able to delete his page in draft state as well.
An options to make a workflow state Delete, with a action to do the delete (I think you need the security disable or user switcher to do that.
But what about, if the author edit an already existing item, maybe you need a delete version instead of item.
using Sitecore.Data.Items;
using Sitecore.Workflows.Simple;
namespace Mirabeau.Sitecore.Workflow.Action
{
public class DeleteItemAction
{
public DeleteItemAction()
{
}
public void Process(WorkflowPipelineArgs args)
{
Item item = args.DataItem;
//example it is not realy save to have this code, every one can delete now. replace or make up with own check
using (new Sitecore.SecurityModel.SecurityDisabler())
{
item.Recycle();
}
}
}
}
Use /sitecore/templates/System/Workflow/Action below the Delete Workflow/Command
in the Data section,
"Type string" set the Mirabeau.Sitecore.Workflow.Action, YourDLL
See the "Auto Publish" action in the sample workflow.
An other option is to make a custom or change the Delete Command. Somethings like this Create a Command with dialoge but than with a Delete where you do your specific rights checks.
We are building some plugins in Microsoft Dynamics CRM by inheriting from IPlugin. We have these configured so they fire whenever an Account is updated.
The problem is the plugins are calling our services, which causes our service to respond with an update. We are doing some pretty hacky things right now to prevent these cyclical updates from happening.
We were wondering if there was a way to pass a value to the IOrganizationService service (the web service) that a plugin can look at. Our other system could send a flag ("hey, don't bothing sending an update!") and the plugin could skip calling back.
Can we pass parameters from web service to the plugins?
Good idea could be usage of custom flag-field. For example you add bit field and call it CallFromExternalSystem. So when you make an update from your external system through IOranizationService you just fill this flag with true field and in plugin you can check condition that this field is present in fields list so you have no need to call external system endpoint again.
We decided the correct solution was to use the value found in IPluginExecutionContext.InputParameters["Target"]. In the case of an Update, this returns an Entity containing attributes for all the attributes that were updated.
We basically have a list of attribute names we cared about. We loop through names and see if any of them appear in the entity attribute list. If so, we send an update to our other system. The good news is, Dynamics CRM ignores updates where the values don't actually change, so trying to update a value to itself is no-op.
public void Execute(IServiceProvider serviceProvider)
{
IPluginExecutionContext context = serviceProvider.GetService(typeof(IPluginExecutionContext));
Entity entity = (Entity)context.InputParameters["Target"];
string[] fields = new string[] { "name", "statecode", "address1_line1" };
bool hasUpdates = fields.Where(f => entity.Attributes.Contains(f)).Any();
if (!hasUpdates)
{
return;
}
}
I've got a situation where I want end-users to be able to create new Sitecore items... and then immediately be able to navigate to the Item's URL. Obviously the item will have to be published... but this happens in something of a black box. Is there a way to guarantee an item has been published from Master to Web?
Alternately, I could create the Item in the Web DB... then re-create/copy a Master version at some point. But this strategy seems fraught with peril. And maybe just a bad idea in general.
Suggestions? Am I being needlessly paranoid about creating items directly in Web?
I'll start by saying my answer is not necessarily advisable. However, depending on your situation it should work.
If the items that users are creating always have the same template you could try creating a custom item resolver that falls back to using the Master database.
Allow Sitecore to attempt to resolve the item normally.
When it fails, look in the Master database.
If the item is in there, make sure it has the correct template
Set the found item as the context item.
Using this method, you can publish the items from Master->Web s normal, but you don't have to wait until publishing is completed to see it.
Once again, this should solve the problem, but it's up to you to weigh the risks of serving up Master DB content.
You can't "guarantee" because publishing may be queued and won't go live instantly. Instead if you need instant access, I recommend a preview site that points to the master database:
How to Setup a Sitecore Preview Site to Review Content Before Publishing
You could create a event mapping to a class with the code to publish the item. In the code you can define any rule you want regarnding whether to publish or not.
<event name="item:saved">
<handler type="YourType.ItemEventHandler, YourType" method="OnItemSaved" />
</event>
And the OnItemSaved would look like this: (not tested)
protected void OnItemSaved(object sender, EventArgs args)
{
if (args == null)
{
return;
}
Item item = Event.ExtractParameter(args, 0) as Item;
var webDb = Sitecore.Configuration.Factory.GetDatabase("web");
var masterDb = Sitecore.Configuration.Factory.GetDatabase("master");
foreach (Language language in masterDb.Languages)
{
var options = new PublishOptions(masterDb, webDb, PublishMode.SingleItem, language, DateTime.Now)
{ RootItem = item, Deep = true };
var myPublisher = new Publisher(options);
myPublisher.Publish();
}
}
And about creating the item in the web db, I also wouldn`t go that way. It would be replaced by the default publishing process unexpectedly.
Personally i don't like front-end user creating items in master database, i feel only content authors/editors should be the ones who create items from either content editor or page editor.
There is no guarantee the item gets published instantly, I would recommend you to store any user-created data in a separate database and on the redirect URL just read the data from this database.
Sitecore workbox does not create a new version hence it does not track the change set. (Workbox being used by staff people, admin needs to track these changes.)
According to what I have noticed, When the item is not in the final workflow state, Sitecore allows to override the content, but if the item is in the final workflow state, it will create a new version, which tracks all these changes.
Is it possible to create a new version for non final workflow states? Is it a good idea? Why Sitecore does not do this by default?
The behavior you described is what documentation says. New version of item is created only when item is in final workflow state and
The next time a content author clicks Edit for this item to lock it
before making changes, Sitecore automatically creates a new version of
the item and places the new version in the Draft state, while the
first version remains published.
There is also important information:
Make sure that content authors or other workflow users don't have a
Sitecore administrator account. Otherwise, the workflow will behave
differently. For more information about why the workflow behavior is
different for a Sitecore administrator, see the section Using a
Workflow.
According to workflow reference documentation you can use __OnSave command to create new version of item when a user saves changes to an item.
Use the /sitecore/templates/System/Workflow/Action template to create custom action.
Create a class that implement your desired behavior.
namespace OnAction
{
public class WorkflowAction
{
public void Process(WorkflowPipelineArgs args)
{
}
}
}
Here is example of creating new item version:
var language = Sitecore.Globalization.Language.Parse("en");
var item = master.GetItem(itemPath, language);
using (new Sitecore.SecurityModel.SecurityDisabler())
{
try
{
item .Versions.AddVersion();
item .Editing.BeginEdit();
....
item .Editing.EndEdit();
item .Editing.AcceptChanges();
}
catch (Exception ex)
{
item .Editing.CancelEdit();
}
}
More information about creating custom action here. Link to workflow reference.