Beispiel #1
0
        public virtual RenderingResult BeginRenderLink <T>(T model, Expression <Func <T, object> > field, TextWriter writer, object parameters = null, bool isEditable = false)
        {
            NameValueCollection attrs;

            if (parameters is NameValueCollection)
            {
                attrs = parameters as NameValueCollection;
            }
            else
            {
                attrs = Utilities.GetPropertiesCollection(parameters, true);
            }

            if (IsInEditingMode && isEditable)
            {
                if (attrs != null)
                {
                    attrs.Add("haschildren", "true");
                    return(MakeEditable(field, null, model, attrs, _context, SitecoreContext.Database, writer));
                }
                return(MakeEditable(field, null, model, "haschildren=true", _context, SitecoreContext.Database, writer));
            }
            else
            {
                return(BeginRenderLink(field.Compile().Invoke(model) as Fields.Link, attrs, string.Empty, writer));
            }
        }
Beispiel #2
0
        /// <summary>
        /// Render HTML for a link
        /// </summary>
        /// <param name="link">The link to render</param>
        /// <param name="model">The model containing the link</param>
        /// <param name="field">An expression that points to the link</param>
        /// <param name="attributes">A collection of parameters to added to the link</param>
        /// <param name="isEditable">Indicate if the link should be editable in the page editor</param>
        /// <param name="contents">Content to go in the link</param>
        /// <returns>An "a" HTML element</returns>
        public virtual string RenderLink <T>(T model, Expression <Func <T, object> > field, object attributes = null, bool isEditable = false, string contents = null)
        {
            NameValueCollection attrs = null;

            if (attributes is NameValueCollection)
            {
                attrs = attributes as NameValueCollection;
            }
            else
            {
                attrs = Utilities.GetPropertiesCollection(attributes, true);
            }

            var sb        = new StringBuilder();
            var writer    = new StringWriter(sb);
            var linkField = field.Compile().Invoke(model) as Fields.Link;

            RenderingResult result = null;

            if (IsInEditingMode && isEditable)
            {
                if (!string.IsNullOrEmpty(contents))
                {
                    attrs["haschildren"] = "true";
                }
                if (contents.IsNotNullOrEmpty())
                {
                    attrs.Add("haschildren", "true");
                }

                if (linkField != null)
                {
                    AttributeCheck(attrs, "class", linkField.Class);
                    AttributeCheck(attrs, "title", linkField.Title);
                }

                result = MakeEditable(
                    field,
                    null,
                    model,
                    Utilities.ConstructQueryString(attrs),
                    _context, SitecoreContext.Database, writer);

                if (contents.IsNotNullOrEmpty())
                {
                    sb.Append(contents);
                }
            }
            else
            {
                result = BeginRenderLink(
                    GetCompiled(field).Invoke(model) as Fields.Link, attrs, contents, writer
                    );
            }

            result.Dispose();
            writer.Flush();
            writer.Close();
            return(sb.ToString());
        }
Beispiel #3
0
        /// <summary>
        /// Renders an image allowing simple page editor support
        /// </summary>
        /// <typeparam name="T">The model type</typeparam>
        /// <param name="model">The model that contains the image field</param>
        /// <param name="field">A lambda expression to the image field, should be of type Glass.Mapper.Sc.Fields.Image</param>
        /// <param name="parameters">Image parameters, e.g. width, height</param>
        /// <param name="isEditable">Indicates if the field should be editable</param>
        /// <returns></returns>
        public virtual string RenderImage <T>(T model,
                                              Expression <Func <T, object> > field,
                                              object parameters = null,
                                              bool isEditable   = false)
        {
            if (parameters is ImageParameters)
            {
                var imageParameters = parameters as ImageParameters;
                if (IsInEditingMode && isEditable)
                {
                    return(Editable(model, field, imageParameters));
                }
                else
                {
                    return(RenderImage(field.Compile().Invoke(model) as Fields.Image, parameters == null ? null : imageParameters.Parameters));
                }
            }
            else
            {
                var attrs = Utilities.GetPropertiesCollection(parameters, true);

                if (IsInEditingMode && isEditable)
                {
                    var url = new UrlString();
                    url.Parameters.Add(attrs);
                    return(Editable(model, field, url.Query));
                }
                else
                {
                    return(RenderImage(field.Compile().Invoke(model) as Fields.Image, parameters == null ? null : attrs));
                }
            }
        }
Beispiel #4
0
        /// <summary>
        /// Renders an image allowing simple page editor support
        /// </summary>
        /// <typeparam name="T">The model type</typeparam>
        /// <param name="model">The model that contains the image field</param>
        /// <param name="field">A lambda expression to the image field, should be of type Glass.Mapper.Sc.Fields.Image</param>
        /// <param name="parameters">Image parameters, e.g. width, height</param>
        /// <param name="isEditable">Indicates if the field should be editable</param>
        /// <param name="outputHeightWidth">Indicates if the height and width attributes should be output when rendering the image</param>
        /// <returns></returns>
        public virtual string RenderImage <T>(T model,
                                              Expression <Func <T, object> > field,
                                              object parameters      = null,
                                              bool isEditable        = false,
                                              bool outputHeightWidth = false)
        {
            var attrs = Utilities.GetPropertiesCollection(parameters, true).ToSafeDictionary();

            if (IsInEditingMode && isEditable)
            {
                var url = new UrlString();
                foreach (var pair in attrs)
                {
                    url.Parameters.Add(pair.Key, pair.Value);
                }
                if (!outputHeightWidth)
                {
                    url.Parameters.Add("width", "-1");
                    url.Parameters.Add("height", "-1");
                }

                return(Editable(model, field, url.Query));
            }
            else
            {
                return(RenderImage(GetCompiled(field).Invoke(model) as Image, parameters == null ? null : attrs, outputHeightWidth));
            }
        }
        protected SafeDictionary <string> ProcessParameters(object parameters)
        {
            string parametersStringTemp = string.Empty;

            SafeDictionary <string> dictionary = new SafeDictionary <string>();

            if (parameters == null)
            {
                parametersStringTemp = string.Empty;
            }
            else if (parameters is string)
            {
                parametersStringTemp = parameters as string;
                dictionary           = WebUtil.ParseQueryString(parametersStringTemp ?? string.Empty);
            }
            else if (parameters is NameValueCollection)
            {
                var collection = (NameValueCollection)parameters;
                foreach (var key in collection.AllKeys)
                {
                    dictionary.Add(key, collection[key]);
                }
            }
            else
            {
                var collection = Utilities.GetPropertiesCollection(parameters, true);
                foreach (var key in collection.AllKeys)
                {
                    dictionary.Add(key, collection[key]);
                }
            }

            return(dictionary);
        }
Beispiel #6
0
        public virtual RenderingResult BeginRenderLink <T>(T model, Expression <Func <T, object> > field, TextWriter writer, object parameters = null, bool isEditable = false, bool alwaysRender = false, string aElementTemplate = LinkTagFormat)
        {
            NameValueCollection attrs;

            if (parameters is NameValueCollection)
            {
                attrs = parameters as NameValueCollection;
            }
            else
            {
                attrs = Utilities.GetPropertiesCollection(parameters, true);
            }

            if (IsInEditingMode && isEditable)
            {
                if (attrs != null)
                {
                    attrs.Add("haschildren", "true");
                    return(MakeEditable(field, null, model, attrs, _context, SitecoreService.Database, writer));
                }
                return(MakeEditable(field, null, model, "haschildren=true", _context, SitecoreService.Database, writer));
            }
            else
            {
                return(BeginRenderLink(GetCompiled(field).Invoke(model) as Link, attrs.ToSafeDictionary(), string.Empty, writer, alwaysRender, aElementTemplate));
            }
        }
Beispiel #7
0
        /// <summary>
        /// Render HTML for a link
        /// </summary>
        /// <param name="model">The model containing the link</param>
        /// <param name="field">An expression that points to the link</param>
        /// <param name="attributes">A collection of parameters to added to the link</param>
        /// <param name="isEditable">Indicate if the link should be editable in the page editor</param>
        /// <param name="contents">Content to go in the link</param>
        /// <param name="alwaysRender">Renders an A element even if the link is null</param>
        /// <returns>An "a" HTML element</returns>
        public virtual string RenderLink <T>(
            T model,
            Expression <Func <T, object> > field,
            object attributes       = null,
            bool isEditable         = false,
            string contents         = null,
            bool alwaysRender       = false,
            string aElementTemplate = LinkTagFormat)
        {
            NameValueCollection attrs;

            if (attributes is NameValueCollection)
            {
                attrs = attributes as NameValueCollection;
            }
            else
            {
                attrs = Utilities.GetPropertiesCollection(attributes, true);
            }

            var sb     = new StringBuilder();
            var writer = new StringWriter(sb);

            RenderingResult result;

            if (IsInEditingMode && isEditable)
            {
                if (contents.HasValue())
                {
                    attrs.Add("haschildren", "true");
                    attrs.Add("text", contents);
                }

                result = MakeEditable(
                    field,
                    null,
                    model,
                    attrs,
                    _context, SitecoreService.Database, writer);

                if (contents.HasValue())
                {
                    sb.Append(contents);
                }
            }
            else
            {
                result = BeginRenderLink(
                    GetCompiled(field).Invoke(model) as Link, attrs.ToSafeDictionary(), contents, writer, alwaysRender, aElementTemplate
                    );
            }

            result.Dispose();
            writer.Flush();
            writer.Close();
            return(sb.ToString());
        }
        /// <summary>
        /// Render HTML for a link
        /// </summary>
        /// <param name="link">The link to render</param>
        /// <param name="model">The model containing the link</param>
        /// <param name="field">An expression that points to the link</param>
        /// <param name="attributes">A collection of parameters to added to the link</param>
        /// <param name="isEditable">Indicate if the link should be editable in the page editor</param>
        /// <param name="contents">Content to go in the link</param>
        /// <returns>An "a" HTML element</returns>
        public virtual string RenderLink <T>(T model, Expression <Func <T, object> > field, object attributes = null, bool isEditable = false, string contents = null)
        {
            NameValueCollection attrs = null;

            if (attributes is NameValueCollection)
            {
                attrs = attributes as NameValueCollection;
            }
            else
            {
                attrs = Utilities.GetPropertiesCollection(attributes, true);
            }

            var sb     = new StringBuilder();
            var writer = new StringWriter(sb);

            RenderingResult result = null;

            if (IsInEditingMode && isEditable)
            {
                result = MakeEditable(
                    field,
                    null,
                    model,
                    contents == null ? string.Empty: "haschildren=true",
                    _context, SitecoreContext.Database, writer);
            }
            else
            {
                result = BeginRenderLink(
                    field.Compile().Invoke(model) as Fields.Link, attrs, contents, writer
                    );
            }

            result.Dispose();
            writer.Flush();
            writer.Close();
            return(sb.ToString());
        }
Beispiel #9
0
        /// <summary>
        /// Makes the editable.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="field">The field.</param>
        /// <param name="standardOutput">The standard output.</param>
        /// <param name="model">The model.</param>
        /// <param name="parameters">The parameters.</param>
        /// <returns>System.String.</returns>
        /// <exception cref="Glass.Mapper.MapperException">
        /// To many parameters in linq expression {0}.Formatted(field.Body)
        /// or
        /// Expression doesn't evaluate to a member {0}.Formatted(field.Body)
        /// or
        /// Page editting error. Could not find property {0} on type {1}.Formatted(memberExpression.Member.Name, config.Type.FullName)
        /// or
        /// Page editting error. Could not find data handler for property {2} {0}.{1}.Formatted(
        ///                         prop.DeclaringType, prop.Name, prop.MemberType)
        /// </exception>
        /// <exception cref="System.NullReferenceException">Context cannot be null</exception>
        private RenderingResult MakeEditable <T>(
            Expression <Func <T, object> > field,
            Expression <Func <T, string> > standardOutput,
            T model,
            object parameters,
            Context context, Database database,
            TextWriter writer)
        {
            string firstPart = string.Empty;
            string lastPart  = string.Empty;

            try
            {
                if (field == null)
                {
                    throw new NullReferenceException("No field set");
                }
                if (model == null)
                {
                    throw new NullReferenceException("No model set");
                }

                string parametersStringTemp = string.Empty;

                SafeDictionary <string> dictionary = new SafeDictionary <string>();

                if (parameters == null)
                {
                    parametersStringTemp = string.Empty;
                }
                else if (parameters is string)
                {
                    parametersStringTemp = parameters as string;
                    dictionary           = WebUtil.ParseQueryString(parametersStringTemp ?? string.Empty);
                }
                else if (parameters is NameValueCollection)
                {
                    var collection = (NameValueCollection)parameters;
                    foreach (var key in collection.AllKeys)
                    {
                        dictionary.Add(key, collection[key]);
                    }
                }
                else
                {
                    var collection = Utilities.GetPropertiesCollection(parameters, true);
                    foreach (var key in collection.AllKeys)
                    {
                        dictionary.Add(key, collection[key]);
                    }
                }


                if (IsInEditingMode)
                {
                    if (field.Parameters.Count > 1)
                    {
                        throw new MapperException("To many parameters in linq expression {0}".Formatted(field.Body));
                    }

                    MemberExpression memberExpression;

                    if (field.Body is UnaryExpression)
                    {
                        memberExpression = ((UnaryExpression)field.Body).Operand as MemberExpression;
                    }
                    else if (!(field.Body is MemberExpression))
                    {
                        throw new MapperException("Expression doesn't evaluate to a member {0}".Formatted(field.Body));
                    }
                    else
                    {
                        memberExpression = (MemberExpression)field.Body;
                    }



                    //we have to deconstruct the lambda expression to find the
                    //correct model object
                    //For example if we have the lambda expression x =>x.Children.First().Content
                    //we have to evaluate what the first Child object is, then evaluate the field to edit from there.

                    //this contains the expression that will evaluate to the object containing the property
                    var objectExpression = memberExpression.Expression;

                    var finalTarget =
                        Expression.Lambda(objectExpression, field.Parameters).Compile().DynamicInvoke(model);

                    var site = global::Sitecore.Context.Site;

                    if (context == null)
                    {
                        throw new NullReferenceException("Context cannot be null");
                    }

                    var config = context.GetTypeConfiguration <SitecoreTypeConfiguration>(finalTarget);



                    var scClass = config.ResolveItem(finalTarget, database);

                    //lambda expression does not always return expected memberinfo when inheriting
                    //c.f. http://stackoverflow.com/questions/6658669/lambda-expression-not-returning-expected-memberinfo
                    var prop = config.Type.GetProperty(memberExpression.Member.Name);

                    //interfaces don't deal with inherited properties well
                    if (prop == null && config.Type.IsInterface)
                    {
                        Func <Type, PropertyInfo> interfaceCheck = null;
                        interfaceCheck = (inter) =>
                        {
                            var interfaces = inter.GetInterfaces();
                            var properties =
                                interfaces.Select(x => x.GetProperty(memberExpression.Member.Name)).Where(
                                    x => x != null);
                            if (properties.Any())
                            {
                                return(properties.First());
                            }
                            else
                            {
                                return(interfaces.Select(x => interfaceCheck(x)).FirstOrDefault(x => x != null));
                            }
                        };
                        prop = interfaceCheck(config.Type);
                    }

                    if (prop != null && prop.DeclaringType != prop.ReflectedType)
                    {
                        //properties mapped in data handlers are based on declaring type when field is inherited, make sure we match
                        prop = prop.DeclaringType.GetProperty(prop.Name);
                    }

                    if (prop == null)
                    {
                        throw new MapperException(
                                  "Page editting error. Could not find property {0} on type {1}".Formatted(
                                      memberExpression.Member.Name, config.Type.FullName));
                    }

                    //ME - changed this to work by name because properties on interfaces do not show up as declared types.
                    var dataHandler = config.Properties.FirstOrDefault(x => x.PropertyInfo.Name == prop.Name);
                    if (dataHandler == null)
                    {
                        throw new MapperException(
                                  "Page editing error. Could not find data handler for property {2} {0}.{1}".Formatted(
                                      prop.DeclaringType, prop.Name, prop.MemberType));
                    }



                    using (new ContextItemSwitcher(scClass))
                    {
                        RenderFieldArgs renderFieldArgs = new RenderFieldArgs();
                        renderFieldArgs.Item = scClass;

                        var fieldConfig = (SitecoreFieldConfiguration)dataHandler;
                        if (fieldConfig.FieldId != (Sitecore.Data.ID)null && fieldConfig.FieldId != ID.Null)
                        {
                            renderFieldArgs.FieldName = fieldConfig.FieldId.ToString();
                        }
                        else
                        {
                            renderFieldArgs.FieldName = fieldConfig.FieldName;
                        }

                        renderFieldArgs.Parameters     = dictionary;
                        renderFieldArgs.DisableWebEdit = false;

                        CorePipeline.Run("renderField", (PipelineArgs)renderFieldArgs);

                        firstPart = renderFieldArgs.Result.FirstPart;
                        lastPart  = renderFieldArgs.Result.LastPart;
                    }
                }
                else
                {
                    if (standardOutput != null)
                    {
                        firstPart = GetCompiled <T>(standardOutput)(model).ToString();
                    }
                    else
                    {
                        var    type   = field.Body.Type;
                        object target = (GetCompiled <T>(field)(model) ?? string.Empty);

                        if (type == ImageType)
                        {
                            var image = target as Image;
                            firstPart = RenderImage(image, dictionary);
                        }
                        else if (type == LinkType)
                        {
                            var link       = target as Link;
                            var sb         = new StringBuilder();
                            var linkWriter = new StringWriter(sb);
                            var result     = BeginRenderLink(link, dictionary, null, linkWriter);
                            result.Dispose();
                            linkWriter.Flush();
                            linkWriter.Close();

                            firstPart = sb.ToString();
                        }
                        else
                        {
                            firstPart = target.ToString();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                firstPart = "<p>{0}</p><pre>{1}</pre>".Formatted(ex.Message, ex.StackTrace);
                Sitecore.Diagnostics.Log.Error("Failed to render field", ex, typeof(IGlassHtml));
            }

            return(new RenderingResult(writer, firstPart, lastPart));


            //return field.Compile().Invoke(model).ToString();
        }
Beispiel #10
0
        /// <summary>
        /// Makes the editable.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="field">The field.</param>
        /// <param name="standardOutput">The standard output.</param>
        /// <param name="model">The model.</param>
        /// <param name="parameters">The parameters.</param>
        /// <returns>System.String.</returns>
        /// <exception cref="Glass.Mapper.MapperException">
        /// To many parameters in linq expression {0}.Formatted(field.Body)
        /// or
        /// Expression doesn't evaluate to a member {0}.Formatted(field.Body)
        /// or
        /// Page editting error. Could not find property {0} on type {1}.Formatted(memberExpression.Member.Name, config.Type.FullName)
        /// or
        /// Page editting error. Could not find data handler for property {2} {0}.{1}.Formatted(
        ///                         prop.DeclaringType, prop.Name, prop.MemberType)
        /// </exception>
        /// <exception cref="System.NullReferenceException">Context cannot be null</exception>
        private RenderingResult MakeEditable <T>(
            Expression <Func <T, object> > field,
            Expression <Func <T, string> > standardOutput,
            T model,
            object parameters,
            Context context,
            Database database,
            TextWriter writer)
        {
            string firstPart = string.Empty;
            string lastPart  = string.Empty;

            try
            {
                if (field == null)
                {
                    throw new NullReferenceException("No field set");
                }
                if (model == null)
                {
                    throw new NullReferenceException("No model set");
                }

                string parametersStringTemp = string.Empty;

                SafeDictionary <string> dictionary = new SafeDictionary <string>();

                if (parameters == null)
                {
                    parametersStringTemp = string.Empty;
                }
                else if (parameters is string)
                {
                    parametersStringTemp = parameters as string;
                    dictionary           = WebUtil.ParseQueryString(parametersStringTemp ?? string.Empty);
                }
                else if (parameters is NameValueCollection)
                {
                    var collection = (NameValueCollection)parameters;
                    foreach (var key in collection.AllKeys)
                    {
                        dictionary.Add(key, collection[key]);
                    }
                }
                else
                {
                    var collection = Utilities.GetPropertiesCollection(parameters, true);
                    foreach (var key in collection.AllKeys)
                    {
                        dictionary.Add(key, collection[key]);
                    }
                }


                if (IsInEditingMode)
                {
                    MemberExpression memberExpression;
                    var finalTarget = Mapper.Utilities.GetTargetObjectOfLamba(field, model, out memberExpression);
                    var config      = Mapper.Utilities.GetTypeConfig <T, SitecoreTypeConfiguration>(field, context, model);
                    var dataHandler = Mapper.Utilities.GetGlassProperty <T, SitecoreTypeConfiguration>(field, context, model);

                    var scClass = config.ResolveItem(finalTarget, database);

                    using (new ContextItemSwitcher(scClass))
                    {
                        RenderFieldArgs renderFieldArgs = new RenderFieldArgs();
                        renderFieldArgs.Item = scClass;

                        var fieldConfig = (SitecoreFieldConfiguration)dataHandler;
                        if (fieldConfig.FieldId != (ID)null && fieldConfig.FieldId != ID.Null)
                        {
                            renderFieldArgs.FieldName = fieldConfig.FieldId.ToString();
                        }
                        else
                        {
                            renderFieldArgs.FieldName = fieldConfig.FieldName;
                        }

                        renderFieldArgs.Parameters     = dictionary;
                        renderFieldArgs.DisableWebEdit = false;

                        CorePipeline.Run("renderField", (PipelineArgs)renderFieldArgs);

                        firstPart = renderFieldArgs.Result.FirstPart;
                        lastPart  = renderFieldArgs.Result.LastPart;
                    }
                }
                else
                {
                    if (standardOutput != null)
                    {
                        firstPart = GetCompiled(standardOutput)(model).ToString();
                    }
                    else
                    {
                        object target = (GetCompiled(field)(model) ?? string.Empty);

                        if (ImageType.IsInstanceOfType(target))
                        {
                            var image = target as Image;
                            firstPart = RenderImage(image, dictionary);
                        }
                        else if (LinkType.IsInstanceOfType(target))
                        {
                            var link       = target as Link;
                            var sb         = new StringBuilder();
                            var linkWriter = new StringWriter(sb);
                            var result     = BeginRenderLink(link, dictionary, null, linkWriter);
                            result.Dispose();
                            linkWriter.Flush();
                            linkWriter.Close();

                            firstPart = sb.ToString();
                        }
                        else
                        {
                            firstPart = target.ToString();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                firstPart = "<p>{0}</p><pre>{1}</pre>".Formatted(ex.Message, ex.StackTrace);
                Sitecore.Diagnostics.Log.Error("Failed to render field", ex, typeof(IGlassHtml));
            }

            return(new RenderingResult(writer, firstPart, lastPart));


            //return field.Compile().Invoke(model).ToString();
        }