Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typesafe config: How to iterate over configuration items

In my Play application I've a configuration like this:

social {
    twitter {
        url="https://twitter.com"
        logo="images/twitter.png"
    }
    facebook {
        url="https://www.facebook.com"
        logo="images/facebook.png"
    }
}

Ho do I iterate over all the social entries to get url and logo for each entry?

<table border="0" cellspacing="0" cellpadding="2"><tr>
    @configuration.getConfig("social").map { config =>
        @for(item <- config.entrySet) {
           <td><a href="item.getString("url")">
           <img src="@routes.Assets.at("item.getString("logo")").absoluteURL()" width="24" height="24"/></a></td>
        }
    }
</table>

Of course, item.getString in the snippet here above does not work... it just shows what I'm trying to achieve.

The final objective would be to be able to add any further social url without having to modify the page template.

like image 897
j3d Avatar asked Dec 14 '13 13:12

j3d


3 Answers

If you change the config to:

"social" : [
     {
        name="twitter",
        url="https://twitter.com",
        logo="images/twitter.png"
    },
    {
        name="facebook",
        url="https://www.facebook.com",
        logo="images/facebook.png"
    }
]

You could do it like this:

@(message: String)(implicit request: RequestHeader)
@import play.api.Play.current

<table border="0" cellspacing="0" cellpadding="2"><tr>
    @current.configuration.getConfigList("social").get.map { config =>
            <td><a href="@config.getString("url")">
            <img src="@routes.Assets.at(config.getString("logo").get).absoluteURL()" width="24" height="24"/></a></td>
        }
</table>
like image 165
Paweł Kozikowski Avatar answered Oct 18 '22 11:10

Paweł Kozikowski


For posterity, here's another way to iterate over a nested config like you had. I prefer that format to the array one and I'd rather make my config cleaner than the code.

import collection.JavaConversions._
val socialConfig = ConfigFactory.load.getConfig("social")
socialConfig.root.map { case (name: String, configObject: ConfigObject) => 
    val config = configObject.toConfig
    println(config.getString("url"))
    println(config.getString("logo"))
}

I'm sure the OP could convert this into a Twirl template. That's about as clean as I can get it.

like image 6
Cole Stanfield Avatar answered Oct 18 '22 10:10

Cole Stanfield


In case you're using Java, for a config like:

"social" : [
  {
    name="twitter",
    url="https://twitter.com",
    logo="images/twitter.png"
  },
  {
    name="facebook",
    url="https://www.facebook.com",
    logo="images/facebook.png"
  }
]

this will work:

ConfigList socials = ConfigFactory().load.getList("social")

for (ConfigValue cv : socials) {
   Config c = ((ConfigObject)cv).toConfig();
   System.out.println(c.getString("url"));
   System.out.println(c.getString("logo"));
}
like image 5
Haiyuan Zhang Avatar answered Oct 18 '22 11:10

Haiyuan Zhang