Content Picker does NOT work in Multitenant

Topics: Core, General, Localization, Troubleshooting, Writing modules
Apr 16, 2013 at 10:40 PM
Edited Apr 16, 2013 at 10:50 PM
Hi,

I am not getting the ContentItems in the ContentPicker when using multitenant. (I think that the tenants are making a query to the default site instead the current tenant.. )

Here is how i am generating the Content Items that i am not able to see in any of the tenants of the site when using a ContentPicker:
SchemaBuilder.CreateTable("SubProductPartRecord", table => table
               .ContentPartRecord()
               .Column<int>("ProductPartRecord_id")
            );

            //SubProduct
            ContentDefinitionManager.AlterPartDefinition("SubProductPart", builder => builder
               .Attachable()
               .WithField("SubProductName", cfg => cfg.OfType("TextField")
                   .WithDisplayName("Nombre")
                   .WithSetting("FieldIndexing.Included", true.ToString())
                   .WithSetting("TextFieldSettings.Required", true.ToString()))
              .WithField("SubProductDescription", cfg => cfg.OfType("TextField")
                   .WithDisplayName("Descripción")
                   .WithSetting("FieldIndexing.Included", true.ToString())
                   .WithSetting("TextFieldSettings.Required", true.ToString())
                   .WithSetting("TextFieldSettings.Flavor", "Html"))
              .WithField("SubProductImage", cfg => cfg.OfType("MediaPickerField")
                   .WithDisplayName("Imagen")
                   .WithSetting("MediaPickerFieldSettings.AllowedExtensions", "gif jpg jpeg png")
                   .WithSetting("MediaPickerFieldSettings.Required", true.ToString()))
               .WithField("SubProductFile", cfg => cfg.OfType("MediaPickerField")
                     .WithDisplayName("Ficha Técnica")
                     .WithSetting("MediaPickerFieldSettings.AllowedExtensions", "doc docx pdf txt zip rar")
                     .WithSetting("MediaPickerFieldSettings.Required", true.ToString()))
              );

            ContentDefinitionManager.AlterTypeDefinition("SubProduct", builder => builder
               .DisplayedAs("SubProductos")
               .WithPart("CommonPart")
               .WithPart("SubProductPart")
               .WithPart("LocalizationPart")
               .WithPart("IdentityPart")
               .Creatable()
               .Indexed());
This is how i am generating the Products that i want to link to a SubProduct using ContentPicker:
// Products
            SchemaBuilder.CreateTable("ProductPartRecord", table => table.ContentPartRecord());

            ContentDefinitionManager.AlterPartDefinition("ProductPart", builder => builder
                 .Attachable()
                 .WithField("ProductName", cfg => cfg.OfType("TextField")
                     .WithDisplayName("Nombre")
                     .WithSetting("FieldIndexing.Included", true.ToString())
                     .WithSetting("TextFieldSettings.Required", true.ToString()))
                .WithField("ProductType", cfg => cfg.OfType("EnumerationField")
                    .WithDisplayName("Tipo de producto")
                    .WithSetting("EnumerationFieldSettings.ListMode", "Dropdown")
                    .WithSetting("EnumerationFieldSettings.Options", productTypeOptions.ToString())
                    .WithSetting("EnumerationFieldSettings.Required", true.ToString()))
                .WithField("ProductDescription", cfg => cfg.OfType("TextField")
                     .WithDisplayName("Descripción")
                     .WithSetting("FieldIndexing.Included", true.ToString())
                     .WithSetting("TextFieldSettings.Required", true.ToString())
                     .WithSetting("TextFieldSettings.Flavor", "Html"))
                .WithField("ProductImage", cfg => cfg.OfType("MediaPickerField")
                     .WithDisplayName("Imagen")
                     .WithSetting("MediaPickerFieldSettings.AllowedExtensions", "gif jpg jpeg png")
                     .WithSetting("MediaPickerFieldSettings.Required", true.ToString()))
                .WithField("ProductSubProductList", cfg => cfg.OfType("ContentPickerField")
                     .WithDisplayName("Sub Productos")
                     .WithSetting("ContentPickerFieldSettings.Required", false.ToString())
                     .WithSetting("ContentPickerFieldSettings.Multiple", true.ToString()))
                );

            ContentDefinitionManager.AlterTypeDefinition("Product", builder => builder
               .DisplayedAs("Productos")
               .WithPart("CommonPart")
               .WithPart("ProductPart")
               .WithPart("LocalizationPart")
               .WithPart("IdentityPart")
               .Creatable()
               .Indexed());
Now, to understand better what is happening in my application i will add some screen shots and some links!!

Creating a SubProduct
Image


Verifying things!
Image


Creating a Product
Image


Adding a SubProduct to a Product using Orchard.ContentPicker
Image


Watching what's happening in the ContentPicker Module
Image


Verifying things in backend!
Image

and more...

Watching the database!!
Image

So, what do you think?

It is something wrong with the ContentPicker Module? is it the popup window?
Or it is related to localization? I also removed the localization part, and SubProductPart of the SubProduct Content Item and it behaves the same way!!!

Someone here knows what is happening?

Thx a lot!!
Coordinator
Apr 17, 2013 at 5:29 AM
Seems like you have some pretty good repro steps. You should probably file a bug.
Apr 22, 2013 at 11:03 PM
Edited Apr 22, 2013 at 11:04 PM
I found and fixed the bug thx to Sebastien, i hope they include the fix on the next release.

There was an issue with the baseUrl.

The solution is to replace the content of this file ContentPicker.Edit.cshtml with:
@model MediaGalleryFieldViewModel
@using Orchard.Environment.Configuration
@using Orchard.Fields.Settings;

@{
    Style.Include("media-gallery-admin");
    Script.Require("jQueryUI_Sortable").AtFoot();
    
    var settings = Model.Field.PartFieldDefinition.Settings.GetModel<MediaGalleryFieldSettings>();
    var descriminator = Html.FieldIdFor(m => m.Field.Items);

    var baseUrl = Url.Content("~/") + WorkContext.Resolve<ShellSettings>().RequestUrlPrefix;
}

<fieldset>
    <label @if(settings.Required) { <text>class="required"</text> }>@Model.Field.DisplayName</label>
    <span class="hint">@settings.Hint</span>

    <div id="save-message-@descriminator" class="message message-Warning media-gallery-message">@T("You need to save your changes.")</div>
    <table id="media-gallery-@descriminator" class="items media-gallery" summary="@Model.Field.DisplayName">
        <colgroup>
            <col id="Col1" style="width:20px" />
            <col id="Col2" />
            <col id="Col3" />
        </colgroup>
        <thead>
            <tr>
                <th scope="col" >&nbsp;&darr;</th>
                <th scope="col">@T("Media")</th>
                <th scope="col">&nbsp;</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var media in Model.Items) {
                <tr>
                    <td>&nbsp;</td>
                    <td>
                        <span data-url="@media.Url" data-alt="@media.AlternateText" data-class="@media.Class" data-style="@media.Style" data-align="@media.Alignment" data-width="@media.Width" data-height="@media.Height" data-fieldid="@descriminator" class="media-gallery-item"><a title="@T("Edit")" class="media-gallery-edit" href="#">@media.Url</a></span>
                    </td>
                    <td>
                        <span data-url="@media.Url" class="media-gallery-remove button grey">@T("Remove")</span>
                    </td>
                </tr>
            }
        </tbody>
    </table>

    <span id="btn-@descriminator" class="button">@T("Add")</span>
    
    @Html.HiddenFor(m => m.SelectedItems)
</fieldset>

@using (Script.Foot()) {
<script type="text/javascript">
//<![CDATA[

    (function($) {

        var required = @(settings.Required ? "true" : "false");
        var multiple = @(settings.Multiple ? "true" : "false");
        var addButton = $('#btn-@descriminator');
        var @(descriminator)_Template = '<tr><td>&nbsp;</td><td><span data-url="{url}" data-alt="{alt}" data-class="{class}" data-style="{style}" data-align="{align}" data-width="{width}" data-height="{height}" data-fieldid="@descriminator" class="media-gallery-item"><a title="@T("Edit")" class="media-gallery-edit" href="#">{url}</a></span></td><td><span class="media-gallery-remove button grey">@T("Remove")</span></td></tr>';
        
        var refreshIds = function() {
            var id = $('#@Html.FieldIdFor(m => m.SelectedItems)');
            var selectedItems = [];
            $("span[data-fieldid = @descriminator]").each(function() {
                selectedItems.push(extractModel(this));
            });

            id.val(JSON.stringify(selectedItems));
            
            // can new items be added ?
            if(!multiple && selectedItems.length > 0) {
                addButton.hide();    
            }
            else {
                addButton.show();
            }
        };

        refreshIds();
        
        // adding a new item
        addButton.click(function() {
            addButton.trigger("orchard-admin-pickimage-open", {
                callback: function(data) {
                    
                    var template = @(descriminator)_Template
                        .replace( /\{url\}/g , formatUrl(data.img.src))
                        .replace( /\{alt\}/g , data.img.alt)
                        .replace( /\{class\}/g , data.img['class'])
                        .replace( /\{style\}/g , data.img.style)
                        .replace( /\{align\}/g , data.img.align)
                        .replace( /\{width\}/g , data.img.width || '0')
                        .replace( /\{height\}/g , data.img.height || '0');
                    
                    var content = $(template);
                    $('#media-gallery-@descriminator tbody').append(content);

                    refreshIds();
                    $('#save-message-@descriminator').show();
                },
                baseUrl: '@baseUrl'
            });
        });

        // editing an item
        $(".items.media-gallery").on("click", ".media-gallery-edit", function() {
            var img = extractModel($(this).parent());
            if (img.Url && img.Url.length > 2 && img.Url.substr(0, 2) == "~/") {
                img.Url = '@baseUrl' + img.Url.substr(2);
            }

            var tr = $(this).closest('tr');
            
            $(this).trigger("orchard-admin-pickimage-open", {
                img: {
                    src: img.Url,
                    alt: img.AlternateText,
                    'class': img.Class,
                    style: img.Style,
                    align: img.Alignment,
                    width: img.Width,
                    height: img.Height
                },
                baseUrl: '@baseUrl',
                //uploadMediaPath: 'images',
                callback: function (data) {
                    
                    var template = @(descriminator)_Template
                         .replace( /\{url\}/g , formatUrl(data.img.src))
                         .replace( /\{alt\}/g , data.img.alt)
                         .replace( /\{class\}/g , data.img['class'])
                         .replace( /\{style\}/g , data.img.style)
                         .replace( /\{align\}/g , data.img.align)
                         .replace( /\{width\}/g , data.img.width || '0')
                         .replace( /\{height\}/g , data.img.height || '0');
                    
                    var content = $(template);
                    tr.after(content);
                    tr.remove();

                    refreshIds();
                    $('#save-message-@descriminator').show();
                }
            });
        });
        
        $('#media-gallery-@descriminator').on("click", ".media-gallery-remove", function() {
            $(this).closest('tr').remove();
            refreshIds();
            $('#save-message-@descriminator').show();
        });
            
        $("#media-gallery-@descriminator tbody").sortable({
            handle: 'td:first',
            stop: function(event, ui) {
                refreshIds();
                $('#save-message-@descriminator').show();
            }
        }).disableSelection();
        
        function formatUrl(url) {
            var applicationPath = '@HttpUtility.JavaScriptStringEncode(Url.RequestContext.HttpContext.Request.ApplicationPath.ToLower())';
        
            if (!/\/$/.test(applicationPath)) {
                applicationPath += '/';
            }
        
            if (url.substr(0, 4) != "http") {
                return '~/' + url.substr(applicationPath.length);
            }

            return url;
        }
        
        function extractModel(dom) {
            dom = $(dom);

            return {
                Url: dom.data('url'),
                AlternateText: dom.data('alt'),
                Class: dom.data('class'),
                Style: dom.data('style'),
                Alignment: dom.data('align'),
                Height: dom.data('height'),
                Width: dom.data('width')
            };
        }
        

    })(jQuery);
//]]>
</script>
}