Plone best practice for embedding of objects by uid - plone

I have a Plone 4 site where I currently use the following method to embed objects (e.g. images, videos, tables …) in user-editable HTML content:
I have a custom transform browser which takes HTML text and transforms all a and img elements which refer to an element by UID (i.e., which have an href="…/resolveuid/abc123…" or src="…/resolveuid/abc123…").
My view templates read the text field and let that browser transform it;
the browser has a Python dict TYPE2TEMPLATE which has portal_type keys and template_id values;
for each a or img which refers to an object by UID,
the object is fetched by o = brain._unrestrictedGetObject()
the template id t_id is taken from the TYPE2TEMPLATE dict
the "embed" method is fetched by method = o.unrestrictedTraverse(t_id)
that method is called (in some cases with some keyword arguments), and the result - which is contained in one top HTML element - replaces the "raw" a or img element.
Now that I'm developing an additional customization package (which contains new object types, now using Dexterity), I wonder whether there is some more "plonish" way. Is there, for example, some embed action?

i don't know of a package that does the same and what you're doing sounds sane to me ;-)
i just would use https://pypi.python.org/pypi/plone.outputfilters instead of your transform BrowserView.
if it's possible to explicitly mark links that should not be auto-embedded (eg via span.noEmbed a.internal-link selector) this could become a useful addon.
i guess for portal_type=='File' you'll need to check the mimetype too in order to decide if you're embedding a video file or something else...
other products i know of embed content outside of your plone site (eg. collective.embedly)
another approach would be a to use a tinymce plugin to genereate the proper embed html when editing the html-body of your page (i personally would not go this route because there are different tiny versions to support for 4.3 and 5.0 and we're not sure if tiny woun't be replaced as default editor in the future)

Related

When using apoc.load.html, Is it possible to return the full HTML rather than only text?

Lets say I want to scrape the Neo4j RefCard found at: https://neo4j.com/docs/cypher-refcard/current/
And I would like to fetch a 'code' example along with its styling. Here's my target. Notice that it has CSS treatment (font, color...):
...so in Neo4j I call the apoc.load.html procedure as shown here, and you can see it's no problem finding the content:
It returns a map with three keys: tagName, attributes, and text.
The text is the issue for me. It's stripped of all styling. I would like for it to let me know more about the styling of the different parts of this text.
The actual HTML in the webpage looks like following image with all of these span class tags: cm-string, cm-node, cm-atom, etc. Note that this was not generated by Neo4j's apoc.load.html procedure. It came straight from my Chrome browser's inspect console.
I don't need the actual fonts and colors, just the tag names.
I can seen in the documentation that there is an optional config map you can supply, but there's no explanation for what can be configured there. It would be lovely if I could configure it to return, say, HTML rather than text.
The library that Neo4j uses for CSS selection here is jsoup.
So I am hoping to not strip the <span> tags, or otherwise, extract their class names for each segment of text.
Could you not generate the HTML yourself from the properties in your object? It looks they are all span tags with 3 different classes depending on whether your using the property name, property value, or property delimiter?
That is probably how they are generating the HTML themselves.
Okay, two years later I revisited this question I posted, and did find a solution. I'll keep it short.
The APOC procedure CALL apoc.load.html is using the scraping library Jsoup, which is not a full-fledged browser. When it visits a page it reads the html sent by the server but ignores any javascript. As a result, if a page uses javascript for inserting content or even just formatting the content, then Jsoup will miss the html that the javascript would have generated had it run.
So I have just tried out the service at prerender.com. It's simple to use. You send it a URL, it takes your url as an argument and fetches that page itself and executes the page's javascript as it does. It returns the final result as static HTML.
So if I just call prerender.com with apoc.load.html then the Jsoup library will simply ask for the html and this time it will get the fully rendered html. :)
You can try the following two queries and see the difference pre-rendering makes. The span tags in this page are rendered only by javascript. So if we call it asking for its span tags without pre-rendering we get nothing returned.
CALL apoc.load.html("https://neo4j.com/docs/cypher-refcard/current/", {target:".listingblock pre:contains(age: 38) span"}) YIELD value
UNWIND value.target AS spantags
RETURN spantags
...but if we call it via the prender.com website, you will get a bunch of span tags and their content.
CALL apoc.load.html("https://service.prerender.cloud/https://neo4j.com/docs/cypher-refcard/current/", {target:".listingblock pre:contains(age: 38) span"}) YIELD value
UNWIND value.target AS spantags
RETURN spantags

Django Rest Framework render_form & required fields

When using HTML form renderer in DRF, can anyone think of a nice way to auto generate some indication of "required" field in DRF, by hook or crook? I mean before I submit the form, some indication on the field that it is required - the Browsable API it will show right in the form what the error is but only after submitting.
Whether I am using technique as shown here for browseable API with field level HTML forms (instead of just raw/JSON form):
django-rest-framework - autogenerate form in browsable API?
Or I am using TemplateHTMLRenderer with a call to render_form as discussed in docs here:
http://www.django-rest-framework.org/topics/html-and-forms/#rendering-forms
I don't see a simple way to make my required fields rendered as required. So say we have like
#models.py
class Foobar(model.Models):
foo = models.CharField(max_length=100, blank=True, default='')
bar = models.CharField(max_length=100, blank=False)
The best I can think of is making my own template/snippet for each type of field "required-text-field.html", "required-checkbox.html", etc and using the style declaration in the serializer as shown here:
http://www.django-rest-framework.org/topics/html-and-forms/#field-styles
That's assuming I am understanding this, have not played with it yet to see.
But I would love to see a way to auto-generate the field with/without a required flag as appropriate (even just an asterisk, or applying a CSS class) based on the model definition.
Rambling: The goal here was to avoid writing my own forms, having DRF generate the form for me in custom views. As opposed to writing my own forms using tying them into AJAX I figured templates, render_form, and some format checks would suffice. But now I'm thinking DRF is built for back-end and dev, not front-end, and maybe I should plan to write my own forms if it will be end-user visible? Also I could have CSS files and select based on name, calling render_form then applying hand spun styles, would be less work than the HTML + the CSS. Should I review Django (just Django, not DRF) Forms and re-use serializer as validation?...
I can see 2 ways:
you can define your own template pack, look at the existing ones in the sources (e.g. 'rest_framework/horizontal/input.html') - you can check if field is required and according to this flag, set some css. you do not need something extra, especially "input-readonly.html" - just make your own copy of input.html, add few if-s and it will work.
or you can call OPTIONS on the API endpoint to get all the necessary information about fields, not only required, but readonly and allowed values for some selects - this is if you can update your forms from javascript

What are valid HTML5 custom tags?

Recently I've been reading about how you can make custom tags valid in HTML5 by putting a dash in the name, so I've been wondering what the actual rules / guidelines are for custom tags.
custom-tag √
custom X
-custom ?
custom- ?
What I want to know is if the last two are valid.
Also, as a bonus, I'm kind of curious about how custom attributes work.. as far as I know:
<div my-attribute="demo"> X
<div data-my-attribute="demo"> √
<custom-tag my-attribute="demo"> √
<custom-tag data-my-attribute="demo"> √
But what happens if I'm trying to use existing global attributes, such as title or class?
Does this CSS..
custom-tag.banana {
color: yellow;
}
target this HTML?
<custom-tag class="banana">
Test!
</custom-tag>
Also, this CSS should target the above HTML whether or not global attributes work with custom tags, correct?
custom-tag[class=banana] {
color: yellow;
}
Finally, is there a rule/guideline stating I should have a "-" in the name of my custom attribute, like custom tags? E.g. <div custom-tag="demo">. If there is, like my original question, does it work with -customtag, and customtag-?
Thanks for the help. :)
TL;DR: There are no valid custom HTML5 tags.
I think you may be referring to this Custom Element Working Draft proposed by the Web Applications Working Group, which describes this:
The custom element type identifies a custom
element interface and is a sequence of
characters that must match the NCName
production, must contain a U+002D HYPHEN-MINUS
character, and must not contain any uppercase
ASCII letters. The custom element type must not
be one of the following values:
annotation-xml
color-profile
font-face
font-face-src
font-face-uri
font-face-format
font-face-name
missing-glyph
Additionally, according to HTML5 specification, HTML tag names can only start with ASCII letters. If we assume that the Custom Element proposal does not propose any changes to the HTML Syntax specification, then elements starting with hyphens-minus character is not a valid HTML tag name. If we combine what the Custom Element Working Draft proposal and the HTML5 Syntax specification says, then we can conclude that <-custom> is not a well-formed HTML and so cannot be a valid Custom Element because the tag name does not start with ASCII letter. On the other hand, custom- is both a well-formed HTML and a valid Custom Element.
Note that Custom Element is a Working Draft, not a W3C Recommendation. This means that Custom Elements is not valid in HTML5. Don't get your hopes up either, a lot of Working Drafts that are proposed in W3C never got anywhere (and for good reasons too, not all of the proposals are good).
<rant>Personally I hope that this proposal got shot down. I spent some time reading this proposal, it looks like this proposal tried to reinvent XML Namespace and SGML poorly, and probably forgot about what HTML and the semantic web is supposed to be. In any case, HTML5 syntax already allows authors to use elements that aren't specified in HTML5 specification, I don't see any need to standardize how to create custom elements any further than that. I hope that there would be people in HTML5 working group sane enough to realize how bad this proposal is and vote this proposal off. Keep HTML5 closed from author-defined custom modifications.</rant>
If you want to define your own custom vocabularies, I suggest you should write an XML application with XHTML5, which actually specifies how you can define your own custom elements with XML namespaces. Unlike HTML, XML is designed to be extensible.
As for your question about custom data attribute, this is what the HTML5 specification says:
A custom data attribute is an attribute in no namespace whose name starts with the string "data-", has at least one character after the hyphen, is XML-compatible, and contains no uppercase ASCII letters.
So with your examples, these are valid data-* attributes:
data-my-attribute
while these are not:
my-attribute
As far as I can tell, the Custom Elements Working Draft does not specify any additional syntactical requirement for custom attributes on Custom Elements, nor does it explicitly permit using arbitrary non-data-* attributes and how custom attributes interacts with existing HTML attributes, although we can reasonably infer that allowing custom attributes is probably the intent of the proposal.
As for your question about CSS, yes you understood correctly, those are valid CSS selectors to target those Custom Elements. CSS can be used to style any elements, not just elements defined by HTML, but also other markup languages like SVG, MathML, as well as arbitrary XML vocabularies when using XHTML. The CSS Selectors specification does not actually depend on HTML vocabulary in any substantial way (although HTML is used heavily in the examples, as it's what most people are most familiar with). It is for this reason that CSS Selector syntax can be used to refer to any elements in the document, including custom elements that aren't specified in the HTML specification. Styling custom tag already works in all major browsers today. You can use any arbitrary tag names, and select them with the selector that you expect, and CSS will style them as you would expect them to be. There is no requirement for having hyphen-minus in the tag name for this to work.
To pass validation, all attributes you add that aren't available for the element by default should be prefixed with data - it has nothing to do with it containing a dash or not.
Targeting these in CSS is done by using something like element[data-attribute].
So this is valid: <div data-title="Custom Data Title"></div>,
this would not be : <div custom-title="Custom Title"></div>.
Targeting could be done by using div[data-title="Custom Data Title"]{}
Concerning tags, you are limited to the tags provided by the browser if you want your site to validate. You cannot use custom elements willy-nilly, as it increases processing of your page.
You can use javascript to require a page to recognise certain tags, but it still won't validate. This will work, but is not advised:
<script type="text/javascript">document.createElement("custom");</script>
<custom data-name="Something">Here</custom>
Theres more info here: https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Using_data_attributes
HTML5 does not have a specific doctype definition or an XML schema definition.
It is possible to create custom HTML tags (custom elements) as they can be used to create web components
Custom attributes are also valid as they can serve to supply a web component with required information
e.g.
<custom-element a="x" b="y"/>

Creating custom layouts for Images in page content TYPO3 6

Typo3 provides option to add multiple images to a page content, but all the images are wrapped under some default <div> tags. I want these images to be wrapped under <ul> and <li> tags instead and giving my own custom CSS ids and classes to it.
There are not many resources on TYPO3 for me to approach this issue. Can TYPO3 allow to use custom tags for the page content elements?
UPDATE
From Jost's answer was able to get my images displayed, but how do I split the image details?
My each image will have title, alt-text, image-path and image-link. Now, using TypoScript how do I retrieve this, because each details has to go in separate tags.
Check the TypoScript object browser. There you will find the object tt_content, which contains the rendering definitions for content elements. The rendering definition for images is found at tt_content.image.20, for example
tt_content.image.20.imageStdWrap.dataWrap = <div class="csc-textpic-imagewrap" style="width:{register:totalwidth}px;"> | </div>
The default definitions given there are usually provided by the static TypoScript of CSS-styled-content. You can overwrite them in your own TS, but when updating to a newer TYPO3-version, the default template may change, which could result in additional wrappers.
Update
Most content rendering in TYPO3 is defined in the TypoScript object tt_content. You can browse all TS-objects that will be used on a page by selecting the "Template" module and the page in question, and then choose "TypoScript Object Browser" in the selectbox at the top of the window. To understand what that stuff means, knowledge of TypoScript is necessary (Tutorial, Reference).
You can add your own TypoScript, which may override existing settings. You can do that in the Template-module too, but usually this is done by creating a file containing the script somewhere in the fileadmin folder and including it from the Template module.
The above enables you to edit the markup of the page. (Additional) CSS is usually defined in external files, that are included by a PAGE object (see the reference about that).
This post is a bit older but I want to add the following:
If you want to understand how the different content elements are wrapped, you may have a look into the css_styled_content extension. I assume that you have included the "Static Template (from extension)" in your main Typoscript template.
You can find the setup.txt here:
typo3/sysext/css_styled_content/static/setup.txt
There you´ll find the line Jost mentioned in line 860 (TYPO3 version 6.1), for example. And of course a lot of other definitions, too.
But check to read the documentation and tutorials on typo3.org.
HTH
merzilla

How can we save multimedia components using external resource types if the URL doesn’t end in with a file extension?

We have a Tridion use case related to curated content where we are creating multimedia components for images associated with our content which are pointing to External resource types instead of uploaded resource types.
One of the issues we have run into with this use case is that despite explicitly setting the Multimedia Type for the resource, if the URL of the image has either a query string in it: http://cdn.hw.net/UploadService/1c8b7f28-bb12-4e02-b888-388fdff5836e.jpg?w=160&h=120&mode=crop&404=default or uses a ‘friendly url’: http://www.somewhere.com/images/myimage/ when we save the component, Tridion barfs with error messages similar to : ‘Invalid value for property 'Filename'. Unexpected file extension: jpg?w=160&h=120&mode=crop&404=default. Expecting: jpg,jpeg,jpe.’
So far, the only way we’ve been able to figure out to potentially get around this issue is to do something hacky like appending an extra query string parameter to the very end of the urls which end with the expected file extension: http://cdn.hw.net/UploadService/1c8b7f28-bb12-4e02-b888-388fdff5836e.jpg?w=160&h=120&mode=crop&404=default&ext=.jpg Obviously, this is not the best solution and in fact may not work for some images if the site they are being served from strictly validates the requested URL.
Does anyone have any ideas on how we can work around this issue?
Unfortunately I can't really think of an easy solution to this, since Tridion "detects" the Mime type by checking the file extension.
You could perhaps add it while saving and remove it when reading (via Event System)? Definitely a worthwhile enhancement request, to my knowledge this behavior has not been changed for the soon-coming Tridion 2013... See comment below, it has been changed for 2013.
+1 for Nuno's answer. Recognizing that the title of your question is specific to multimedia components, you may want to consider another approach which is to use normal Components, not Multimedia Components. You can create a normal component schema called something like "External Image" that has an External Url field to store your extentionless url.
Content authors will then include these images via regular component linking mechanisms in the Tridion GUI.
You will then need a custom link resolver TBB that will parse the Output item (via Regex) looking for any Tridion anchor tags <a tridion:href="tcm:x-y-z"> and for each one replace them with an <img src=...> tag where the src path would come from this linked component.
For an example of a similar approach, but with videos, and sample code for a custom link resolver TBB have a look at the code in the following post: http://www.tridiondeveloper.com/integration-sdl-tridion-jw-media-player.

Resources