Open jesperlandberg opened 6 years ago
I have the same question.
your application, which is doing the rest call, already needs infos like
so whatΒ΄s the deal adding a:
to your existing config ? π€
@michabbb Not sure I follow.
@jesperlandberg ah, you mean path on the server, not url to open that image in the browser, right ? π
@michabbb correct=)
@jesperlandberg pardon, misunderstanding π π
Since this cms is mainly used as a "headless" cms, it would just make sense to serve absolute image paths, because more often than not is this cms hosted on a different domain than the frontend. Even if this would be an opt-in option.
@michabbb Your suggestion might be okay in a "smaller" frontend environment, but it becomes a pain when you have to deal with a ton of components, services and maybe even multiple apps, which all get their data from this cms. To feed a "image_url"-variable through everything is just a unnecessary pain.
@nisdec i am just evaluating this cms at the moment, thats why i am interested in some issues here. as i said, sorry - misunderstanding here π beside the fact that there exists NULL docu about "howto write an addon", i really like what i see, so far. and yes, i understand you.
It's an oft-requested feature https://github.com/agentejo/cockpit/issues/695 and one we've argued with @aheinze about before https://github.com/agentejo/cockpit/issues/470
Create a file /config/bootstrap.php
with this content:
<?php
/*
copy this code to `/config/bootstrap.php`
When you save an asset, absolute_path and real_path are added automatically.
*/
$app->on('cockpit.assets.save', function(&$assets) use ($app) {
foreach ($assets as &$asset) {
// add paths
$asset['absolute_path'] = $app['site_url'] . $app['base_url'] . '/storage/uploads' . $asset['path'];
$asset['real_path'] = COCKPIT_DIR . '/storage/uploads' . $asset['path'];
}
});
or $app->on('collections.save.before', function(...
for all collections.
Now all assets have absolute_path
and real_path
, when they are saved.
The trigger collections.find.before
doesn't allow to modify data, so it's necessary to create the path when saving the entry.
edit: replaced code with a much better solution
@raffaelj Thank you for your solution!
Unfortunately I get the following error when I try your solution:
Warning: Parameter 1 to LimeExtra\App::{closure}() expected to be a reference, value given in /cms/lib/Lime/App.php on line 592
Any idea?
@nisdec I can't reproduce it. Can you explain, what you did before? Did you use the assets manager or image-field or asset-field or the api...? Maybe you have a typo...
Do you use the (latest) next branch or master? Is your PHP version > 7.0?
@raffaelj Okay I managed to solve the error simply by updating Cockpit, sorry. I was on PHP 7.2 with Cockpit 0.6.0 or 0.6.1. Now I'm on PHP 7.2 with Cockpit 0.8.0.
It actually works now when I use an asset-field! Is there also a way to do the same for an image-field?
Thank you so much.
@nisdec
Is there also a way to do the same for an image-field?
I'm not sure. After skimming the code, I don't think so. Image uploads are handled different than assets. It looks like they are just simple files without any database entries.
You could create a custom api endpoint:
<?php
/*
copy this code to `/config/api/imagepath.php`
call it with `/api/imagepath?token=xxtokenxx`
json body: {"src":"imageid","h":"100"}
*/
$thumb_url = $this->invoke('\\Cockpit\\Controller\\RestApi', 'image');
$relative_path = str_replace($this['site_url'].$this['base_route'], '', $thumb_url);
$real_path = COCKPIT_DIR . $relative_path;
return [
'thumb_url' => $thumb_url,
'relative_path' => $relative_path,
'real_path' => $real_path
];
I have a site that consumes Cockpit content via API and I would like to insert images in HTML fields, using uploaded assets. The WYSIWYG editor truncates the image paths and outputs relative links, like '/storage/...'.
In a headless CMS I would expect full paths in HTML, like 'http(s)/:.mysite.domain/storage....'
Is there a way to configure the editor to prepend the site path to src in image tags?
I found this option in the TinyMCE docs https://www.tiny.cloud/docs/configure/file-image-upload/#images_upload_base_path but I don't know how, or whether, it is possible to configure Cockpit to use it.
The alternative would be to parse all HTML client-side and replace the image links, which I would rather avoid.
I have a site that consumes Cockpit content via API and I would like to insert images in HTML fields, using uploaded assets. The WYSIWYG editor truncates the image paths and outputs relative links, like '/storage/...'.
In a headless CMS I would expect full paths in HTML, like 'http(s)/:.mysite.domain/storage....'
Is there a way to configure the editor to prepend the site path to src in image tags?
I found this option in the TinyMCE docs https://www.tiny.cloud/docs/configure/file-image-upload/#images_upload_base_path but I don't know how, or whether, it is possible to configure Cockpit to use it.
The alternative would be to parse all HTML client-side and replace the image links, which I would rather avoid.
I still think is the best option, contents are saved in Cockpit as collections, so its good to have all paths relative to the storage they are configured, if you switch servers, change domain or migrate, it would be a bit of nightmare to update again all paths, right?
Dealing with that in the frontend is not so complicated, usually in React (or any node app) I defined an .env file (e.g. .env.local, .env.production, etc..):
COCKPIT_STORAGE_ASSETS_URL=https://mycockpit-url/
and replace it on asset fields, etc..
if I'm using a WYSIWYG editor I can also transform the markup, for that I use the handy htmr library (https://github.com/pveyes/htmr) and can do something like:
// (...other imports)
import convert from "htmr";
// my transform callback, can handle any html tag like img
const transform = {
img: node => <img src={`${process.env.COCKPIT_STORAGE_ASSETS_URL}/${node.src}`} {...node} />,
};
const MyComponent = props => {
return <div>{convert(props.markup, { transform })}</div>;
}
export default MyComponent;
keep in mind that above is a very draft example, you may need to deal with external images, etc..
I absolutely agree that storing full paths in the database is nonsense and would cause more harm than good.
But I am not sure what is wrong with the API itself prepending the URL on database output. Cockpit already uses site_url
in configuration, and the paths to assets, uploads, etc. are also separately defined and can be overridden on a per-system basis.
Basically, my wish for the future is that the Cockpit API would process the storage paths internally and output the URLs in links. That way the files could even be stored on another system. And the clients would only call the API and remain agnostic of which assets are stored where. But that is probably a whole new feature request.
In the meantime, I will stick to a simple regex replacement in the client.
But I am not sure what is wrong with the API itself prepending the URL on database output. Cockpit already uses
site_url
in configuration, and the paths to assets, uploads, etc. are also separately defined and can be overridden on a per-system basis.
I agree. Additionally, Cockpit is even more aggressive in that if you put in a fully qualified url, cockpit will rewrite it to a relative url - which is a huge pain - https://github.com/agentejo/cockpit/issues/1102
There should be an option for absolute URL's as this is really annoying on JAMstack or SPA apps. On these kind of apps, the CMS is always (98% of the time) on a different domain so the absolute path would be the most accurate solution.
Is there any good way of getting the full path to images (rest api)? I'm not hosting cockpit on the same server as the front-end.