<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	>
<channel>
	<title>Comments on: Avoiding Silos: &#8220;link&#8221; as a first-class object</title>
	<atom:link href="http://blog.ianbicking.org/2008/12/27/avoiding-silos-link-as-a-first-class-object/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.ianbicking.org/2008/12/27/avoiding-silos-link-as-a-first-class-object/</link>
	<description></description>
	<pubDate>Wed, 17 Mar 2010 22:02:52 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: Eric Larson</title>
		<link>http://blog.ianbicking.org/2008/12/27/avoiding-silos-link-as-a-first-class-object/comment-page-1/#comment-67898</link>
		<dc:creator>Eric Larson</dc:creator>
		<pubDate>Tue, 30 Dec 2008 16:22:50 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/12/27/avoiding-silos-link-as-a-first-class-object/#comment-67898</guid>
		<description>My biggest issue in working with links has been how to handle transformations gracefully. For example, I would prefer my links to be absolute at all times. This reduces ambiguity between links generated from content and links within the actual application. Along the same lines, when the application is made of smaller microapps (as you've advocated), having an easy way of creating these links effectively can be difficult. 

One method I've used is the idea of a resolver. The application might keep the current pattern for a link generated from data, but the resolve allows for previous patterns to also be used. It also allows for a catalog of bases to be used (ie XML Catalog). This idea is based entirely on creating a custom URL resolver for XSLT, which most XSLT processing libraries support. 

The point here is that I agree links should be first class objects in addition to having a framework or controller in place for managing them that goes beyond simple parsing/routing.</description>
		<content:encoded><![CDATA[<p>My biggest issue in working with links has been how to handle transformations gracefully. For example, I would prefer my links to be absolute at all times. This reduces ambiguity between links generated from content and links within the actual application. Along the same lines, when the application is made of smaller microapps (as you&#8217;ve advocated), having an easy way of creating these links effectively can be difficult. </p>

<p>One method I&#8217;ve used is the idea of a resolver. The application might keep the current pattern for a link generated from data, but the resolve allows for previous patterns to also be used. It also allows for a catalog of bases to be used (ie XML Catalog). This idea is based entirely on creating a custom URL resolver for XSLT, which most XSLT processing libraries support. </p>

<p>The point here is that I agree links should be first class objects in addition to having a framework or controller in place for managing them that goes beyond simple parsing/routing.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ross Lawley</title>
		<link>http://blog.ianbicking.org/2008/12/27/avoiding-silos-link-as-a-first-class-object/comment-page-1/#comment-67629</link>
		<dc:creator>Ross Lawley</dc:creator>
		<pubDate>Mon, 29 Dec 2008 16:36:04 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/12/27/avoiding-silos-link-as-a-first-class-object/#comment-67629</guid>
		<description>I think that template helpers / template tags and a url method achieves the desired effect.  The instance can return its url via a url() method and the template helpers can manage markup.

This keeps the separation of concern between the model and templates.  Also designers have specific areas in which they can manage / inspect templates should they want to extend or change markup.

How you handle template helpers is another area for debate - you could use template fragments in separate html files (keeping the designers away from code) or return strings from the helper methods - but then is that as bad as declaring them in the model?  Probably not, I'd say its still slightly better but its a matter of preference.  I'd choose the latter if my designers had a high level of competence with scripting languages i.e. frontend developers.</description>
		<content:encoded><![CDATA[<p>I think that template helpers / template tags and a url method achieves the desired effect.  The instance can return its url via a url() method and the template helpers can manage markup.</p>

<p>This keeps the separation of concern between the model and templates.  Also designers have specific areas in which they can manage / inspect templates should they want to extend or change markup.</p>

<p>How you handle template helpers is another area for debate - you could use template fragments in separate html files (keeping the designers away from code) or return strings from the helper methods - but then is that as bad as declaring them in the model?  Probably not, I&#8217;d say its still slightly better but its a matter of preference.  I&#8217;d choose the latter if my designers had a high level of competence with scripting languages i.e. frontend developers.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: mike bayer</title>
		<link>http://blog.ianbicking.org/2008/12/27/avoiding-silos-link-as-a-first-class-object/comment-page-1/#comment-67016</link>
		<dc:creator>mike bayer</dc:creator>
		<pubDate>Sun, 28 Dec 2008 07:11:55 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/12/27/avoiding-silos-link-as-a-first-class-object/#comment-67016</guid>
		<description>I just build some Mako defs that deal with URLs for certain types of objects.    The main point of the "def" in Mako is a place that you can put programmatic view logic.


    def url(post)&#62;
      &lt;a href="/post/${post.year}/${post.month}/${post.slug}" rel="nofollow"&gt;
        ${post.title}&lt;/a&gt;
    /def&#62;

(something is wrong with your markdown formatting, or I've just drank too much tonight)

The filter method someone mentioned above can work with this, though I don't use filters that way myself that often.</description>
		<content:encoded><![CDATA[<p>I just build some Mako defs that deal with URLs for certain types of objects.    The main point of the &#8220;def&#8221; in Mako is a place that you can put programmatic view logic.</p>

<pre><code>def url(post)&amp;gt;
  &lt;a href="/post/${post.year}/${post.month}/${post.slug}" rel="nofollow"&gt;
    ${post.title}&lt;/a&gt;
/def&amp;gt;
</code></pre>

<p>(something is wrong with your markdown formatting, or I&#8217;ve just drank too much tonight)</p>

<p>The filter method someone mentioned above can work with this, though I don&#8217;t use filters that way myself that often.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Nathan de Vries</title>
		<link>http://blog.ianbicking.org/2008/12/27/avoiding-silos-link-as-a-first-class-object/comment-page-1/#comment-66961</link>
		<dc:creator>Nathan de Vries</dc:creator>
		<pubDate>Sun, 28 Dec 2008 02:51:55 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/12/27/avoiding-silos-link-as-a-first-class-object/#comment-66961</guid>
		<description>Not sure what you're gaining by pushing your view helpers into the model layer. You're concerned about your posts keeping the same URL/slug, but throwing link helpers into your models is going to hinder more than it will help.

This is how it would be done with Ruby/ERB:

    &lt;ul&gt;
      &lt;% recent_posts.each do &#124;post&#124; %&gt;
        &lt;li&gt;&lt;%= link_tag h(post.title), post_url(post) %&gt;&lt;/li&gt;
      &lt;% end %&gt;
    &lt;/ul&gt;

Or perhaps if you find yourself creating links to posts often, use a template helper:

    &lt;ul&gt;
      &lt;% recent_posts.each do &#124;post&#124; %&gt;
        &lt;li&gt;&lt;%= link_to_post(post) %&gt;&lt;/li&gt;
      &lt;% end %&gt;
    &lt;/ul&gt;
</description>
		<content:encoded><![CDATA[<p>Not sure what you&#8217;re gaining by pushing your view helpers into the model layer. You&#8217;re concerned about your posts keeping the same URL/slug, but throwing link helpers into your models is going to hinder more than it will help.</p>

<p>This is how it would be done with Ruby/ERB:</p>

<pre><code>&lt;ul&gt;
  &lt;% recent_posts.each do |post| %&gt;
    &lt;li&gt;&lt;%= link_tag h(post.title), post_url(post) %&gt;&lt;/li&gt;
  &lt;% end %&gt;
&lt;/ul&gt;
</code></pre>

<p>Or perhaps if you find yourself creating links to posts often, use a template helper:</p>

<pre><code>&lt;ul&gt;
  &lt;% recent_posts.each do |post| %&gt;
    &lt;li&gt;&lt;%= link_to_post(post) %&gt;&lt;/li&gt;
  &lt;% end %&gt;
&lt;/ul&gt;
</code></pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ian Bicking</title>
		<link>http://blog.ianbicking.org/2008/12/27/avoiding-silos-link-as-a-first-class-object/comment-page-1/#comment-66957</link>
		<dc:creator>Ian Bicking</dc:creator>
		<pubDate>Sun, 28 Dec 2008 02:40:59 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/12/27/avoiding-silos-link-as-a-first-class-object/#comment-66957</guid>
		<description>In this case using interfaces is similar to generic functions (and has relatively little to do with an "interface").  Using PyProtocols it might look like:

    @link.when('isinstance(obj, Page) and obj.type == "link"')
    def link(obj):
        return obj.body

Of course in Zope you'd probably have separate class types; outside of Zope it's more common to use a single class that's more connected to the storage type (e.g., a one-to-one mapping of class to database table).

Generally, I'm not sure the complexity of the indirection pays off much.  In theory there's some important separation going on there, but in practice I've never seen it.  Given a RESTful approach, there actually isn't a distinction at all -- an object *is* at its URL, this is not just an implementation detail.  I don't think of the web as an implementation detail, in my mind it is core to the application itself.

That said, creating URLs without some kind of helper is also a needless waste of time and causes bugs (e.g., not allowing for application path prefixes, not quoting segments properly, or spending an inordinate amount of time formatting query string parameters).  And once you have a helper, you've got at least *some* indirection happening.</description>
		<content:encoded><![CDATA[<p>In this case using interfaces is similar to generic functions (and has relatively little to do with an &#8220;interface&#8221;).  Using PyProtocols it might look like:</p>

<pre><code>@link.when('isinstance(obj, Page) and obj.type == "link"')
def link(obj):
    return obj.body
</code></pre>

<p>Of course in Zope you&#8217;d probably have separate class types; outside of Zope it&#8217;s more common to use a single class that&#8217;s more connected to the storage type (e.g., a one-to-one mapping of class to database table).</p>

<p>Generally, I&#8217;m not sure the complexity of the indirection pays off much.  In theory there&#8217;s some important separation going on there, but in practice I&#8217;ve never seen it.  Given a RESTful approach, there actually isn&#8217;t a distinction at all &#8212; an object <em>is</em> at its URL, this is not just an implementation detail.  I don&#8217;t think of the web as an implementation detail, in my mind it is core to the application itself.</p>

<p>That said, creating URLs without some kind of helper is also a needless waste of time and causes bugs (e.g., not allowing for application path prefixes, not quoting segments properly, or spending an inordinate amount of time formatting query string parameters).  And once you have a helper, you&#8217;ve got at least <em>some</em> indirection happening.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Brandon Craig Rhodes</title>
		<link>http://blog.ianbicking.org/2008/12/27/avoiding-silos-link-as-a-first-class-object/comment-page-1/#comment-66945</link>
		<dc:creator>Brandon Craig Rhodes</dc:creator>
		<pubDate>Sun, 28 Dec 2008 01:53:50 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/12/27/avoiding-silos-link-as-a-first-class-object/#comment-66945</guid>
		<description>In Grok/Zope-land, I just create as many IAbsoluteURL adapters as I have object classes that I want to assign URLs to, and the component framework swings into action and invokes the right one when a view asks for some object's URL.  That way my models do not accumulate interface-specific information about where they live, which would be deeply troubling, and yet I have a way to maintain the URL information *alongside* my models in a way that I find scalable.

See slide 147 of [my NOLA Grok talk](http://rhodesmill.org/brandon/2008/nola-plone-symposium-talk/) for an example of how a URL factory looks when you build it for one of your own types.  I should nudge the Grok folks to make that take less lines and look less grungy.  Like maybe three lines. Yeah, three lines.</description>
		<content:encoded><![CDATA[<p>In Grok/Zope-land, I just create as many IAbsoluteURL adapters as I have object classes that I want to assign URLs to, and the component framework swings into action and invokes the right one when a view asks for some object&#8217;s URL.  That way my models do not accumulate interface-specific information about where they live, which would be deeply troubling, and yet I have a way to maintain the URL information <em>alongside</em> my models in a way that I find scalable.</p>

<p>See slide 147 of <a href="http://rhodesmill.org/brandon/2008/nola-plone-symposium-talk/">my NOLA Grok talk</a> for an example of how a URL factory looks when you build it for one of your own types.  I should nudge the Grok folks to make that take less lines and look less grungy.  Like maybe three lines. Yeah, three lines.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ian Bicking</title>
		<link>http://blog.ianbicking.org/2008/12/27/avoiding-silos-link-as-a-first-class-object/comment-page-1/#comment-66888</link>
		<dc:creator>Ian Bicking</dc:creator>
		<pubDate>Sat, 27 Dec 2008 22:58:58 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/12/27/avoiding-silos-link-as-a-first-class-object/#comment-66888</guid>
		<description>Sure, the `.link()` method (in my example) isn't entirely necessary, far more important is the `.url()` method.  I wish, though, that there was a way of doing object-oriented display code that is also designer-friendly.  For example, if you do allow for something like a compound link (as with the via example), coding that into every template where you display a link is entirely infeasible.

One way of handling this would be to use template functions or blocks.  Then you can centralize the logic of link display (making it easier to extend that logic) while still putting it somewhere a designer can find.  Backtracking rendered code to these template functions isn't that easy, but that's something that should be fixed -- it *should* be much easier to see a bit of rendered code and backtrack to where that code was defined.</description>
		<content:encoded><![CDATA[<p>Sure, the <code>.link()</code> method (in my example) isn&#8217;t entirely necessary, far more important is the <code>.url()</code> method.  I wish, though, that there was a way of doing object-oriented display code that is also designer-friendly.  For example, if you do allow for something like a compound link (as with the via example), coding that into every template where you display a link is entirely infeasible.</p>

<p>One way of handling this would be to use template functions or blocks.  Then you can centralize the logic of link display (making it easier to extend that logic) while still putting it somewhere a designer can find.  Backtracking rendered code to these template functions isn&#8217;t that easy, but that&#8217;s something that should be fixed &#8212; it <em>should</em> be much easier to see a bit of rendered code and backtrack to where that code was defined.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Adrian Holovaty</title>
		<link>http://blog.ianbicking.org/2008/12/27/avoiding-silos-link-as-a-first-class-object/comment-page-1/#comment-66875</link>
		<dc:creator>Adrian Holovaty</dc:creator>
		<pubDate>Sat, 27 Dec 2008 22:13:14 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/12/27/avoiding-silos-link-as-a-first-class-object/#comment-66875</guid>
		<description>Yeah, I agree with Rudolph -- why not give the model objects a `url()` method that simply outputs the URL itself? This lets the designer/template define custom classes for the link.

Regarding Marcus' point about relying on a framework's reversing logic -- IMHO, that's going a bit too far, and I never use `reverse()` stuff in model URL methods. I tend to see this as an acceptable breach of the DRY principle, because it's a lot more efficient just to hard-code the URL-generating logic directly in the `url()` method (as opposed to relying on the reverse logic).

It's sort of like denormalizing a database for performance. If you're outputting a list of links and each one is calling `url()`, which in turn calls `reverse()`...whew! That's a lot of unnecessary overhead.</description>
		<content:encoded><![CDATA[<p>Yeah, I agree with Rudolph &#8212; why not give the model objects a <code>url()</code> method that simply outputs the URL itself? This lets the designer/template define custom classes for the link.</p>

<p>Regarding Marcus&#8217; point about relying on a framework&#8217;s reversing logic &#8212; IMHO, that&#8217;s going a bit too far, and I never use <code>reverse()</code> stuff in model URL methods. I tend to see this as an acceptable breach of the DRY principle, because it&#8217;s a lot more efficient just to hard-code the URL-generating logic directly in the <code>url()</code> method (as opposed to relying on the reverse logic).</p>

<p>It&#8217;s sort of like denormalizing a database for performance. If you&#8217;re outputting a list of links and each one is calling <code>url()</code>, which in turn calls <code>reverse()</code>&#8230;whew! That&#8217;s a lot of unnecessary overhead.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Marcus Cavanaugh</title>
		<link>http://blog.ianbicking.org/2008/12/27/avoiding-silos-link-as-a-first-class-object/comment-page-1/#comment-66868</link>
		<dc:creator>Marcus Cavanaugh</dc:creator>
		<pubDate>Sat, 27 Dec 2008 21:52:35 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/12/27/avoiding-silos-link-as-a-first-class-object/#comment-66868</guid>
		<description>The URL approach seems sound, with the primary issue being that web frameworks like to abstract the URL away from the object itself via routing. Most web frameworks would rather see you grab the url via a "reverse" method, rather than hard-coded into the Model itself:

    class Post(SomeORM):
        def url(self):
            if self.is_internal:
                return SomeRouting.reverse('view_post', id=4)
            else:
                return self.external_url

URI-aware objects provide consistency and extensibility.</description>
		<content:encoded><![CDATA[<p>The URL approach seems sound, with the primary issue being that web frameworks like to abstract the URL away from the object itself via routing. Most web frameworks would rather see you grab the url via a &#8220;reverse&#8221; method, rather than hard-coded into the Model itself:</p>

<pre><code>class Post(SomeORM):
    def url(self):
        if self.is_internal:
            return SomeRouting.reverse('view_post', id=4)
        else:
            return self.external_url
</code></pre>

<p>URI-aware objects provide consistency and extensibility.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jerry</title>
		<link>http://blog.ianbicking.org/2008/12/27/avoiding-silos-link-as-a-first-class-object/comment-page-1/#comment-66837</link>
		<dc:creator>Jerry</dc:creator>
		<pubDate>Sat, 27 Dec 2008 20:15:57 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/12/27/avoiding-silos-link-as-a-first-class-object/#comment-66837</guid>
		<description>Hi Ian,

I agree with the initial 40% of your idea, the rest, I think, pushes too much the View layer into the Control layer -- `post.link()` will likely output links with classes and/or ids (even when assuming inline JavaScript is strictly forbidden), which introduces a high dependency/risk of keeping the Control code in sync with the View whenever the web team refactors/updates the design.

I believe a balance can be achieved when `post.link_href()` outputs the content of href and nothing else, while `post.link_text()` returns the a link text.

Jerry

P.S. How to disable/escape underscore Markdown formating? [for cases like these using backticks renders it as code and no markup is not interpreted inside the backticks -- Ian]</description>
		<content:encoded><![CDATA[<p>Hi Ian,</p>

<p>I agree with the initial 40% of your idea, the rest, I think, pushes too much the View layer into the Control layer &#8212; <code>post.link()</code> will likely output links with classes and/or ids (even when assuming inline JavaScript is strictly forbidden), which introduces a high dependency/risk of keeping the Control code in sync with the View whenever the web team refactors/updates the design.</p>

<p>I believe a balance can be achieved when <code>post.link_href()</code> outputs the content of href and nothing else, while <code>post.link_text()</code> returns the a link text.</p>

<p>Jerry</p>

<p>P.S. How to disable/escape underscore Markdown formating? [for cases like these using backticks renders it as code and no markup is not interpreted inside the backticks -- Ian]</p>
]]></content:encoded>
	</item>
</channel>
</rss>

<!-- Dynamic Page Served (once) in 2.446 seconds -->
