Catalog Result By Positional Order in Contents - plone

I want to have catalog result displayed using the following codes from my Archetypes package. The issue is the displayed listing not according to the positional order in Contents tab. What am I missing?
class BookView(BrowserView):
implements(IBookView)
def get_chapters(self):
context = aq_inner(self.context)
catalog = getToolByName(context, 'portal_catalog')
folder_path = '/'.join(context.getPhysicalPath())
results = catalog(
path={'query': folder_path, 'depth': 1},
portal_type=('File', 'Chapter')
)
return results
<div class="books-pdf"
tal:define="chapters view/get_chapters"
tal:condition="chapters">
<span class="listname"
i18n:translate="">Chapter Name</span>
<span class="iconname"
i18n:translate="">File Type</span>
<span class="sizename"
i18n:translate="">File Size</span>
<tal:chapters repeat="chapter chapters">
...

The catalog returns items in internal order unless you explicitly request an order. You can do so with the sort_on parameter, which should be the name of an index to use for the sorting.
Most indexes can be used for sorting, with the notable exception being full text indexes (which is why there is a sortable_title index in the Plone catalog).
You probably want to sort on the getObjPositionInParent index, which holds the index of each object in it's container:
results = catalog(
path=dict(query=folder_path, depth=1),
portal_type=('File', 'Chapter'),
sort_on='getObjPositionInParent',
)

You need to sort results by this index:
getObjPositionInParent

Related

DynamoDB Java SDK query to match items in a list

I'm trying to use SQL IN clause kind of feature in dynamoDB. I tried using withFilterExpression but I'm not sure how to do it. I looked at similar questions as they were too old. Is there a better method to do this? This is the segment of code I have got. I have used a static List as example but it is actually dynamic.
def getQuestionItems(conceptCode : String) = {
val qIds = List("1","2","3")
val querySpec = new QuerySpec()
.withKeyConditionExpression("concept_id = :c_id")
.withFilterExpression("question_id in :qIds") // obviously wrong
.withValueMap(new ValueMap()
.withString(":c_id", conceptCode));
questionsTable.query(querySpec);
}
I need to pass qID list to fetch results similar to IN clause in SQL Query.
Please refer to this answer. Basically you need to form key list/value list dynamically
.withFilterExpression("question_id in (:qId1, :qId2, ... , :qIdN)")
.withValueMap(new ValueMap()
.withString(":qId1", ..) // just do this for each element in the list in a loop programmatically
....
.withString(":qIdN", ..)
);
Mind there is a restriction on maxItems in 'IN'

JSViews Merge id with string to get unique id

I have an array which I am iterating over using
{{for}}
in the loop, I am creating various elements, one of which I need to generate unique Ids for include one of the variables in the array (Id)
so for example:
<div id="post-123">...
I have tried:
<div data-link="id{post-:Id}">...
and
div data-link="id{'post-':Id}">...
and
<div id="post-" data-link="id{merge:Id}">...
however none of these work.
if I omit the string and just use:
<div data-link="id{:Id}">...
it sets the Id just fine. Can anyone see what I am doing wrong?
These links talk of data-linking to attributes:
http://www.jsviews.com/#linked-elem-syntax
http://www.jsviews.com/#link-elemattribs
http://www.jsviews.com/#samples/data-link/attributes
The standard syntax is
data-link="attributeName{:dataPathOrExpression}"
In your case attributeName is id.
dataPathOrExpression can be any expression, so here you need it to be the Id value concatenated with (preceded by) the string 'post-', so you need to write:
<div data-link="id{:'post-' + Id}">...
or, equivalently
<div data-link='id{:"post-" + Id}'>...
You don't want to put anything between the { and :. The tag is {: (http://www.jsviews.com/#assigntag) - and the only thing you can put between those characters is a converter name such as myCvt, as in: id{myCvt:...}.
That said, if your Id values are not changing observably, then you don't need to data-link the id and you can instead write:
<div id="post-{{:Id}}">...
just as you would if you were rendering the template as a JsRender template, without data binding.

Plone Dexterity forms- Is it possible to set the default of a field equal to a value returned from a function in Add form?

I have a dexterity content type and I have been following along with the schema-driven types tutorial from the Dexterity Manual (http://docs.plone.org/external/plone.app.dexterity/docs/schema-driven-types.html#the-schema) and I am trying to change the default value of a field.
The value being returned is based on a portal catalog search. The field is an int type in which I want it equal to the highest number + 1 of the field in question. Because this is a field I want to hide, I figured maybe it would be possible to set the default value through returning a value from a function
value into the default parameter of a field.
Here is my Interface:
class ISupplier(model.Schema):
"""
Supplier of an asset or services
"""
supplier_id = schema.Int(
title=_(u"Supplier ID"),
description=_(u"ID that links to the database"),
required=True,
default=newID
)
...
Here is my function that I am trying to use to return a value. It is outside of classes.
#grok.provider(IContextSourceBinder)
def newID(context):
limit = 1
catalog = getToolByName(context, 'portal_catalog')
result = catalog.searchResults(portal_type='gpcl.supplier.supplier',
sort_on='supplier_id',
sort_order='descending',
sort_limit=limit
)[:1]
return result.supplier_id + 1
The reason I thought it'd be possible to do something like this is because in a choice type field I set the source equal to a value returned from a function:
form.widget(supplierType=CheckBoxFieldWidget)
supplierType = schema.List(title=u'Types',
value_type=schema.Choice(source=supplierTypes),
required=True
supplierTypes, the function, starts off like this:
#grok.provider(IContextSourceBinder)
def supplierTypes(context):
"""
"""
...
I did try using default_value:
#form.default_value(field=ISupplier['supplier_id'])
def supplierIDDefaultValue(data):
defaultID = newID
return defaultID
This did not work unfortunately. I believe I actually may be having a misunderstanding altogether. If I could have any help, I would greatly appreciate it.

Xquery group by on 2 tags

Below is the XML part of my data.
<A>
<a><Type>Fruit</Type><Name>Banana</Name></a>
<a><Type>Fruit</Type><Name>Orange</Name></a>
<a><Type>Fruit</Type><Name>Apple</Name></a>
<a><Type>Fruit</Type><Name>Lemon</Name></a>
<a><Type>Cars</Type><Name>Toyota</Name></a>
<a><Type>Cars</Type><Name>Lamborghini</Name></a>
<a><Type>Cars</Type><Name>Renault</Name></a>
</A>
Out put as -
<a>Fruits-Banana,Orange,Apple,Lemon</a>
<a>Cars-Toyota,Lamborghini,Renault</a>
I tried to get the required output by all in vain. I tried 'group by` clause too, but getting errors.
any help?
let $x:=
<A>
<a><Type>Fruit</Type><Name>Banana</Name></a>
<a><Type>Fruit</Type><Name>Orange</Name></a>
<a><Type>Fruit</Type><Name>Apple</Name></a>
<a><Type>Fruit</Type><Name>Lemon</Name></a>
<a><Type>Cars</Type><Name>Toyota</Name></a>
<a><Type>Cars</Type><Name>Lamborghini</Name></a>
<a><Type>Cars</Type><Name>Renault</Name></a>
</A>
for $z in distinct-values($x//a/Type)
let $c := $x//a[Type=$z]/Name
return
<a>{concat($z, "-", string-join($c, ","))}</a>
First for is taking the distinct values of the tag Type, then for each distinct value of this, the respective values of all the Name tags are derived.
Then using the concat function I have concatenated the Type text with the string generated by string-join, used to add/append the Name and , (comma).
HTH :)

sort collection items by getObjPositionInParent

I would like to have getObjPositionInParent as a sort criteria in a collection. I configured it as "available" in the site setup for collection views. But it is not available. Did I forget something?
You didn't forget anything, but found a bug in Plone. The GopipIndex from plone.app.folder is used for the getObjPositionInParent index. But this index type is not registered for any collection criteria. The criterion registry in Products.ATContentTypes.criteria needs to include a mapping for the GopipIndex. Likely adding it to the SORT_INDICES list would be the right thing to do. To do this from outside, you can do something like:
# Make sort criteria available for the GopipIndex
from Products.ATContentTypes.criteria import _criterionRegistry
crit_reg = _criterionRegistry
crit_id = 'ATSortCriterion'
index = 'GopipIndex'
indices = crit_reg.criterion2index.get(crit_id, ())
crit_reg.criterion2index[crit_id] = indices + (index, )
value = crit_reg.index2criterion.get(index, ())
crit_reg.index2criterion[index] = value + (crit_id, )

Resources