I am receiving the following error when trying to edit some of my Component Presentations using SiteEdit.
Sys.FormatException: Could not get the type info from component xml
schema. Field: cf_tcm:32-204267_title XPath:
Content/custom:Content/custom:title[1]
It's strange because some of the Components with the same Template work fine (these do not have an image set,but the ones with an image set do not work).
Here is the code for my CT:
<div class="column v-2 siteedit">
<!-- TemplateBeginIf cond = "Component.thumbnail" -->
<!-- TemplateBeginIf cond = "Component.image" -->
<a href="##Component.Fields.image##" class="fb ajax">
<!-- TemplateEndIf -->
<img src="##Component.Fields.thumbnail##" class="align-left"
alt="##thumbnail0.Metadata.alt##" height="69" width="99"/>
<!-- TemplateBeginIf cond = "Component.image" -->
</a>
<!-- TemplateEndIf -->
<!-- TemplateEndIf -->
<h2>
<tcdl:ComponentField name="title">##Component.Fields.title##</tcdl:ComponentField>
</h2>
<p>##Component.Fields.summary##</p>
</div>
(I have removed other editable fields just to make sure that it wasn't a problem with a specific field)
Any ideas?
Update
As requested here's my (anonymized) HTML, the 1st and 3rd components have the issue, the middle one is fine:
<div class="general-content columns-three">
<div class="column v-2 siteedit" style="height: 209px; ">
<!-- Start SiteEdit Component Presentation: {
"ID" : "97829119-68f0-4e41-9862-b042d480cb71",
"ComponentID" : "tcm:32-204859",
"ComponentTemplateID" : "tcm:32-204536-32",
"Version" : "2",
"IsQueryBased" : false
} -->
<a href="http://REDACTED:84/_images/REDACTED.png?__Proxy=0" class="fb ajax" target="_self">
<img src="/_images/REDACTED.gif" class="align-left" alt="REDACTED" height="69" width="99">
</a>
<h2>
<span style="">
<!-- Start SiteEdit Component Field: {
"ID" : "cf_tcm:32-204267_title",
"XPath" : "tcm:Content/custom:Content/custom:title[1]",
"IsMultiValued" : false
} -->REDACTED
</span>
</h2>
<p>REDACTED</p>
</div>
<div class="column v-2 siteedit" style="height: 209px; ">
<!-- Start SiteEdit Component Presentation: {
"ID" : "2933b5e0-2006-440d-bc03-2224650bdd7d",
"ComponentID" : "tcm:32-204268",
"ComponentTemplateID" : "tcm:32-204536-32",
"Version" : "5",
"IsQueryBased" : false
} -->
<h2> <span style="">
<!-- Start SiteEdit Component Field: {
"ID" : "cf_tcm:32-204268_title",
"XPath" : "tcm:Content/custom:Content/custom:title[1]",
"IsMultiValued" : false} -->REDACTED</span>
</h2>
<p>REDACTED</p>
</div>
<div class="column v-2 siteedit" style="height: 209px; ">
<!-- Start SiteEdit Component Presentation: {
"ID" : "fac3c467-7c71-4be9-b319-8a35524ee172",
"ComponentID" : "tcm:32-204860",
"ComponentTemplateID" : "tcm:32-204536-32",
"Version" : "2",
"IsQueryBased" : false
} -->
<a href="http://REDACTED:84/_images/REDACTED.png?__Proxy=0" class="fb ajax" target="_self">
<img src="/_images/REDACTED.gif" class="align-left" alt="REDACTED" height="69" width="99">
</a>
<h2> <span style="">
<!-- Start SiteEdit Component Field: {
"ID" : "cf_tcm:32-204269_title",
"XPath" : "tcm:Content/custom:Content/custom:title[1]",
"IsMultiValued" : false
} -->REDACTED</span>
</h2>
<p>REDACTED</p>
</div>
</div>
I explained when that error message appears here: "Could not get the type info from component xml schema" when loading a page in SiteEdit 2009
Your use-case may be different from that question, the product always shows this for the same reason: it can't find a field (that is identified in a <!-- Start SiteEdit Component Field command) in the current Component (that is identified in the enclosing <!-- Start SiteEdit Component Presentation command).
Given your error message:
cf_tcm:32-204267_title XPath: Content/custom:Content/custom:title[1]
It seems like Component tcm:32-204267 doesn't have a field named title.
In these cases it is always easiest if you look at the HTML that SiteEdit ends up processing, so what your staging/preview server returns. Find the title field and its enclosing Component Presentation and verify that indeed that Component Presentation has a field named title.
If you'd like a more direct answer to "what am I doing wrong?", add the relevant HTML-with-the-SiteEdit-commands to your question and I'll update my answer to match.
Update based on the HTML provided
If I look at the IDs of the Component and Fields you provided:
Component: tcm:32-204859 Field: cf_tcm:32-204267_title
Component: tcm:32-204268 Field: cf_tcm:32-204268_title
Component: tcm:32-204860 Field: cf_tcm:32-204269_title
The ID in the JSON is only used by SiteEdit to ensure some meaningless uniqueness. But in this case the Field ID seems to indicate from which Component the field comes.
If you then look at the data closely, you can see that for Component 2 the field points to the same Component. For Components 1 and 3 the fields actually point to another Component. Again, the ID properties of the Field commands are in themselves not used. But the relation between what works and what doesn't seems to coincide pretty well with the knowledge that SiteEdit loads the Schema of the Component indicated in the containing Component Presentation command and cannot find the field at the XPath indicated in the Component Field command.
I suspect that in #1 and #3 you have put some regular Component on the page, but are rendering the title of a Multimedia Component that is linked that Component. In #2 you are most likely rendering the title of an MMC that is explicitly put on the page.
Related
This is my Manage page that was generated by the Scaffolded Identity.
Previously this weird Manage your account header with the subheading: Change your account settings and menu did not appear.
The only thing that showed was the form in the image and the Manage Account header located directly above the form but I'm not sure why suddenly this extra header and menu appears. I've tried searching on the page itself but it doesn't show up in the code. Is this a configuration somewhere?
EDIT:
Added structure of Manage
You can try to open the file _Layout.cshtml in the folder Manage, maybe there is something like this:
<h2>Manage your account</h2>
<div>
<h4>Change your account settings</h4>
<hr />
<div class="row">
<div class="col-md-3">
<partial name="_ManageNav" />
</div>
<div class="col-md-9">
#RenderBody()
</div>
</div>
</div>
#section Scripts {
#RenderSection("Scripts", required: false)
}
Based on your update, I think the problem comes from the way you add scaffolded item.
I suggest you to follow these steps to add all scaffolded items, then deleting which one you don't use.
Right-click on the solution -> Add -> New Scaffolded Item... -> Identity -> Identity -> Add
Check with the option: Override all files.
In the layout input, clicking on the ... button to select the default layout:
In the Data context class input, clicking on + button to create new context class:
After scaffolding, you will receive all the files:
Lastly, you can open the file _Layout.cshtml to check the title, the file content could be:
#{
Layout = "/Areas/Identity/Pages/_Layout.cshtml";
}
<h2>Manage your account</h2>
<div>
<h4>Change your account settings</h4>
<hr />
<div class="row">
<div class="col-md-3">
<partial name="_ManageNav" />
</div>
<div class="col-md-9">
#RenderBody()
</div>
</div>
</div>
#section Scripts {
#RenderSection("Scripts", required: false)
}
I've made a menu showing systems and their subsystems (can in theory be indefinitely) using a recursive component. A user can both add and delete systems, and the menu should therefore update accordingly.
The menu is constructed using a "tree"-object. This tree is therefore updated when a new system is added, or one deleted. But, I now have a problem; even though the new child component is added when the tree is rerendered, the classes of it's parent-component doesn't update. It is necessary to update this because it defines the menu-element to having children/subsystems, and therefore showing them.
Therefore, when adding a new subsystem, this is presented to the user:
<div class="">
<a href="#/Admin/364" class="item">
<i class=""></i>Testname
<div class=""></div>
</a>
</div>
Instead of this:
<div class="menu transition visible" style="display: block !important;">
<a href="#/Admin/364" class="item">
<i class=""></i>Testname
<div class=""></div>
</a>
</div>
It works fine adding a subsystem to a system which already have subsystems (since the menu-class is already present), but not when a subsystem is added to one without subsystems. In that case, the menu ends up looking like this:
The "opposite" problem also occurs on deletion, since the parent still has the menu-class:
Here's the code for the recursive component:
<template>
<router-link :to="{ name: 'Admin', params: { systemId: id } }" class="item" >
<i :class="{ dropdown: hasChildren, icon: hasChildren }"></i>{{name}}
<div :class="{ menu: hasChildren }">
<systems-menu-sub-menu v-for="child in children" :children="child.children" :name="child.name" :id="child.id" :key="child.id"/>
</div>
</router-link>
</template>
<script type = "text/javascript" >
export default {
props: ['name', 'children', 'id'],
name: 'SystemsMenuSubMenu',
data () {
return {
hasChildren: (this.children.length > 0)
}
}
}
</script>
I'm guessing this has to do with Vue trying to be efficient, and therefore not rerendering everything. Is there therefore any way to force a rerender, or is there any other workaround?
EDIT: JSFiddle https://jsfiddle.net/f6s5qzba/
I'm vague about I should be using in a sort of a simulation app where the user is presented with a web page that presents data from multiple domains and provides a variety of interactions that touch multiple domains.
In this case it is a real estate simulation where the UI presentation shows the user data about houses, offer to buy and sell, status of the users negotiations, etc, information about "state of the world" and that kind of thing. A fair amount of ajax going on in the page as well.
Can I just have a controller which is not associated with a particular domain and then just provide all the different objects? Maybe use a command object to deal with actions coming back from the user?
Hopefully this quesiton is not too vague for a coherent answer, I'm just looking for suggestions on the high level approach.
Yes, you can have a controller which does not directly correlate to a specific domain. For instance you could create a DashboardController. The use of command objects is up to you and your needs, but you can use Domain instance in the above controller just like any other controller.
As #Joshua Moore stated, it's no problem, let me give a small - shortened - example. (hope it gives you a bit of an idea...)
I use in the application a bootstrap-theme and the information on the dashboard (several statistic widgets) is generated through ajax-calls into the dashboard-controller.
First, the UrlMappings.groovy file:
class UrlMappings {
static mappings = {
"/$controller/$action?/$id?(.$format)?"{
constraints {
// apply constraints here
}
}
"/"(controller: "dashboard", action:"index")
"500"(view:'/error')
}
}
Then the controller-code:
package example
import java.util.Random
import grails.converters.JSON
import groovy.time.TimeCategory
class DashboardController {
def index() {}
def contractAmountAsJson() { ...someCode; return Data as JSON... }
}
Then the index.gsp page:
<!DOCTYPE html>
<html>
<head>
<meta name="layout" content="main">
<g:set var="entityName" value="${message(code: 'syParameter.label', default: 'SyParameter')}" />
<title><g:message code="default.list.label" args="[entityName]" /></title>
</head>
<body>
<!-- NEW WIDGET START -->
<article class="col-xs-12 col-sm-6 col-md-6 col-lg-6">
<!-- Widget ID (each widget will need unique ID)-->
<div class="jarviswidget" id="wid-id-8" data-widget-editbutton="false">
<header>
<span class="widget-icon"> <i class="fa fa-bar-chart-o"></i> </span>
<h2>Vertragsvolumen aktiver Kunden-Verträge pro Monat</h2>
</header>
<!-- widget div-->
<div>
<!-- widget edit box -->
<div class="jarviswidget-editbox">
<!-- This area used as dropdown edit box -->
</div>
<!-- end widget edit box -->
<!-- widget content -->
<div class="widget-body no-padding">
<div id="customerContractAmount" class="chart no-padding"></div>
</div>
<!-- end widget content -->
</div>
<!-- end widget div -->
</div>
<!-- end widget -->
</article>
</body>
</html>
And the javascript as an example:
if ($('#customerContractAmount').length) {
$.ajax({
url: '${request.contextPath}/dashboard/contractAmountAsJson?type=customer',
dataType: 'json',
success: function(chartData) {
Morris.${session?.user?.statisticStyle ? session.user.statisticStyle : "Area"}({
element : 'customerContractAmount',
data : chartData,
xkey : 'period',
ykeys : ['a', 'b', 'c'],
labels : ['bestätigt', 'erstellt', 'in Arbeit']
});
}
});
}
I'm learning meteor, and finding all kinds of difficulties dealing with nested subviews. Since the application I want to write is full of them... that looks like a difficulty. I found this on github, as a readme for a Meteor project to try and deal with this problem.
"I've been playing around with Meteor for a couple weeks. The ease of setup and the powerful reactivity makes this something I want to stick with. I was however frustrated by the difficulty of programmatically configuring, instantiating, destroying and nesting subviews."
Is this an issue that can be handled in Meteor (without adding a lot of complicated work arounds) or should I look for a different platform ?
I love nesting templates. I get reliable results. I now program off a library of both templates and helper functions (usually for form elements) that compose html for me. HTML is a byproduct, and the files we call .html are really a javascript DSL.
There are many S.O. issues raised about insertions into sorted lists giving people problems. I haven't had time to look.
My rule of thumb: Meteor is (well) designed from the beginning to do this easily and reliably.
So far the harder thing to solve was when I added an accordion from foundation, and a refresh of the document led to its initial state (being all closed, or one open). I had to put code in that saved the current section, and code to re-assert that in the rendered callback for the template that used it.
Why not write a prototype of the nesting with just a field or two in places, and find what bothers you?
Here is a sample chain. You see all the nested templates. This template itself is running within multiple.
First template: called 'layout', suggested by iron router. Has basic page and menu. Main body is a yield, set by router. On a sample page, a route calls template 'availability'
<template name='availability'>
{{#each myAgents}}
<form class="custom" id="Agent_{{_id}}" action="">
<div id='availability' class="section-container accordion" data-section="accordion">
<section id="services">
<p class="title" data-section-title><a href="#">
Your Info
</a></p>
<div class="content" data-section-content>
{{>services}}
</div>
</section>
<section id="skills">
<p class="title" data-section-title><a href="#">
Skills
</a></p>
<div class="content" data-section-content>
{{>skills}}
</div>
</section>
<section id="sureties">
<p class="title" data-section-title><a href="#">
Sureties
</a></p>
<div class="content" data-section-content>
{{>sureties}}
</div>
</section>
<section id="time">
<p class="title" data-section-title><a href="#">
Time Available
</a></p>
<div class="content" data-section-content>
{{>time}}
</div>
</section>
<section id="schedule1">
<p class="title" data-section-title><a href="#">
Schedule 1
</a></p>
<div class="content" data-section-content>
{{>schedule}}
</div>
</section>
<section id="schedule2">
<p class="title" data-section-title><a href="#">
Schedule 2
</a></p>
<div class="content" data-section-content>
{{>schedule}}
</div>
</section>
<section id="distance">
<p class="title" data-section-title><a href="#">
Distance
</a></p>
<div class="content" data-section-content>
{{>distance}}
</div>
</section>
</div>
</form>
{{/each}}
</template>
sample further nest:
<template name='services'>
{{label_text fname='name' title='Agent Name' placeholder='Formal Name' collection='agent' passthrough='autofocus=autofocus ' }}
{{label_text fname='agentInCharge' title='Agent In Charge' placeholder='Owner' collection='agent' }}
{{label_text fname='phone' title='Phone Number(s)' placeholder='Include Area Code'collection='agent' }}
{{>gps }}
<h4>Not shared:</h4>
{{label_text fname='email' title='Email:' placeholder='you remain anonymous' collection='agent' }}
</template>
and label_text is a helper, learned from the https://github.com/mcrider/azimuth project:
generateField = (options) ->
options.hash.uniqueId = options.hash.fieldName + "_" + Math.random().toString(36).substring(7) if options.hash.template is "wysiwyg"
options.hash.id = options.hash.id or #_id
options.hash.value = options.hash.value or this[options.hash.fname]
# allow for simple params as default
options.hash.title = options.hash.title or options.hash.fname
options.hash.template = options.hash.template or "label_text"
options.hash.placeholder = options.hash.placeholder or options.hash.title
# compatible with old
options.hash.fieldName = options.hash.fieldname or options.hash.fname
options.hash.label = options.hash.label or options.hash.title
# FIXME: Return error if type not valid template
new Handlebars.SafeString(Template[options.hash.template](options.hash))
Handlebars.registerHelper "label_text", (options) ->
options.hash.collection = options.hash.collection or 'generic'
generateField.call this, options
I am fairly new to Meteor, but I found out really soon that I wanted nested views (aka dynamic includes or sub-templates). I'm not sure whether this is what you mean, but here is my solution.
I created the following handlebars helper, that can be used to create sub-templates:
Handlebars.registerHelper('subTemplate', function(container, property, context, options) {
if (container && container.hasOwnProperty(property)) {
var subTemplate = container[property];
if (typeof subTemplate === 'function') {
return new Handlebars.SafeString(subTemplate(context || this));
}
else if (typeof subTemplate === 'string') {
return new Handlebars.SafeString(Template[subTemplate](context || this));
}
}
});
It can be used inside something I call a generic template. For example to create a list:
<template name="item_list">
<ul class="items-list">
{{#each items}}
<li class="listview-item">
{{subTemplate .. 'listItem' this}}
</li>
{{/each}}
</ul>
</template>
Now invoking this generic template requires that a 'listItem' property is present within its context. This can be either a string with the name of the sub-template, or the inline definition of a sub-template. The example below shows both options:
<template name="my_list">
{{! First option, referring to the sub-template by name:}}
<div>
{{#with listData listItem="my_list_item"}}
{{> item_list}}
{{/with}}
</div>
{{! Second option, inlining the sub-template:}}
<div>
{{#with listData}}
{{#assignPartial 'listItem'}}
<span>{{name}}</span>
{{/assignPartial}}
{{> item_list}}
{{/with}}
</div>
</template>
<template name="my_list_item">
<span>{{name}}</span>
</template>
Template.my_list.listData = function() {
return {
items: collections.people.find()
};
};
The second option requires an extra handlebars helper.
Handlebars.registerHelper('assignPartial', function(prop, options) {
this[prop] = options.fn;
return '';
});
I made more of these kinds of useful helpers, at some point I will probably share them on GitHub.
Code sample
'someproc' is a custom processor which extends org.broadleafcommerce.common.web.dialect.AbstractModelVariableModifierProcessor from broadleaf platform.
<myproc:someproc /> // as a result is objectCreatedInProcessor
<div th:classappend="${objectCreatedInProcessor==null?'null':'not_null'}></div>
<div th:classappend="${objectAddedToModelAndView==null?'null1':'not_null_1'}></div>
<div th:each="someVar : ${someVars}">
<div th:classappend="${objectCreatedInProcessor==null?'null':'not_null'}></div>
<div th:classappend="${objectAddedToModelAndView==null?'null1':'not_null_1'}></div>
</div>
<div th:classappend="${objectCreatedInProcessor==null?'null':'not_null'}></div>
<div th:classappend="${objectAddedToModelAndView==null?'null1':'not_null_1'}></div>
As a output result will be :
<div class='not_null'></div>
<div class='not_null_1'></div>
<div>
<div class='null'></div>
<div class='not_null_1'></div>
<div class='null'></div>
<div class='not_null_1'></div>
<div class='null'></div>
<div class='not_null_1'></div>
</div>
<div class='not_null'></div>
<div class='not_null_1'></div>
supposing we have three items into $someVars list.
The question is, why is $objectCreatedInProcessor beeing made NULL into th:each loop. And why variable $objectAddedToModelAndView isn't made NULL, and is accessible into th:each loop?
What I'm doing wrong? Is something what I miss?
EDIT1 : Closed conditional expression. This wasn't the reason of the problem, it was only a bad code sample.
EDIT2 : Closed classes into result display.
EDIT3 : Forogot to mention that $someVars is a variable added from a controller to spring ModelAndView.
It appears as if you are not properly closing the conditionals on your ternary functions. Add a } after the null and before the ? on each line.
Here is an example ternary from the docs for reference
'User is of type ' + (${user.isAdmin()} ? 'Administrator' : (${user.type} ?: 'Unknown'))