0

I've looked through the C1 documentation and can't seem to find any docs or examples of passing a page meta type field to a razor function.

I'll give a very trivial example for a POC I'm doing.I've created a page with a page meta type that has a tag field. This tag field will be passed to a razor function that will query Flickr for all images tagged with the value contained in that field. I also don't want to configure this in the Razor function itself in case the Razor function is used on a page that does not use this page meta type.

Update

From what I can tell, you can't say use a constant or select a meta type field from the function parameters dialog, so instead I've just added a parameter that allows you to select the meta type field. See below.

@inherits RazorFunction

@functions {
    public override string FunctionDescription
    {
        get  { return "Some tweets based on keyword"; }
    }

    [FunctionParameter(Label="Flickr Data")]
    public DataReference<MyNamespace.Flickr> FlickrData { get;set; }

    [FunctionParameter(Label="Maximum tweets to show", DefaultValue = 5)]
    public int MaxItems { get; set; }
}

@{
    XNamespace atom = "http://www.w3.org/2005/Atom";
    var feed = XDocument.Load("https://api.flickr.com/services/feeds/photos_public.gne?tags=" + this.FlickrData.Data.FlickrTag);

    var items = feed.Descendants(atom + "entry").Take(this.MaxItems).Select(item => new {
        Title = item.Element(atom + "title").Value,
        Published = item.Element(atom + "published").Value,
        Markup = item.Element(atom + "content").Value
    });
}

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://www.composite.net/ns/function/1.0">
    <head>
    </head>
    <body>
    <p>
        @Html.Raw(@Resources.FlickrAtomFeed.FlickrFeedForMessage) <strong>@FlickrData.Data.FlickrTag</strong>
    </p>
        <dl>
            @foreach (var item in items) {
                <dt>@Html.Raw(@item.Markup)</dt>
                <dd>@item.Title
                    <em>@DateTime.Parse(item.Published).ToString("F"))</em>
                </dd>
            }
        </dl>
    </body>
</html>

From there if I want to use the function on a page, I just have to ensure that that meta type field is on that page. In fact if you try to add the function to a page without the meta type field, it will not let you save the function parameters, so it would be pretty clear that the meta type field needs to be on that page. Still not what I want, but it works.

nickytonline
  • 6,855
  • 6
  • 42
  • 76

1 Answers1

1

In short, if your function is inserted on a page, you can:

  1. Get the current page ID. (Please see http://docs.composite.net/Functions/Composite-C1-API/Sitemap-Navigator)
  2. Query your meta type for the specific data item (the tag on this very page). (Please see http://docs.composite.net/Functions/Razor/Getting-C1-Data and http://docs.composite.net/Legacy/Razor/List-to-Details for inspiration)
  3. Process the retrieved data.

The function can go like this (assuming your page meta type is "My.Meta.Type"):

@using Composite.Data
@inherits RazorFunction

@functions {
    public override string FunctionDescription
    {
        get  { return "..."; }
    }   
}

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://www.composite.net/ns/function/1.0">
    <head>
    </head>
    <body>

        @using (DataConnection dataConnection = new DataConnection())
        {
            // (1) get the current page ID

            SitemapNavigator sitemapNavigator = new SitemapNavigator(dataConnection);

            Guid PageId = sitemapNavigator.CurrentPageNode.Id;

            if (PageId != null)
            {

            // (2) Get the meta field from the current page

                var myTag = Data.Get<My.Meta.Type>().Where(t => t.PageId == PageId).FirstOrDefault();

            // (3) Process the tag the way you like

                if(myTag != null)
                { 
                    <p>@myTag.Tag</p>
                }
            }
        }

    </body>
</html>
wysocki
  • 731
  • 5
  • 7
  • so it does not appear that I can do what I would like to out of the box, i.e. enter a value or select a value from the page meta type field. That looks like custom development. I updated my answer with what I've done for the moment, but after reading your answer, I think I could make it better given I cannot do exactly what I’d like to do. I could have a non required parameter that would be the value the user could type in. If they left it blank, I could do what your answer does in my razor function to grab the meta type field and use that as the parameter. Thoughts? – nickytonline Dec 26 '14 at 19:59