Thursday, July 22, 2010
File Download Dialog Box for Sitecore Media Item
You can do pretty sick things with our MediaRequestHandler (as an example of that, check out what Alistair Deneys done with it in the past).
Today, however, I wanted to cover a fairly easy aspect of this functionality.
Sunday, December 02, 2007
Cannot upload big files on IIS7
Wednesday, October 17, 2007
Publish related media items
Often users are curious why when they publish articles, the media associated with this article was not published.
There is one simple explanation - media items/assets in Sitecore are considered as separate content items and should be published separately.
Thanks to the powerful Sitecore Workflow engine that can be easily extended using workflow actions, it is possible to publish related media items by means of a special workflow action.
So by simply adding a workflow action before the Auto Publish action with the logic below, you will ensure that the relations will be published before the actual item:
The code of the workflow action:
using System;
using Sitecore;
using Sitecore.Configuration;
using Sitecore.Data.Items;
using Sitecore.Links;
using Sitecore.Publishing;
using Sitecore.Workflows.Simple;
namespace WebApp.Customizations
{
public class PublishRelationsAction
{
public void Process(WorkflowPipelineArgs args)
{
Item dataItem = args.DataItem;
// Find all related items
ItemLink[] itemLinks = dataItem.Links.GetValidLinks();
foreach (ItemLink link in itemLinks)
{
Item itm = link.GetTargetItem();
// publishing related media items - the ones that were referenced by the workflow item
// this can be extended - you can publish related aliases also
if (itm != null && itm.Paths.IsMediaItem)
{
PublishItem(itm);
}
}
}
private void PublishItem(Item item)
{
PublishOptions options = new PublishOptions(PublishMode.SingleItem, item.Language, DateTime.Now);
options.RootItem = item;
options.Deep = false;
options.SourceDatabase = item.Database;
// publishing to the web database
// production scenarios may have different publishing targets
// this can be handled by some more advanced logic,
// for example retrieving parameterized targets from the workflow action
options.TargetDatabase = Factory.GetDatabase("web");
new Publisher(options).Publish();
}
}
}
Related reading:
- http://sdn5.sitecore.net/Resources/Shared%20Source/Workflow/Workflow%20Actions.aspx
- http://sdn5.sitecore.net/Resources/Shared%20Source/Workflow.aspx
- http://sdn5.sitecore.net/FAQ/Workflow/Workflow%20State%20Action.aspx
- http://sdn5.sitecore.net/FAQ/API/Cause%20the%20workflow%20to%20invoke%20an%20action.aspx
The caveats:
- If media items are associated with another workflow, they should be in the final state.
- Obviously this solution works when you are using workflow. Other solutions such as handing of publish:end events does not seem to be as easy as workflow action. In this case it could be better to introduce a one step workflow with one initial state "Editing" and final "Published" with such action attached.
Thanks to Alexander Tsvirchkov for investigation and code and Kim Hornung for ideas.
Tuesday, July 17, 2007
Editing media files through the UI
This then the following approach can be used.
First of all, a special button should be added to the media tab. In order to do this, go to the core database -> and create a button under /sitecore/system/Ribbons/Contextual Ribbons/Media/Media/Media. The easiest way will be to duplicate the existing Download button and change the name to something more appropriate, e.g. "Edit File". Set the following properties:
- Header = Edit File
- Icon = Applications/16x16/contract.png
- Click = media:edit
- Tooltip = Edit the file.
The Click field is the most important. This value will connect the button with the execution logic.
Next step will be to define the "media:edit" command. Open the \app_config\Commands.config file and add something like:
<command name="media:edit" type="WebApp.Shell.Framework.Commands.Media.Edit,WebApp" />
This will tell Sitecore to look up the "WebApp.Shell.Framework.Commands.Media.Edit" class in the WebApp assembly from the bin folder.
So the only thing that is left to do is to compile the code that will execute an application to edit the file.
The code is represented below:
using Sitecore; using Sitecore.Data; using Sitecore.Data.Items; using Sitecore.Shell.Framework; using Sitecore.IO; using Sitecore.Text; using Sitecore.Shell.Framework.Commands;
namespace WebApp.Shell.Framework.Commands.Media { public class Edit : Command { public override void Execute(CommandContext context) { foreach (Item item in context.Items) { string filename = item["file path"]; if (FileUtil.FileExists(filename)) { UrlString url = new UrlString(); url.Append("fi", filename); if (filename.EndsWith(".xml", StringComparison.OrdinalIgnoreCase)) { Windows.RunApplication("Layouts/IDE", url.ToString()); return; } } } } } }
This is basically a class that inherits from the Command base class and contains one single method "Execute" that is fired whenever the button is clicked.
In the logic of this method we simply get the currently selected media item, get the physical path and check if this is an XML file. If it is, we execute the Developer Center application that allows us to edit and save the file. You can modify the logic to fit your needs.
This is how it looks like:
Note that this scenario deals with file system media storage. In case of database storage you will be able to download the media file from the blob field and reattach it to the same media item.
Friday, February 09, 2007
Get media path by file path
This code snippet applies to 5.1.1/5.2.
Here is the code snippet that does the job:
string fullPath = @"D:\wwwroot\Clean5.2.0.12\upload\images\Devil-Skype!.png";
// mapping the path
string mappedPath = Sitecore.Resources.Media.MediaPath.MapPath(fullPath);
// switching the context to shell
Sitecore.Context.SetActiveSite("shell");
// setting the actual media path
string mediaPath = Sitecore.Resources.Media.MediaPath.CreatePath(mappedPath).Paths.FullPath;
// next you may switch back to website
The site switch is necessary since the CreatePath method deals with the content database of the context site which is null for the website by default.
If you don’t want to change the site context, you should add the content database definition to the website:
<site
name="website"
...
content="master" or “web”
...
This way your code will look like:
string fullPath = @"D:\wwwroot\Clean5.2.0.12\upload\images\Devil-Skype!.png";
string mappedPath = Sitecore.Resources.Media.MediaPath.MapPath(fullPath);
string mediaPath = Sitecore.Resources.Media.MediaPath.CreatePath(mappedPath).Paths.FullPath;
Tuesday, December 12, 2006
Uploading media items from the front end
Why not? What if you want the extranet users to upload media to the master database? No problem with that! Just follow these easy steps to accomplish this.
Step 1: add a new pipeline to the <processors> section in the web.config:
<frontendUpload>
<processor mode="on" type="Sitecore.Pipelines.Upload.Save, Sitecore.Kernel" />
</frontendUpload>
Step 2: Add the FileUpload control to your layout (web form):
<asp:FileUpload ID="FileUpload1" runat="server" />
This control will be used to select a image for uploading.
Step3: in the code behind of a layout you should add the following code for example in the button click handler.
// defining if a file is being uploaded
if (FileUpload1.PostedFile != null)
{
// disabling security in order to create a media item
using (new Sitecore.SecurityModel.SecurityDisabler())
{
// creating necessary arguments to be passed to the processor
UploadArgs args = new UploadArgs();
// adding http files collection
args.Files = base.Request.Files;
// a media path where the media item will be created
args.Folder = "/sitecore/media library/Files";
// we may want to override existing media items
args.Overwrite = true;
// we do not need to choose this option since we are uploading images, not archives
args.Unpack = false;
// turning on versioning for the uploaded item
args.Versioned = true;
// selecting a language in which the media item will be created
args.Language = Sitecore.Globalization.Language.Parse("en");
// we are uploading to the database
args.Destination = UploadDestination.Database;
// if we are uploading to the master database, we need to change the active site
Sitecore.Context.SetActiveSite("shell");
// starting the pipeline previously added to web.config
PipelineFactory.GetPipeline("frontendUpload").Start(args);
// the media item is created. Now we can do whatever we want with the uploaded items
// for exampe, programmatically populate the Alt fields
foreach (Item itm in args.UploadedItems)
{
itm.Editing.BeginEdit();
itm.Fields["Alt"].Value = "Set from API";
itm.Editing.EndEdit();
}
// setting the active site back
Sitecore.Context.SetActiveSite("website");
}
}
else
{
Response.Write("No file is posted.");
}
