Ye' old general discussion board. Basically, for everything that isn't covered elsewhere. Come here to shoot the breeze, shoot your mouth off, or whatever suits your fancy.
This forum is not for asking programming related questions.
Moderator: General Moderators
yacahuma
Forum Regular
Posts: 870 Joined: Sun Jul 01, 2007 7:11 am
Post
by yacahuma » Wed Feb 18, 2009 5:18 pm
For my last project I created a library that reads xml and displays it into an html form. In the xml you can define input types. You can also match a data object with the presentation. You can also define in the xml the errors that you will catch, and its corresponding user friendly explanation. The library know how to create new elements and how to delete them , and it can handle any kind of complex object. You can define validation routines and prechecks, in case you dont what to show that form if you are not supposed to. You can also tell the form where to go next. Basically all the display and logic flow is in the xml. The actual coding is done in the object that the form represents.
Has this been done before?
Code: Select all
<page id="w2_per" class="W2:IndividualInfo" group="W2">
<title>W2</title>
<subtitle>Información Personal</subtitle>
<alertcodes function="W2/W2Forms[]/validatePersonalInfo():W2/checkForDupControlNumbers()">
<code value="W_INVALID_CONTROL_NUMBER">El número de control es inválido. Deben ser 8 dígitos</code>
<code value="W_SPOUSE_NA_NOT_MARRIED">Cónyuge no es permitido debido a su estado personal</code>
<code value="W_ControlNumber_EXISTS">El Número de Control ya existe</code>
<code value="W_Owner_EMPTY">Falta Dueno</code>
<code value="W_Type_EMPTY">Falta Tipo</code>
<code value="O_RECORD_UPDATED">Su data ha sido actualizada</code>
</alertcodes>
<formfields>
<field type="Owner" name="Owner" ds="W2/W2Forms[]/Owner">
<label>¿De quien es la W2?</label>
</field>
<field type="w2type" name="w2Type" ds="W2/W2Forms[]/w2Type">
<label>Tipo de W2</label>
</field>
<field type="TFGen8" name="ControlNumber" ds="W2/W2Forms[]/ControlNumber">
<label>Número Control:</label>
</field>
</formfields>
<flowinfo id="Owner" on_y="__SELF__?pageid=w2_employer&dx=[]" on_n="__SELF__?pageid=w2_employer&dx=[]" />
</page>
josh
DevNet Master
Posts: 4872 Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida
Post
by josh » Thu Feb 19, 2009 5:02 am
yacahuma wrote: Has this been done before?
Yes. I personally disdain the XML config method. I used to loathe it, until I had to try to debug some one else's system that used it. XML is not a programming language and the more you use it for stuff like this the greater the chances you're going to have to come back and re-define your syntax whenever new features get added
yacahuma
Forum Regular
Posts: 870 Joined: Sun Jul 01, 2007 7:11 am
Post
by yacahuma » Thu Feb 19, 2009 5:42 am
I know what you mean. The thing is that this particular kind of application lend itself to be configured by array data. So instead of placing the data in arrays, xml seem a better choice. It does have some benefits like the separation of presentation and code, and also the whole application behaves the same(It basically forces you). I guess a real test will be how fast can someone finish an application the normal way and the xml way. I am not convince myself that it is a better way. Time will tell.
josh
DevNet Master
Posts: 4872 Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida
Post
by josh » Thu Feb 19, 2009 2:31 pm
You can still separate things without putting it in XML. Theres code, databases, etc.. I don't think alot of tests need to be done to tell that some one that is new to the system is going to have a harder time learning the XML syntax. Thing is most IDEs have the ability to jump to method declarations, if a programmer didn't know what something did he could jump straight to the code, with XML try this: intentionally introduce a typo like an unrecognized tag ( but keep the syntax correct ). Your application will most likely run just behave unexpectedly, maybe your error catching is really good though...
josh
DevNet Master
Posts: 4872 Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida
Post
by josh » Thu Feb 19, 2009 2:45 pm
Here's an example of how this breaks down. Try and decipher what this does:
Code: Select all
<?xml version="1.0"?>
<!--
/**
* Magento
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE_AFL.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@magentocommerce.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade Magento to newer
* versions in the future. If you wish to customize Magento for your
* needs please refer to http://www.magentocommerce.com for more information.
*
* @category design_default
* @package Mage
* @copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
*/
Supported layout update handles (action):
- catalog_product_gallery
- catalog_product_compare_index
Supported layout update handles (special):
- default
- catalog_category_default
- catalog_category_layered
- catalog_product_view
-->
<layout version="0.1.0">
<!--
Default layout, loads most of the pages
-->
<default>
<!-- Mage_Catalog -->
<reference name="top.menu">
<block type="catalog/navigation" name="catalog.topnav" template="catalog/navigation/top.phtml"/>
</reference>
<reference name="left">
<block type="core/template" name="left.permanent.callout" template="callouts/left_col.phtml">
<action method="setImgSrc"><src>images/media/col_left_callout.jpg</src></action>
<action method="setImgAlt" translate="alt" module="catalog"><alt>Our customer service is available 24/7. Call us at (800) DEMO-NUMBER.</alt></action>
<action method="setLinkUrl"><url>checkout/cart</url></action>
</block>
</reference>
<reference name="right">
<block type="core/template" before="cart_sidebar" name="catalog.compare.sidebar" template="catalog/product/compare/sidebar.phtml"/>
<block type="core/template" name="right.permanent.callout" template="callouts/right_col.phtml"/>
</reference>
<reference name="footer_links">
<action method="addLink" translate="label title" module="catalog" ifconfig="catalog/seo/site_map"><label>Site Map</label><url helper="catalog/map/getCategoryUrl" /><title>Site Map</title></action>
</reference>
</default>
<!--
Category default layout
-->
<catalog_category_default>
<reference name="left">
<block type="catalog/navigation" name="catalog.leftnav" after="currency" template="catalog/navigation/left.phtml"/>
</reference>
<reference name="content">
<block type="catalog/category_view" name="category.products" template="catalog/category/view.phtml">
<block type="catalog/product_list" name="product_list" template="catalog/product/list.phtml">
<block type="catalog/product_list_toolbar" name="product_list_toolbar" template="catalog/product/list/toolbar.phtml">
<!-- The following code shows how to set your own pager increments -->
<!--
<action method="setDefaultListPerPage">
<limit>4</limit></action>
<action method="setDefaultGridPerPage"><limit>9</limit></action>
<action method="addPagerLimit"><mode>list</mode><limit>2</limit></action>
<action method="addPagerLimit"><mode>list</mode><limit>4</limit></action>
<action method="addPagerLimit"><mode>list</mode><limit>6</limit></action>
<action method="addPagerLimit"><mode>list</mode><limit>8</limit></action>
<action method="addPagerLimit" translate="label"><mode>list</mode><limit>all</limit><label>All</label></action>
-->
</block>
<action method="setToolbarBlockName"><name>product_list_toolbar</name></action>
</block>
</block>
</reference>
</catalog_category_default>
<!--
Category layered navigation layout
-->
<catalog_category_layered>
<reference name="left">
<block type="catalog/layer_view" name="catalog.leftnav" after="currency" template="catalog/layer/view.phtml"/>
</reference>
<reference name="content">
<block type="catalog/category_view" name="category.products" template="catalog/category/view.phtml">
<block type="catalog/product_list" name="product_list" template="catalog/product/list.phtml">
<!-- <action method="addReviewSummaryTemplate">
<type>default</type><template>review/helper/su.phtml</template></action> -->
<block type="catalog/product_list_toolbar" name="product_list_toolbar" template="catalog/product/list/toolbar.phtml">
<!-- The following code shows how to set your own pager increments -->
<!--
<action method="setDefaultListPerPage">
<limit>4</limit></action>
<action method="setDefaultGridPerPage"><limit>3</limit></action>
<action method="addPagerLimit"><mode>list</mode><limit>2</limit></action>
<action method="addPagerLimit"><mode>list</mode><limit>4</limit></action>
<action method="addPagerLimit"><mode>list</mode><limit>6</limit></action>
<action method="addPagerLimit"><mode>list</mode><limit>8</limit></action>
<action method="addPagerLimit" translate="label"><mode>list</mode><limit>all</limit><label>All</label></action>
<action method="addPagerLimit"><mode>grid</mode><limit>3</limit></action>
<action method="addPagerLimit"><mode>grid</mode><limit>6</limit></action>
<action method="addPagerLimit"><mode>grid</mode><limit>9</limit></action>
<action method="addPagerLimit"><mode>grid</mode><limit>all</limit><label>All</label></action>
-->
</block>
<action method="setToolbarBlockName"><name>product_list_toolbar</name></action>
</block>
</block>
</reference>
</catalog_category_layered>
<catalog_category_layered_nochildren>
<remove name="right.reports.product.viewed" />
<reference name="right">
<block type="reports/product_viewed" before="right.permanent.callout" name="left.reports.product.viewed" template="reports/product_viewed.phtml" />
</reference>
</catalog_category_layered_nochildren>
<!--
Compare products page
-->
<catalog_product_compare_index>
<!-- Mage_Catalog -->
<reference name="root">
<action method="setTemplate"><template>page/one-column.phtml</template></action>
</reference>
<reference name="head">
<action method="addJs"><script>scriptaculous/scriptaculous.js</script></action>
<action method="addJs"><script>varien/product.js</script></action>
</reference>
<reference name="content">
<block type="catalog/product_compare_list" name="catalog.compare.list" template="catalog/product/compare/list.phtml"/>
</reference>
</catalog_product_compare_index>
<customer_account_index>
<reference name="right">
<action method="unsetChild"><name>catalog_compare_sidebar</name></action>
</reference>
</customer_account_index>
<!--
Product view
-->
<catalog_product_view>
<!-- Mage_Catalog -->
<reference name="root">
<action method="setTemplate"><template>page/2columns-right.phtml</template></action>
</reference>
<reference name="head">
<action method="addJs"><script>varien/product.js</script></action>
<action method="addItem"><type>js_css</type><name>calendar/calendar-win2k-1.css</name><params/><!--<if/>
<condition>can_load_calendar_js</condition>--></action>
<action method="addItem"><type>js</type><name>calendar/calendar.js</name><!--<params/>
<if/><condition>can_load_calendar_js</condition>--></action>
<action method="addItem"><type>js</type><name>calendar/lang/calendar-en.js</name><!--<params/>
<if/><condition>can_load_calendar_js</condition>--></action>
<action method="addItem"><type>js</type><name>calendar/calendar-setup.js</name><!--<params/>
<if/><condition>can_load_calendar_js</condition>--></action>
</reference>
<reference name="content">
<block type="catalog/product_view" name="product.info" template="catalog/product/view.phtml">
<!--
<action method="addReviewSummaryTemplate">
<type>default</type><template>review/helper/summary.phtml</template></action>
<action method="addReviewSummaryTemplate"><type>short</type><template>review/helper/summary_short.phtml</template></action>
<action method="addReviewSummaryTemplate"><type>...</type><template>...</template></action>
-->
<block type="catalog/product_view_media" name="product.info.media" as="media" template="catalog/product/view/media.phtml"/>
<block type="core/text_list" name="alert.urls" as="alert_urls" />
<action method="setTierPriceTemplate"><template>catalog/product/view/tierprices.phtml</template></action>
<block type="catalog/product_list_upsell" name="product.info.upsell" as="upsell_products" template="catalog/product/list/upsell.phtml">
<action method="setColumnCount"><columns>4</columns></action>
<action method="setItemLimit"><type>upsell</type><limit>4</limit></action>
</block>
<block type="catalog/product_view_additional" name="product.info.additional" as="product_additional_data" />
<block type="catalog/product_view_description" name="product.description" as="description" template="catalog/product/view/description.phtml"/>
<block type="catalog/product_view_attributes" name="product.attributes" as="additional" template="catalog/product/view/attributes.phtml"/>
<block type="catalog/product_view" name="product.info.addto" as="addto" template="catalog/product/view/addto.phtml"/>
<block type="catalog/product_view" name="product.info.addtocart" as="addtocart" template="catalog/product/view/addtocart.phtml"/>
<block type="catalog/product_view" name="product.info.options.wrapper" as="product_options_wrapper" template="catalog/product/view/options/wrapper.phtml">
<block type="catalog/product_view_options" name="product.info.options" as="product_options" template="catalog/product/view/options.phtml">
<action method="addOptionRenderer"><type>text</type><block>catalog/product_view_options_type_text</block><template>catalog/product/view/options/type/text.phtml</template></action>
<action method="addOptionRenderer"><type>file</type><block>catalog/product_view_options_type_file</block><template>catalog/product/view/options/type/file.phtml</template></action>
<action method="addOptionRenderer"><type>select</type><block>catalog/product_view_options_type_select</block><template>catalog/product/view/options/type/select.phtml</template></action>
<action method="addOptionRenderer"><type>date</type><block>catalog/product_view_options_type_date</block><template>catalog/product/view/options/type/date.phtml</template></action>
</block>
</block>
<block type="catalog/product_view" name="product.info.options.wrapper.bottom" as="product_options_wrapper_bottom" template="catalog/product/view/options/wrapper/bottom.phtml">
<action method="insert"><block>product.tierprices</block></action>
<block type="catalog/product_view" name="product.clone_prices" as="prices" template="catalog/product/view/price_clone.phtml"/>
<action method="append"><block>product.info.addtocart</block></action>
</block>
<block type="core/template_facade" name="product.info.container1" as="container1">
<action method="setDataByKey"><key>alias_in_layout</key><value>container1</value></action>
<action method="setDataByKeyFromRegistry"><key>options_container</key><key_in_registry>product</key_in_registry></action>
<action method="append"><block>product.info.options.wrapper</block></action>
<action method="append"><block>product.info.options.wrapper.bottom</block></action>
</block>
<block type="core/template_facade" name="product.info.container2" as="container2">
<action method="setDataByKey"><key>alias_in_layout</key><value>container2</value></action>
<action method="setDataByKeyFromRegistry"><key>options_container</key><key_in_registry>product</key_in_registry></action>
<action method="append"><block>product.info.options.wrapper</block></action>
<action method="append"><block>product.info.options.wrapper.bottom</block></action>
</block>
<action method="unsetCallChild"><child>container1</child><call>ifEquals</call><if>0</if><key>alias_in_layout</key><key>options_container</key></action>
<action method="unsetCallChild"><child>container2</child><call>ifEquals</call><if>0</if><key>alias_in_layout</key><key>options_container</key></action>
</block>
</reference>
<reference name="right">
<block type="catalog/product_list_related" name="catalog.product.related" before="-" template="catalog/product/list/related.phtml"/>
</reference>
</catalog_product_view>
<!--
Additional block dependant on product type
-->
<PRODUCT_TYPE_simple>
<reference name="product.info">
<block type="catalog/product_view_type_simple" name="product.info.simple" as="product_type_data" template="catalog/product/view/type/simple.phtml"/>
</reference>
</PRODUCT_TYPE_simple>
<PRODUCT_TYPE_configurable>
<reference name="product.info">
<block type="catalog/product_view_type_configurable" name="product.info.configurable" as="product_type_data" template="catalog/product/view/type/configurable.phtml"/>
</reference>
<reference name="product.info.options.wrapper">
<block type="catalog/product_view_type_configurable" name="product.info.options.configurable" as="options_configurable" before="-" template="catalog/product/view/type/options/configurable.phtml"/>
</reference>
</PRODUCT_TYPE_configurable>
<PRODUCT_TYPE_grouped>
<reference name="product.info">
<block type="catalog/product_view_type_grouped" name="product.info.grouped" as="product_type_data" template="catalog/product/view/type/grouped.phtml" />
</reference>
</PRODUCT_TYPE_grouped>
<PRODUCT_TYPE_virtual>
<reference name="product.info">
<block type="catalog/product_view_type_virtual" name="product.info.virtual" as="product_type_data" template="catalog/product/view/type/virtual.phtml"/>
</reference>
</PRODUCT_TYPE_virtual>
<!--
Product send to friend
-->
<catalog_product_send>
<!-- Mage_Catalog -->
<reference name="root">
<action method="setTemplate"><template>page/2columns-right.phtml</template></action>
</reference>
<reference name="head">
<action method="addJs"><script>varien/product.js</script></action>
</reference>
<reference name="content">
<block type="catalog/product_send" name="product.send" template="catalog/product/send.phtml">
</block>
</reference>
</catalog_product_send>
<!--
Product additional images gallery popup
-->
<catalog_product_gallery>
<!-- Mage_Catalog -->
<reference name="root">
<action method="setTemplate"><template>page/one-column.phtml</template></action>
</reference>
<reference name="content">
<block type="catalog/product_gallery" name="catalog_product_gallery" template="catalog/product/gallery.phtml"/>
</reference>
</catalog_product_gallery>
<!--
SEO Site Map
-->
<catalog_seo_sitemap>
<remove name="right"/>
<remove name="left"/>
<reference name="root">
<action method="setTemplate"><template>page/1column.phtml</template></action>
</reference>
<reference name="content">
<block type="page/template_container" name="seo.sitemap.container" template="catalog/seo/sitemap/container.phtml">
<block type="page/template_links" name="seo.sitemap.links" as="links" template="page/template/links.phtml"/>
<block type="page/html_pager" name="seo.sitemap.pager.top" as="pager_top" template="page/html/pager.phtml"/>
<block type="page/html_pager" name="seo.sitemap.pager.bottom" as="pager_bottom" template="page/html/pager.phtml"/>
</block>
</reference>
</catalog_seo_sitemap>
<catalog_seo_sitemap_category>
<update handle="catalog_seo_sitemap" />
<reference name="seo.sitemap.container">
<action method="setTitle" translate="title" module="catalog"><title>Categories</title></action>
<block type="catalog/seo_sitemap_category" name="seo.sitemap.sitemap" as="sitemap" after="pager_top" template="catalog/seo/sitemap.phtml">
<action method="bindPager"><pager>seo.sitemap.pager.top</pager></action>
<action method="bindPager"><pager>seo.sitemap.pager.bottom</pager></action>
<action method="setItemsTitle" translate="title" module="catalog"><title>categories</title></action>
</block>
</reference>
<reference name="seo.sitemap.links">
<action method="addLink" translate="label title" module="catalog"><label>Products Sitemap</label><url helper="catalog/map/getProductUrl"/><title>Products Sitemap</title></action>
</reference>
</catalog_seo_sitemap_category>
<catalog_seo_sitemap_product>
<update handle="catalog_seo_sitemap" />
<reference name="seo.sitemap.container">
<action method="setTitle" translate="title" module="catalog"><title>Products</title></action>
<block type="catalog/seo_sitemap_product" name="seo.sitemap.sitemap" as="sitemap" after="pager_top" template="catalog/seo/sitemap.phtml">
<action method="bindPager"><pager>seo.sitemap.pager.top</pager></action>
<action method="bindPager"><pager>seo.sitemap.pager.bottom</pager></action>
<action method="setItemsTitle" translate="title" module="catalog"><title>products</title></action>
</block>
</reference>
<reference name="seo.sitemap.links">
<action method="addLink" translate="label title" module="catalog"><label>Categories Sitemap</label><url helper="catalog/map/getCategoryUrl"/><title>Categories Sitemap</title></action>
</reference>
</catalog_seo_sitemap_product>
<!--
Catalog search terms block
-->
<catalog_seo_searchterm_popular>
<remove name="right"/>
<remove name="left"/>
<reference name="root">
<action method="setTemplate"><template>page/1column.phtml</template></action>
</reference>
<reference name="content">
<block type="catalog/seo_searchterm" name="seo.searchterm" template="catalog/seo/searchterm.phtml"/>
</reference>
</catalog_seo_searchterm_popular>
</layout>
yacahuma
Forum Regular
Posts: 870 Joined: Sun Jul 01, 2007 7:11 am
Post
by yacahuma » Thu Feb 19, 2009 3:35 pm
it socks when is not my xml,
josh
DevNet Master
Posts: 4872 Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida
Post
by josh » Thu Feb 19, 2009 3:37 pm
JAB Creations
DevNet Resident
Posts: 2341 Joined: Thu Jan 13, 2005 6:44 pm
Location: Sarasota Florida
Contact:
Post
by JAB Creations » Fri Feb 20, 2009 5:29 am
Simpsons did it.
josh
DevNet Master
Posts: 4872 Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida
Post
by josh » Fri Feb 20, 2009 10:31 am
Now you can draw your cartoons in a declarative manner
josh
DevNet Master
Posts: 4872 Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida
Post
by josh » Sat Feb 21, 2009 3:37 am
yacahuma
Forum Regular
Posts: 870 Joined: Sun Jul 01, 2007 7:11 am
Post
by yacahuma » Sun Feb 22, 2009 5:22 am
I will not go as far as saying is an anti pattern. If you have a lot of data in an array, why not save it into an xml(or some other method outside the code). True you get a performance hit. I guess if you used a compiled language it will make more sense to have this data out. Since php is scripted, this decision is less crucial.
For example. In my case started like this. I had at lot of form data in an array like
Code: Select all
$pages = ['page1']= array('Name','Last Name','Initial');
Since I had so many, I thought that using xml it ill be better originized
Code: Select all
<pages>
<page id="page1">
<formfields>
<field id="Name" />
<field id="Last Name" />
<field id="Initial" />
</formfields>
</page>
</pages>
An it just grew from there. I think the biggest problem is when you start putting logic in the xml. In my case I use functions like:
Code: Select all
<page id="page1" precheck="function1()">
Thats when I stopped. Functions just return empty or an error code. A page will or not displayed depending on the error. But that logic is not in the xml, it is in php. So Is just presentation data. You will find not if statements in the xml.
josh
DevNet Master
Posts: 4872 Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida
Post
by josh » Sun Feb 22, 2009 5:01 pm
I prefer database tables, since they are more machine + human friendly then the XML approach. If it doesn't make sense in a database then I could see debating between XML or application code. The only advantage I see of XML is the compiled thing. The disadvantages of XML is you're throwing out your IDE, debugging, you're reinventing basic language syntax, etc..
yacahuma
Forum Regular
Posts: 870 Joined: Sun Jul 01, 2007 7:11 am
Post
by yacahuma » Sun Feb 22, 2009 7:46 pm
I am going to have to disagree on your last post. I dont see a need to store static data on a database. A simple include file does the job perfectly.
josh
DevNet Master
Posts: 4872 Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida
Post
by josh » Sun Feb 22, 2009 8:25 pm
Obviously if the data is static database is overkill? The point of externalizing the business rules is because they vary more often then the application code, and an include would imply application code anyways. There are vast advantages a database has over flat file, they should be common sense.