Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • julius 107 posts 289 karma points
    Aug 27, 2011 @ 14:54
    julius
    0

    How would you implement this method

    ..if you were using linq2umbraco??

    IEnumerable<DocTypeBase> FindNodes(string nodeName, string nodeType);

     

    I would like to select nodes with a certain nodeName and from a certain Document Type. I am not sure if this is possible with linq2umbraco though.

    The linq2umbraco queries I use now look like this:

     

    var article = (from art
                              in _ctx.ArticlePages
                              where art.Id == id
                              select art).First();

    How would I create a query that can dynamically select from _ctx.ArticlePages, _ctx.Foo, _ctx.Bar or any type, based on the nodeType parameter?

  • julius 107 posts 289 karma points
    Aug 27, 2011 @ 16:51
    julius
    0

    Hm, I think the answer here is "you wouldn't", or at least not with the existing API. This post by smercer from almost a year ago summarizes the problem:

     

    "what I  meant by class factory, is a factory method, where you could pass it a node ID and it would return a strongly typed Linq2Umbraco POCO cast to an interface (IDocTypeBase?). It could use reflection or just a big switch block that could be generated at the same time one would generate their Linq2Umbraco classes. Just a thought. Manually adding to that switch block every time I add a doc type to umbraco would be nice to avoid."

    http://our.umbraco.org/forum/developers/api-questions/10921-Simple-Linq2umbraco-question

    What I want is the ability to select nodes from Umbraco and return them as strongly types linq2umbraco entities, but without knowing from what context I will be fetching them (without prior knowledge of the "ArticlePages" part of "from _ctx.ArticlePages".

    The reflection option suggested by smercer would be nice. Perhaps it is somehow possible to create a FindNodeById (or ByWhatever) method that returns a IDocTypeBase that uses reflection to determine and dynamically create the right linq2umbraco type and fill its properties. Sounds like a tricky job, but it might work.

     

    Anyone want to reflect on this?

     

     

     

  • Jeroen Breuer 4908 posts 12265 karma points MVP 5x admin c-trib
    Aug 29, 2011 @ 09:45
    Jeroen Breuer
    0

    Not sure if this topic is useful, but here I'm trying to do the same thing. Returning the current page as a Linq2Umbraco object: http://our.umbraco.org/forum/developers/api-questions/13670-Linq-to-Umbraco-get-single-object#comment50365

    Jeroen

  • julius 107 posts 289 karma points
    Aug 29, 2011 @ 23:09
    julius
    0

    Actually, I found out that the whole idea behind this method is pretty useless. My aim was to get strongly typed objects through linq2umbraco. But all you can return from a method like this is a collection of generic DocTypeBase objects. There is little you can do with the DocTypeBase interface. You can't access the actual properties of the underlying  objects (which might be any type extending DocTypeBase), and you don't even KNOW the real object's types at runtime.

    I am trying to write a method that can output any subtree of the content tree as a HTML UL menu and I am now using the NodeFactory to accomplish this.

     

  • Rich Green 2246 posts 4008 karma points
    Aug 30, 2011 @ 08:39
    Rich Green
    0

    Hi,

    If you prefer to work with strongly typed objects you might want to look at uSiteBuilder http://our.umbraco.org/projects/developer-tools/usitebuilder

    However you could also achieve what you're trying to do without a usercontrol using either an Razor or XSLT macro.

    Rich

  • julius 107 posts 289 karma points
    Aug 30, 2011 @ 17:18
    julius
    0

    Hey Rich,

    I am currently using an ASPX macro that takes two arguments, the nodeName and nodeType. I retrieve the first node that matches the nodeName and nodetype (discarding any others) and the I'm using a recursive method to read its children and create the ul list.

    Pretty straightforward really. Next step would be to filter the children by document type, so that I can display one "Category" nodes in the menu of example.

     

    Best, J

     

     

  • Rich Green 2246 posts 4008 karma points
    Aug 30, 2011 @ 17:21
    Rich Green
    0

    Hey,

    Re-useable too :)

    Nice work!

    Rich

     

  • julius 107 posts 289 karma points
    Aug 30, 2011 @ 19:37
    julius
    0

    And the code below. This could be extended by applaying a node type filter in the printRecursive method so it prints only the nodes of the types you want.

     

     

    public string SubtreeAsHtmlList(string nodeName, string nodeTypeAlias)
            {
                IEnumerable nodes = FindNodes(nodeName, nodeTypeAlias);
                if(nodes != null && nodes.Count() > 0)
                {
                    // Grab only the first node and print its children
                    Node rootNode = nodes.First();
                    PrintRecursive(rootNode);
                }
                return HtmlList.ToString();
            }
           
            private IEnumerable FindNodes(string nodeName, string nodeTypeAlias)
            {
                if (String.IsNullOrEmpty(nodeName) || String.IsNullOrEmpty(nodeTypeAlias))
                {
                    throw new ArgumentNullException("Null arguments are not allowed in FindNodes");
                }

                return FetchAsNodes("//root/descendant-or-self::* [@isDoc and name()='" + nodeTypeAlias
                                    + "' and @nodeName = '" + nodeName + "']");
            }


            private IEnumerable FetchAsNodes(string xPathQuery)
            {
                XPathNodeIterator iterator = umbraco.library.GetXmlNodeByXPath(xPathQuery);
                IList nodes = new List();

                while (iterator.MoveNext())
                {
                    XPathNavigator navigator = iterator.Current;
                    if (navigator != null)
                    {
                        var xmlDoc = new XmlDocument();
                        xmlDoc.LoadXml(navigator.OuterXml);
                        string id = navigator.GetAttribute("id", "");
                        int nodeId = -10;
                        int.TryParse(id, out nodeId);
                        nodes.Add(new Node(nodeId));
                    }
                }
                return nodes;
            }
           
           

            // Prints nodes under the the supplied node as an Html unordered list
            // Note: this forum eats my HTML tags, so I replaced all html brackets by *
            private void PrintRecursive(INode node)
            {
                HtmlList.Append("*ul*");
                foreach(Node n in node.ChildrenAsList)
                {             
                    HtmlList.Append("*li*");
                    HtmlList.Append(n.Name);
                    if(n.Children.Count > 0)
                    {
                        PrintRecursive(n);
                    }
                    HtmlList.Append("*/li*");
                }
                HtmlList.Append("*/ul*");
            }

          

Please Sign in or register to post replies

Write your reply to:

Draft