xml-rpcorchardcms-1.7windows-live-writermetaweblog

How to change Orchard CMS default image folder path


I have Orchard CMS setup and working correctly. When using windows live writer to create pages it maps images to a folder like /Media/Default/WindowsLiveWriter folder

Eg. /Media/Default/WindowsLiveWriter/testpost-title_12A72/sample_image_2.jpg

I don't want my urls to have technology specific sections like "WindowsLiveWriter"

1) How can I customize this in Orchard 1.7 code. I want to have an image url structure like

/Media/Default/2014/March/02/sample_image_2.jpg or /Media/Default/MyBlog/testpost-title_12A72/sample_image_2.jpg

2) Is there an option in live writer to specify the folder on which the images should be dropped? E.g. use date as a sub folder?

3) Can I change the meta data live writer receive to tell it where my image folder is?

I searched the entire Orchard 1.7 code base for a string WindowsLiveWriter (which is part of the url) but couldn't find it.


Solution

  • Change the file \src\Orchard.Web\Modules\Orchard.MediaLibrary\Services\XmlRpcHandler.cs

    as follows. There is a method called

    private XRpcStruct MetaWeblogNewMediaObject(
                    string userName,
                    string password,
                    XRpcStruct file,
                    UrlHelper url){
    
            }
    

    Inside that change the name of the file at the beginning before response being sent to MS word blog template for live writer.

        var name = file.Optional<string>("name");
        name = Path.GetFileName(name);
        name = "images/"+DateTime.Now.Year+"/"+DateTime.Now.Month+"/" + name;
    

    The complete method now looks like

       public void Process(XmlRpcContext context) {
            var urlHelper = new UrlHelper(context.ControllerContext.RequestContext, _routeCollection);
    
        if (context.Request.MethodName == "metaWeblog.newMediaObject") {
            var result = MetaWeblogNewMediaObject(
                Convert.ToString(context.Request.Params[1].Value),
                Convert.ToString(context.Request.Params[2].Value),
                (XRpcStruct)context.Request.Params[3].Value,
                urlHelper);
            context.Response = new XRpcMethodResponse().Add(result);
        }
    }
    
    private XRpcStruct MetaWeblogNewMediaObject(
        string userName,
        string password,
        XRpcStruct file,
        UrlHelper url) {
    
        var user = _membershipService.ValidateUser(userName, password);
        if (!_authorizationService.TryCheckAccess(Permissions.ManageMediaContent, user, null)) {
            throw new OrchardCoreException(T("Access denied"));
        }
    
        var name = file.Optional<string>("name");
    
        name = Path.GetFileName(name);
        name = "images/"+DateTime.Now.Year+"/"+DateTime.Now.Month+"/" + name;
    
        var bits = file.Optional<byte[]>("bits");
    
        string directoryName = Path.GetDirectoryName(name);
        if (string.IsNullOrWhiteSpace(directoryName)) { // Some clients only pass in a name path that does not contain a directory component.
            directoryName = "media";
        }
    
        try {
            // delete the file if it already exists, e.g. an updated image in a blog post
            // it's safe to delete the file as each content item gets a specific folder
            _mediaLibraryService.DeleteFile(directoryName, Path.GetFileName(name));
        }
        catch {
            // current way to delete a file if it exists
        }
    
        string publicUrl = _mediaLibraryService.UploadMediaFile(directoryName, Path.GetFileName(name), bits);
        _mediaLibraryService.ImportMedia(directoryName, Path.GetFileName(name));
        return new XRpcStruct() // Some clients require all optional attributes to be declared Wordpress responds in this way as well.
            .Set("file", publicUrl)
            .Set("url", url.MakeAbsolute(publicUrl))
            .Set("type", file.Optional<string>("type"));
    }