Copied to clipboard

Flag this post as spam?

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


  • Adam 9 posts 30 karma points
    Feb 13, 2013 @ 19:51
    Adam
    1

    How to get a node by name?

    Hi,

    I am relatively new to Umbraco.  I'm using V6 with MVC.  Things are clicking pretty well, but I'm running into an issue.  My homepage has an image carousel.  I am trying to keep the page site nodes pages clean, so I created the following document type structure:

    -MasterPage (where page nodes will live)
       - Home
       - Subpage

    - TableData (where more database-like data will live)
       - Carousel
            - CarouselImage

    Content-wise, I'd have a homepage carousel with 4 images and an "Our Services" carousel with other images.

    In my Razor code, I'd like to fetch all images under a node called "HomePage Carousel".  I'm not seeing a way to achieve that simple task.  I dont want to hard-code a nodeID, since devel and production may differ.

    This seems like a common task, but I haven't been able to find a great answer.  Can someone help?

    Thanks,
    Adam

     

     

  • Charles Afford 1163 posts 1709 karma points
    Feb 13, 2013 @ 22:36
    Charles Afford
    0

    Hey :) Does your carousel folder have a unique document type?  What you will need to do is pass in the id of your root node (which would be HomePage and OurServices) and then use the GetDesendents() method, or if that is not avaliable the GetChildren() method.

    There should be someway using that method of drilling down to find your 'HomePage Carousel' folder and then itterating though that folder to get the images ect for your carousel.  Hope this helps.  Charlie :) 

  • Adam 9 posts 30 karma points
    Feb 13, 2013 @ 22:51
    Adam
    0

    Hi,

    Thanks for the prompt response, Charlie.

    Content-wise, the Carousels look like the following (below).  It seems like there should be some way of saying, "Get me the node with namee Home Page Carousel so that I can loop over its children".  The way you describe (passing a nodeID) seems to be the standard way of doing things, but would break if you have a development and production environment.  I come from a background of more structured data, so I guess I'm trying to simulate a mini-database using the structure I describe here.  Perhaps this isn't common in Umbraco?

    TableData
       - Carousels
           - Home Page Carousel
                - Slide 1
                - Slide 2
                - Slide 3
           - Services Carousel
                - Slide 4
                - Slide 5
                - Slide 6

    Thanks,
    Adam

     

     

     

     

  • Nathalie Larsson 2 posts 22 karma points c-trib
    Feb 14, 2013 @ 09:12
    Nathalie Larsson
    0

    Hi, not sure if this is what you looking for. 

    How about a content picker on your Home Page node, where you pick the Home Page Carousel folder? In that way you can easily get the nodeID and loop thru the children from it. 

    Or have you tried working with the "nodeTypeAlias"?

     

  • Charles Afford 1163 posts 1709 karma points
    Feb 14, 2013 @ 10:34
    Charles Afford
    0

    Hi, why would i break if you have a dev and production enviroment?

  • gary 385 posts 916 karma points
    Feb 14, 2013 @ 11:07
    gary
    0

    Hi Adam

    @{    var siteRoot = CurrentPage.AncestorOrSelf();

        var updates = siteRoot.Descendants("HomePageCarousel").Children; }

    foreach (var item in updates) { @item.Name}  (This should list them so you know the call is correct)

    That should give you what you need in terms of getting to the children (V6 Mvc). Working with media is a little different, depending on what you have set up for this. My preferred route is to use DigibizAdvancedMediaPicker (DAMP) as it is very flexible.

    But if you use the same call you are using to get media on a level page in the foreach it should work if you include a 

    dynamic media = @item."Your image property alias". then @media.umbracoFile (if you are using standard arrangement)

    If not 100% correct it is hopefully nearer a solution than you are now.

    Regards G

  • Jeroen Breuer 4908 posts 12265 karma points MVP 4x admin c-trib
    Feb 14, 2013 @ 12:52
    Jeroen Breuer
    0

    If you want a good example of DAMP have a look at the DAMP gallery.

    Jeroen

  • Adam 9 posts 30 karma points
    Feb 14, 2013 @ 14:51
    Adam
    0

    Thanks for you feedback, guys.  Nice to see such a helpful community.

    Gary, your code above looks almost exactly like what I am trying to achieve. The only thing I cannot figure out is how to access a node that lives outside of the current site root.  In my example structure below, "var siteRoot = CurrentPage.AncestorOrSelf();" will return  the "Home" node.  I want to go to the TableData node, then use tableDataRoot.Descendants("HomePageCarousel").Children;

    My structure is:

    -Home (the site root node)
       -About Us
       -Other Subpages
    -Table Data
       - Image Carousels
          - Home Page
              - Slide 1
              - Slide 2
              - Slide 3

    Any ideas?

    Thanks,
    Adam

    PS.  I don't think DAMP would work here, as each slide has a title, a body, and an image.  I created a new document type for CarouselImage with these properties. This seems like a good way to go.... if I can just access the "HomePage Carousel" node!

     

  • gary 385 posts 916 karma points
    Feb 14, 2013 @ 15:05
    gary
    0

    Hi Adam

    var siteRoot = CurrentPage.AncestorOrSelf("HomePageCarousel") would go direct (dependent on where your page is in the tree), if not, then try

    var siteRoot = CurrentPage.AncestorOrSelf();

    var blob = siteRoot.Descendants("HomePageCarousel").

    Can't say why wxactly, but sometines you can create the whole string in one, sometimes it needs to be split.

    Just check your docTypeAlais for the nodes, you may be able to do @CurrentPage.AncestorOrSelf().Decendants("The alias you want") then foreach it. You can also specify a level, so AncestorOrSelf(1), etc. . . 

    http://our.umbraco.org/projects/developer-tools/razor-dynamicnode-cheat-sheet   - this may also help, calls are slightly different in V6, but it gives a list of what is avaialable and I often use it as a reference, then V6 it, as it were.

    If you still stuck, post again, see what we can do.

    G

  • Adam 9 posts 30 karma points
    Feb 14, 2013 @ 15:46
    Adam
    0

    Thanks Gary. I think the big problem is that AncestorOrSelf() stops at the "HomePage" node.  It does not want to go above that.  How can I start at the "Content" node (which is the Umbraco default node where content is added under?

    If I had three websites, wouldn't each be a seperate node under Content?  If so, how would I access an item from Site 2 from within Site 1 (since AncestorOrSelf() won't get me out of the current site?

    Thanks,
    Adam

  • gary 385 posts 916 karma points
    Feb 14, 2013 @ 16:12
    gary
    0

    Hi Adam

    Think we may have stumbled across the "root" of the problem.

    The best set up for umbraco is Content Node (ie the permanent one), then rootNode(ie www.yoursite) then your Home Node. It took me a long while to get my head around this, but the benefits are that everything works when you do.

    So its really hard to make in this editor, but have a look at this post from Sebastiaan

    http://cultiv.nl/blog/2010/12/19/tip-of-the-week-the-ultimate-site-structure-setup/

    If you don't currently have this, it will be best you do now - don't worry - all is not lost it can be re-arranged so don't delete anything, you can slide in a rootNode. Will post code snippets and where to put etc, shouldn't take more than 5 minutes.

    Let me know if you need to do this, or I have made a mistake in assuming this and I will guide you through, it just seems that as you cannot get descendants after your "homeNode" that this may be the case.

    If you don't feel you need this structure, you may be able to use AncestorOrSelf(level), but it could get very messy, if it works

    G

     

  • Adam 9 posts 30 karma points
    Feb 14, 2013 @ 17:17
    Adam
    0

    Thanks again, Gary.  For the moment, I just decided to use the nodeID, which leads to one simple line of code to achieve my goal:

        var carousleImages = new Node(1059).Children;

    I don't like hard-coding IDs in templates, as a production database will have different IDs than production (which I'll have to get around be having web.config transformations). 

    It seems to me that a similar function to return a node by name would be a very welcomed addition.  Node would need a constructor for Node(string nodeName, bool byName).  Then you could do:

        var carousleImages = new Node("Homepage-Carousel", true).Children;

    Thanks again for all your help,
    Adam

  • gary 385 posts 916 karma points
    Feb 14, 2013 @ 17:47
    gary
    0

    Hi Adam

    Just looked backed through the posts and we may have a crossed-wire. I think that many people would disagree with your thoughts on the node constructor as that would mean in general terms if a customer changed the name of the node it would break.

    The code I have given you works not on the node name, but on the documentTypeAlias, this will always be "fixed" as long as the node exists. This also means that you can change the name of the node without breaking the code. (ok, it may not apply in your situation, but in general it would be the case).

    Have a quick look at what you named your document type and try to call that - it may make a difference. Sometimes the naming can get a bit confusing.

    Sorry if you have already checked this, but it was just a thought.

    G

  • Adam 9 posts 30 karma points
    Feb 14, 2013 @ 21:59
    Adam
    0

    Sorry, I meant the URLName field, not the name field.  It is my understanding that URLName can be thought of as a unqiue code for each page.  I would hard-code this into my templates instead of nodeID.  Here is the solution a co-worker and I came up with (using Examine).  It's the stubbed out code for my Razor partal view for displaying an image carousel.  This would be much shorter if I could remove the Examine code (which is solely used to access a node by it's URLName property).

    @inherits Umbraco.Web.Mvc.UmbracoTemplatePage
    @using umbraco.MacroEngines
    @using umbraco.NodeFactory
    @using Examine;
    @using UmbracoExamine;
    @using UmbracoExamine.SearchCriteria;

    @{
        string carouselName = (string)ViewBag.carouselName;

        var criteria = ExamineManager.Instance.SearchProviderCollection["ExternalSearcher"].CreateSearchCriteria(UmbracoExamine.IndexTypes.Content);
        var filter = criteria.GroupedOr(new string[] { "urlName" }, carouselName).Compile();
        SearchResult node = ExamineManager.Instance.SearchProviderCollection["ExternalSearcher"].Search(filter).FirstOrDefault();

        var carouselNodeID = Convert.ToInt32(node.Fields["id"]);
        var carouselNode = new Node(carouselNodeID);
        var images = carouselNode.Children;
      
    }

    @foreach (Node item in images)
    {
        <div>
        <b>@item.Name</b><br />
        @item.GetProperty("bodyText")
        </div>
    }

    Thanks again for your help,
    Adam



  • gary 385 posts 916 karma points
    Feb 14, 2013 @ 22:42
    gary
    0

    Wow! That is a demonstration of Examine for all of us.

    Think I will stick to the easy way - for a gallery with thumbnails

    @inherits Umbraco.Web.Mvc.UmbracoTemplatePage

           @{ foreach ( dynamic d in CurrentPage.gallery)

             {

                            <img src="@d.Crops.thumbnail"  alt="d.Alt" /> 
                                   <img src="@d.Url" alt="@d.Name" />
    }
    and that calls the crop and the full size image. (Amend CurrentPage as required) Thanks to Jeroen and DAMP for that.
    The beauty of Umbraco - so many ways to work with it.
    If you set it up correctly, use the available tools, things become easier.
    regards
    G

     

  • Arie 224 posts 675 karma points
    Feb 17, 2013 @ 06:23
    Arie
    0

    I recently installed a carousel on a site, very similar to what you're describing. In my case, there's a node under the home page that acts as the landing page for a section of product lines. Under this the actual product lines appear, each on its own node.

    - home

        - line card index (channel page)

            - line card 1

            - line card 2

            - ...

    The channel page has a specific template (LineCardIndex) applied to it, which I target to grab the line cards. Here's the code:

     

     

    <ul id="carousel" style="border:1px DarkGray solid;background-color:WhiteSmoke;">
    @foreach (var node in Model.AncestorOrSelf().LineCardIndex.First().Children)
    {
    <li>
    <a href="@node.Url">
    <img src="@node.lineCardLogo" width="124" height="83" />
    </a>
    <p class="tooltip">
    <strong>
    @node.GetProperty("contentPageHeader")
    </strong>
    <br />
    @node.GetProperty("lineCardTeaser")
    </p>
    </li>
    }
    </ul>

     

     

     

  • Adam 9 posts 30 karma points
    Feb 17, 2013 @ 15:39
    Adam
    0

    Thanks Arie.  I am storing my slides data outside of the individual site (since it will be shared across a few sites).  Therefore, GetAncestorOrSelf won't work, since that only goes up the each site's root.  That's why I want to access a node by its nodeName, which will find the node outside of each website's root.

  • gary 385 posts 916 karma points
    Feb 20, 2013 @ 08:47
    gary
    0

    Hi Adam

    Looks like you have stumbled across something here - have just tried to do something similar, but cannot, it has also been listed in other topics.

    I can get the "normal" calls to work, (ie AncesorOrSelf().Children) but cannot then specify documentTypes, or Node,  but can only achieve this by running a foreach loop to get to the node. So, currently it is not as it should be. Will post in other similar topics to try to find the answer.

    Maybe you can understand the workings to find a solution?

    So, var p = AncestorOrSelf("topNode").Children.Where("DocumentTypeAlias ==\"SomeChild"), climbs to the top of a sub-tree anywhere in the tree, then, down to find documentType "SomeChild". So, @p.Url() will give the Url of the specified child. But it doesn't. (Have also broken this into individual parts to check each, all seems to function).

    However @foreach ( var item in p) { @item.Url() } will return the specified Url.

    I guess the question is, what does the foreach loop "use" to fetch the property, as it is looping only on one node?

    If you could give a pointer it may solve some issues for a lot of people.

    Many thanks, regards G

  • Adam 9 posts 30 karma points
    Feb 20, 2013 @ 14:26
    Adam
    0

    Hi Gary,

    I have only been working w/ Umbraco for a few weeks now.  I was very surprised to not be able to find a simple method for getting a node by its URLName (primarily if it lives outside of the top node of your site).  If I have two sites running off one install and I want them both to incorporate data that lives in a shared node outside of each website root (like shared image carousels), I think fetching all nodes under a URLName woudl be a standard way to achieve this.  My Examine response above does this, but not in an easy or elegant way (as you need to configure Examine for this to work).

    If anyone has a better/simpler solution, can you please share w/ the group?

    Thanks,
    Adam

     

  • gary 385 posts 916 karma points
    Feb 20, 2013 @ 14:39
    gary
    0

    Hi Adam

    Apologies, it is my surprise too, had loops running so didn't see what you had seen. I don't have a full answer, but have something that may help you.

    There is an Umbraco Helper;

    You should be able to replace your Examine with

    @Umbraco.NiceUrl(1089), or whatever the Id of your node is, replace 1089, this will give you the url, via Intellisense you will see the available extensions, there is one for @Umbraco.NiceUrlWithDomain(1125), which should be of interest to you.

    But as you say, in Umbraco we would normally call the documentTypeAlias, because this can be made unique, will not change even if it were deleted and then replaced, the code would not break. Ok, thanks for reply, hope this little snippet helps and then we can get an answer, it just seems as there is a piece of the jigsaw missing that gets the url. 

    regards Gary

  • Adam 9 posts 30 karma points
    Feb 20, 2013 @ 14:43
    Adam
    0

    Thanks Gary, My whole goal is to use URLName instead of NodeID.  NodeIDs will differ from dev and production databases, but I can set up my homepage image carousel with a URLName of HomePageImageCarousel on dev and prod and know I am fetching the same node.  That's my goal anyway!

    Thanks again for all your help,
    Adam

  • gary 385 posts 916 karma points
    Feb 20, 2013 @ 14:53
    gary
    0

    Hi

    Pleasure - I have sections that can be added, so, parent node and then assorted children, I need a booking form button on each page, so go up to parent, come back down to the booking form doctype, get the url for the button, display on each child page. The only method I can find at present is by the node by Id, which will be different each time, so a manual process. If a customer were to delete it, then re-add, it all breaks.

    Anyhow, sure it will be fixed very soon, or a solution found, other people seem to be experiencing similar issues although using different methods to get there.

    As soon as something comes up, will let you know.

    Have a great day, G

  • rich hamilton 117 posts 136 karma points
    Jul 15, 2013 @ 10:55
    rich hamilton
    1

    He is asking to get a node by name, not it's document type.

    Surely this should be basic functionality?

Please Sign in or register to post replies

Write your reply to:

Draft