I am still running Plone 3.0.6 for our Intranet. I have tried to upgrade to current version, but always come up against a road block. I'll have another go at that later when I have more time.
For now, I just need to customise /portal_skins/plone_content/file_view to make it open pdf attachments in the browser instead of downloading them. We are installing a new kiosk system that will display PDFs in the browser but can't browse and view files in the filesystem.
I've done a lot of searching and found others who have done this, but not for the version I'm running. I'm not a developer of any sort, so I can't figure out how to do what they have done on my system.
Here is the current code for file_view.
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"
xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal"
xmlns:i18n="http://xml.zope.org/namespaces/i18n"
lang="en"
metal:use-macro="here/main_template/macros/master"
i18n:domain="plone">
<body>
<div metal:fill-slot="main">
<tal:main-macro metal:define-macro="main"
tal:define="size python:here.getObjSize(here);
content_type here/get_content_type|here/Format;
kssClassesView context/##kss_field_decorator_view;
getKssClasses nocall:kssClassesView/getKssClassesInlineEditable">
<div tal:replace="structure provider:plone.abovecontenttitle" />
<h1 class="documentFirstHeading">
<metal:field use-macro="python:here.widget('title', mode='view')">
Title
</metal:field>
</h1>
<div tal:replace="structure provider:plone.belowcontenttitle" />
<p class="documentDescription">
<metal:field use-macro="python:here.widget('description', mode='view')">
Description
</metal:field>
</p>
<div tal:replace="structure provider:plone.abovecontentbody" />
<p>
<metal:field use-macro="python:here.widget('file', mode='view')">
File
</metal:field>
</p>
<div tal:condition="python: content_type.startswith('text')">
<h2 i18n:translate="heading_file_contents">File contents</h2>
<pre tal:content="here/get_data|here/data|nothing">
</pre>
</div>
<div metal:use-macro="here/document_relateditems/macros/relatedItems">
show related items if they exist
</div>
<div tal:replace="structure provider:plone.belowcontentbody" />
</tal:main-macro>
</div>
</body>
</html>
I've also done a search for at_download and found /Plone/portal_skins/archetypes/at_download. It contains this code:
if traverse_subpath:
field = context.getWrappedField(traverse_subpath[0])
else:
field = context.getPrimaryField()
return field.download(context)
Can anyone tell what I need to change to make PDFs view in the browser?
Currently when I select a link to a PDF it looks like this. http://intranet.internal.lan/somewhere/Test.pdf/at_download/file
I need it to look like this.
http://intranet.internal.lan/somewhere/Test.pdf
(without /at_download/file)
Any help will be greatly appreciated.
Thanks
David
I don't know if it's work in plone 3.x.x, but
I am using plone 4.1.6 and I wanted to render a pdf file
in a browser (worked in chrome and firefox) and put like this
in a page tamplate:
<a tal:attributes="href string:${edicao_url}/##images/field_pdf" target="_blank">View PDF</a>
where the url shows:
http://localhost:8080/plone_site/content-type/##images/field_pdf/
So, the field field_pdf is an attribute from a content-type!
Ah, and I am using too a content type from Dexterity!
I hope this help help you! =D
You right, you need something like this:
<object id="pdfRenderer" data="/path/to/document.pdf" type="application/pdf" style="height: 700px;">
</object>
This can be achieved by trigger a download of the file if you don't append view to the url.
For example:
http://intranet.internal.lan/somewhere/Test.pdf/view: Shows the default file view (This is Plone default)
http://intranet.internal.lan/somewhere/Test.pdf: Should trigger a download
For triggering the download you have to implement this on your file type or patch the existing one.
A possible entry point ist the FileFied index_html method.
This is a working example for Plone 4.3.x:
from plone.app.blob import field
from plone.app.blob.download import handleIfModifiedSince, handleRequestRange
from urllib import quote
from webdav.common import rfc1123_date
from zope.component import getMultiAdapter
class FileField(field.FileField):
def index_html(self, instance, REQUEST=None, RESPONSE=None,
charset='utf-8', disposition='inline'):
"""Kicks download.
Writes data including file name and content type to RESPONSE
"""
if REQUEST is None:
REQUEST = instance.REQUEST
if RESPONSE is None:
RESPONSE = REQUEST.RESPONSE
RESPONSE.setHeader('Last-Modified', rfc1123_date(instance._p_mtime))
RESPONSE.setHeader('Content-Type', self.getContentType(instance))
RESPONSE.setHeader('Accept-Ranges', 'bytes')
if handleIfModifiedSince(instance, REQUEST, RESPONSE):
return ''
length = self.get_size(instance)
RESPONSE.setHeader('Content-Length', length)
filename = self.getFilename(instance)
if filename is not None:
if isinstance(filename, unicode):
filename = filename.encode(charset, errors="ignore")
# Create a user agent specific disposition header
# IE needs an url quoted filename
# Other browsers need an unquoted filename
user_agent = REQUEST.get('HTTP_USER_AGENT', '')
if 'MSIE' in user_agent:
header_value = '%s; filename=%s' % (disposition,
quote(filename))
else:
header_value = '%s; filename="%s"' % (disposition, filename)
RESPONSE.setHeader("Content-disposition", header_value)
request_range = handleRequestRange(instance, length, REQUEST, RESPONSE)
# Notify file downloads, but do not notify range requests
if not ('start' in request_range and request_range['start'] > 0):
portal_state = getMultiAdapter((instance, instance.REQUEST),
name='plone_portal_state')
return self.get(instance).getIterator(**request_range)
You should really consider to upgrade your Plone site before implement new features, which may block you again!!
Related
I wish to embed an html map within a JustPy generated web page. I get mangled output which I guess means there's a CSS or other clash. Any ideas to get this working will be gratefully received.
import justpy as jp
def map_page(request):
wp = jp.WebPage()
jp.Div(text='iFrame with map goes here...', a=wp)
m = jp.Div(a=wp)
m.inner_html = '<iframe src = "map.html"></iframe>'
return wp
jp.justpy(map_page)
wp = jp.WebPage()
see http://ceur-ws-browser.bitplan.com/volume/400 for a working example:
http://ceur-ws.org/Vol-400/ is embedded:
headerHtml=f"""{links}<h3>{volume.h1}</h3>
<a href='{volume.url}'>{volume.acronym}<a>
{volume.title}<br>
{volume.desc}
published: {volume.pubDate}
submitted By: {volume.submittedBy}"""
iframeHtml=f"""
<iframe src='{volume.url}' style='min-height: calc(100%); width: calc(100%);'></iframe>"""
self.volumeHeaderDiv.inner_html=headerHtml
self.volumeDiv.inner_html=iframeHtml
When I get the content without DomCrawler, I get the html with custom tags like #click but when I use $this->crawler->filter('something')->html() DomCrawler is removing my #click tags.
Here an example without using DomCrawler:
And here is using DomCrawler:
As you can see, DomCrawler is removing all the #clicks, how can I stop this?
Unfortunately, you can't. DomCrawler uses DOMDocument under the hood and will not allow the "#click". Also:
The DomCrawler will attempt to automatically fix your HTML to match the official specification.
The modifiers to disable this would be LIBXML_HTML_NOIMPLIED which is not used in the addHmlContent method of DomCrawler:
//... Symfony\Component\DomCrawler\Crawler.php
$dom->loadHTML($content);
// ...
and even calling #$dom->loadHTML($content, LIBXML_HTML_NOIMPLIED); would not work in your case.
Example:
$html = <<<TEST
<html>
<div class="test" #click="something"></div>
</html>
TEST;
dump($html);
//<html>\n
// <div class="test" #click="something"></div>\n
//</html>
// Symfony Crawler
$crawler = new \Symfony\Component\DomCrawler\Crawler();
$crawler->addHtmlContent($html);
dump($crawler->html());
//<body>\n
// <div class="test"></div>\n
//</body>
// Custom crawler with LIBXML_HTML_NOIMPLIED
$crawler = new \MyCrawler\Crawler();
$crawler->addHtmlContent($html);
dump($crawler->html());
// <div class="test"></div>
You could replace the #click with x-on:click which has the exact same effect and is valid HTML at the same time.
I need to create a component that displays the content of another webpage.
So for instance if I have the site of stackoverflow, I would like to create a component that does a http request and displays the content through my app. By the way, the external website is just django-rest-swagger and to access it, I need to include a header everytime I access it. So, when I make the request for the external site content I need to inlclude the header x-forwarded-host.
<div>
<html> CONTENT OF EXTERNAL WEBSITE </html>
</div>
thank you
#Component({
selector: ...
template: `<div [innerHTML]="fetchedHtml"></div>
})
export class ExternalHtml {
constructor(http:Http) {
var headers = new Headers();
headers.append('x-forwarded-host', 'foo');
http.get('someUrl', {headers: headers}).subscribe(response => {
this.fetchedHtml = response.json();
}
}
See also
In RC.1 some styles can't be added using binding syntax
Alternatively you can also use an iframe to display the fetched HTML.
You can display it as follows:
<div [innerHTML]="contentOfTheExternalWebsite">
</div>
I can view an image in index file like this :
#*#Html.DisplayFor(modelItem => item.ImagePath)*#//Instead of this, I use the line below
<img src="~/Images/#item.ImagePath" height=100 width=200>
But In details file I have this :
#Html.DisplayFor(model => model.ImagePath)
How can I view the image in details file when there is a model not item? I have done several attempts but failed all of them. Thanks.
You can use custom template and dataannotations
http://msdn.microsoft.com/en-us/library/ee308450(v=VS.100).aspx
http://www.codeproject.com/Tips/720515/Custom-HTML-Helper-for-MVC-Application
The answer should be like :
<img src="~/Images/#Url.Content(Model.ImagePath)" height=100 width=200 />
This razortag string " #Html.DisplayFor(model => model.ImagePath) " is calling the DB, getting the path and then presenting the path string as its output. In the Index view " item.ImagePath " is a variable that has been populated and currently contains the path ready for output. In the Details view, there are no variables, and the ImagePath is empty because the function has not run. Well technically it ran once but since it delivered its output to the view it is again empty by the time you try to use it. To get the ImagePath as your img src call the whole function where you are placing the image and it will run again and its output will be the ImagePath used for the img src.
This also will work in the Index view as well. The codeproject.com link in the above answer provides some relevant ideas.
"<img src="#Html.DisplayFor(model => model.ImagePath)"
I have been asked to extract info by an academic colleague from a website where I need to link the content of a webpage in a table - not too hard with the contents of a text file which is only reacheable (as far as I can tell) by clicking on a javascript link... e.g.
<a id="tk1" href="javascript:__doPostBack('tk1$ContentPlaceHolder1$grid$tk$OpenFileButton','')">
The table is conveniently inside a table with id='tk1' which is nice... but how do I follow the link which pulls the text file.
Ideally I'd like to do this in R... I can grab the relevant table in text format by saying
u <- the url of interest...
library(XML)
tables = readHTMLTable(u)
interestingTable <- tables[grep('tk1', names(tables))]
And this will give the text in the table, but how do I grab the html for that particular table? and how do I "click" on the button and get the text file behind it?
I note that there is a form with massive hidden values - the site appears to be asp.net driven and uses impenetrable URLs.
Many thanks!
This is somewhat tricky, and not fully integrated in R, but some system()-fiddling will get you started.
Download and install phantom javascript: http://code.google.com/p/phantomjs/
Check the short script on http://menne-biomed.de/uni/JavaButton.html, which emulates your case. When you click the javascript anchor, it redirects http://cran.at.r-project.org/ via doPostBack(inaccessibleJavascriptVar).
Save the following script locally as javabutton.js
var page = new WebPage();
page.open('http://www.menne-biomed.de/uni/JavaButton.html', function (status) {
if (status !== 'success') {
console.log('Unable to access network');
} else {
var ua = page.evaluate(function () {
var t = document.getElementById('tk1').href;
var re = new RegExp('\((.*)\)');
return eval(re.exec(t)[1]);
});
console.log(ua);// Outputs http://cran.at.r-project.org/
}
phantom.exit();
});
With phantomjs on path, call
phantomjs javabutton.js
The link will be displayed on the console. Use any method to get it into Rcurl.
Not elegant, but maybe someones wraps phantomjs into R one day. In case the link to JaveButton.html should be lost, here it is as code.
<!DOCTYPE html >
<head>
<script>
inaccesibleJavascriptVar = 'http://' + 'cran.at.r-project.org/';
function doPostBack(myref)
{
window.location.href= myref;
return false;
}
</script>
</head>
<body>
<a id="tk1" href="javascript:doPostBack(inaccesibleJavascriptVar)" >Click here</a>
</body>
</html>
Have a look at the RCurl package:
http://www.omegahat.org/RCurl/