Foren

Using metal.js components in SoyPortlet

S Ts, geändert vor 7 Jahren.

Using metal.js components in SoyPortlet

New Member Beiträge: 16 Beitrittsdatum: 31.08.16 Neueste Beiträge
Hi,

Im trying to write a portlet using the SoyPortlet class with in liferay 7.

Im able to write and use my own components however Im having trouble using the existing metal components. (ie. Datatable, Treeview, Dropdown as seen here https://github.com/metal/metal-components)

I can see them in my node_modules dir and can compile soy templates using the components successfully, however any data I attempt to pass to them results in a type error.

Here is my render method.

    @Override
    public void render(RenderRequest renderRequest, RenderResponse renderResponse)
            throws IOException, PortletException {
        
        Map<string, object> data = new HashMap<string, object>();
        List<map> l = new ArrayList<map>();
        for (int i = 0; i &lt; 5; i++) {
            Map<string, integer> row = new HashMap<string, integer>();
            row.put("hello", i);
            row.put("goodbye", i*i);
            l.add(row);
        }
        template.put("data", l);
        super.render(renderRequest, renderResponse);
    }
</string,></string,></map></map></string,></string,>


Here is my soy template

{namespace StockTable}

/**
 * StockTable -&gt; Table o stocks
 * @param data
 */
{template .render}
  <div>
    {call Datatable.render}
      {param data: $data /}
    {/call}
  </div>
{/template}


Here is the exception.

23:44:08,931 ERROR [http-nio-8080-exec-1][render_portlet_jsp:131] null
com.google.template.soy.tofu.SoyTofuException: In 'call' command {call .render_ data="$data"}{param displayColumnsType: $displayColumnsType /}{param tableClasses: $tableClasses /}{/call}, the data reference does not resolve to a SoyRecord.
	at Datatable.render(Datatable.soy:11)
	at StockTable.render(StockTable.soy:9)


Do i have to pass the parameters in as as list of SoyRecords? if so where can i find this class?

I can get the datatable to render if I do it through javascript but this is obviously not ideal.

{namespace StockTable}

/**
 * StockTable -&gt; Table o stocks
 * @param data
 */
{template .render}
  <div>
    {$data}
    // {call Datatable.render}
    //   {param data: $data /}
    // {/call}
  </div>
{/template}


partial .js file

. . .
class StockTable extends Component {
 . . .
  attached() {
    // this successfully renders the Datatable (at the base of the page) with the data i pass in form the soy portlet
    this.table = new Datatable({
      data: this.data,
      displayColumnsType: false,
    }, '#simple');
  }
}

Soy.register(StockTable, templates);

StockTable.STATE = {
  data: {},
  table: {},
};

export default StockTable;


Any help would be greatly appreciated!
thumbnail
Chema Balsas, geändert vor 7 Jahren.

RE: Using metal.js components in SoyPortlet

Regular Member Beiträge: 127 Beitrittsdatum: 25.02.13 Neueste Beiträge
Hey S TS,

The data format datatable needs for server-side rendering is quite complex. You'd definitely need to massage your data to adapt to it. We don't have something out of the box that would help with that, but it shouldn't be that hard to accomplish. You can see the output outcome in the metal-datatable sources to see what's the exepcted output.

As a reference, we have some places with server-side rendering for it and others that simply render it client-side.

Hope that helps!
S Ts, geändert vor 7 Jahren.

RE: Using metal.js components in SoyPortlet

New Member Beiträge: 16 Beitrittsdatum: 31.08.16 Neueste Beiträge
Hi Chema,

Thanks for the reply!

I'm a little unfamiliar with soy templates in general so please correct me if I'm wrong. But when we extend the SotPortlet class and point to a soy template, the template is rendered into java that the portlet serves up? If we create the object through js then under the hoods we use our <component>.soy.js and the client generates whatever the component needs?

In any case do you guys have any public src that renders the datatable server side? The only portlet I could find that uses soy templates is the fontend-image-editor, and from what I can tell it doesn't pass anything too fancy to the soy templates.
thumbnail
Severin Rohner, geändert vor 7 Jahren.

RE: Using metal.js components in SoyPortlet

Junior Member Beiträge: 43 Beitrittsdatum: 28.01.14 Neueste Beiträge
S Ts:

In any case do you guys have any public src that renders the datatable server side? The only portlet I could find that uses soy templates is the fontend-image-editor, and from what I can tell it doesn't pass anything too fancy to the soy templates.


Hi guys
Yes, this would be very helpful. Specially for the question how to build a reactive UI in Liferay:
Angular 2 has to many function that should be handled by the portal. I was trying it once, but it didn't match for me.
React would be great, but there are some issues with routing, conflicts with SennaJS and server side rendering will be very very hard. (And it's not the Liferay way)
So IMHO the best way should be to use MetalJS, but the documentation is not very deep, there are no real world examples (till today I can't find any use of metal router anywhere in the portal master) and even in the Liferay community is no existing community. This means I'm going to have a huge learning curve. emoticon

So, thanks for every help (special thanks to Chema) and any productive code. I hope Liferay will use MetalJS in protlets very soon ;-)
thumbnail
Gustav Novotný, geändert vor 7 Jahren.

R: Using metal.js components in SoyPortlet

New Member Beiträge: 15 Beitrittsdatum: 25.01.12 Neueste Beiträge
I vote for better documentation and examples, too!