Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ghost Image Output #128

Closed
JohnONolan opened this issue Jun 10, 2013 · 27 comments
Closed

Ghost Image Output #128

JohnONolan opened this issue Jun 10, 2013 · 27 comments
Labels
affects:editor Work relating to the Koenig Editor

Comments

@JohnONolan
Copy link
Member

A hypothetical scenario for clarity: One particular post looks something like this (image dimensions are of original uploaded media). This is the content which the user has defined.

  • Text
  • Image (500x200)
  • Text
  • Text
  • Image (600x400)
  • Text
  • Image (1024x800)

Separately, the theme defines the following criteria about how it would like to display the images on the front end.

  • The default size for all images in the blog content of this theme is 600x400
  • The theme can display a featured image (on the homepage or in search results) this image is 100x100
  • The theme has a secondary size for its featured image on a different template, which is 200x100

Installation / Image Sizes

When a theme is activated/installed, it runs a process (preferably in the background, in order of newest to oldest) to resize images to the sizes it needs.

If any images are too small (the original media size) they are left alone.

Consideration: How does this work with 3rd party image services? Do they simply mirror the local Ghost image directory?

Featured Images

What if the concept of a "featured image" is simply the first image that appears (completely optionally) in any post.

Turning the concept of the WordPress featured image on its head - rather than the user being forced to create an entity defined as a thumbnail, the theme checks for something which it can use as a featured image.

Ghost scans a post to see if an image is available to use as a featured image - when it finds one, it uses it. If no image exists in the post which meets the required dimensions - a featured image is not assigned.

Markdown

We are extending markdown to produce some new functionality with the Ghost editor. By typing the following syntax:

!image[alt text](source)

an image uploader is generated in the content preview pane. Once an image is uploaded via this upload form, the markdown is then populated with the appropriate data. Eg:

!image[bananas](http://localhost/ghost/content/images/bananas.jpg)

Consideration: Is changing the official markdown tag of ![alt](src) to !image[alt](src) worth it? The initial thinking was to differentiate between image/video/something. But it might make sense to keep the ![alt](src) syntax for any type of media which is then detected automatically.

Multiple Image Sizes

Ghost does not support dynamic image sizes within content, it also does not support images being floated around differently within text. An image is a block of media equivalent to a paragraph. The theme can style that image to fit within its design.

It would be good if themes could define different sizes of image, so that users could still display content differently.

For example, an image that fits the width of the screen ("full")
image

or an image that fits the width of the content ("standard")
image

Considerations:

  • How could this control be achieved within the post preview UI?
    • Potentially overlaid toggle on the image preview that can switch the image between output sizes.
  • How could this control be achieved (and translated) in markdown?
    • This would have to extend Markdown in a non-standard way
    • Potentially something like ![alt][size](src)
  • How would we handle sizes being input incorrectly / not working / being changed?
    • Fall back to a standard image size
    • If the image is too small to be displayed at the standard image size - display the original media
@ErisDS
Copy link
Member

ErisDS commented Jun 10, 2013

Long term, I'd like to have alt again, but short-term I think our functionality might conflict with showdown's default. Definitely worth investigating.

I think that a potential extension to haunted markdown that would solve multiple problems, would be to have the syntax be alt{size: standard, other-attr: other-value}

If no attrs are specified then defaults are used.

This would allow us to support alignments / floating. I know that the above says we don't support this, but I foresee it being a much requested feature... I use this feature of WP a lot on my own blog because I tend to include small low-quality images, like logos etc. Of course we can start without, but the attribute format I am recommending gives us plenty of opportunity to add new features. We could augment links in a similar way.. again, much further in the future when we have the editor much more under our own belt.

@JohnONolan
Copy link
Member Author

There are a couple of lines we need to be conscious of when we start bastardising Markdown, which is that these 3 all exist for different reasons:

  • Markdown
  • HTML
  • Shortcodes

We just need to be a bit careful that we don't accidentally invent tag soup 2.0.

@ErisDS
Copy link
Member

ErisDS commented Jun 10, 2013

With regards to featured images being the first image in the post, this seems like a sub-optimal solution to me:

  • it would mean that one of the images that shown in the editor preview gets handled differently by the theme... what if that is not what the user intended at all? It breaks the preview (preview is no longer a true preview).
  • it would mean pre-parsing the HTML content, finding & ripping out the first image & then making it available in some other way. At the moment we just display the HTML output of the content editor, this could potentially slow things down quite a lot, as well as introducing complexity.

@ErisDS
Copy link
Member

ErisDS commented Jun 10, 2013

And yep, very wary of tag-soup... but also of limitations... perhaps we have one default image size, and a featured image defined in some other way, and as soon as the user specifies any other property (size or whatever) we default to putting HTML in the markdown.

@JohnONolan
Copy link
Member Author

Why is the preview no longer a true preview? I think you're confusing "featured image" with "post thumbnail". The equivalent of single.php would have no concept of a post thumbnail. The post thumbnail would be used as a piece of UI for themes - eg. http://travelllll.com/must-read/ - nothing more.

RE complication - we can't get around this. It is complicated. Our choice is to either give that complication to the user, and make them deal with it (like the WordPress implementation of post thumbnail) or deal with the complication on the back end, and make things simple for the user. I'm obviously rather in favour of the latter :)

@ErisDS
Copy link
Member

ErisDS commented Jun 10, 2013

If this is the first image in the post, then we still leave that image in the post? The assumption I made is that we would do something different with it in every view. I made that assumption because no matter what the answer to the above is, we still have to find and serve that image separately, which is technically, not challenging, but smelly IMO. And if we have the image separately, then themes may choose to do something with it on eq.single.php .. which would require that it didn't also appear in the post.

In summary.. I think this approach adds complexity, not just for us but also for the user. I think we could use a ui within the editor to mark one image as the featured one, which would leave it in the post, but also store it as the feature. If the user didn;t want to use one from the post, they could upload separately through some other UI

@JohnONolan
Copy link
Member Author

See what you're saying - I would suggest though, that if the featured image is always the first image in the post (and it had a unique class) - then it would be reasonably easy for a theme author to pull that image out of the flow of the content using CSS or JS, right?

@ErisDS
Copy link
Member

ErisDS commented Jun 10, 2013

Not really? That seems like the way you would hack it if we didn't support featured images as a feature. If we support it, we should support it properly.. or else just provide what you just described as a plugin.

@JohnONolan
Copy link
Member Author

But it is a hack if a theme author wants to style a post thumbnail in a special way on a single post view. That's not what post thumbnail is designed for. The fact that the content can be pulled out of the document flow and re-arranged on an aesthetic basis is exactly (to the letter) what CSS was designed for.

Don't think about it as a "featured image" which is "an image at the start of a post on the single view" - this is a singular use-case that isn't central to the point of this feature: which is to abstract an image out of the post content and associate it with the title independently from the rest of the content.

@cgiffard
Copy link
Contributor

cgiffard commented Aug 1, 2013

There's actually a good way to do this without breaking markdown. Media Fragment URIs lets you specify sub-components of a given media resource with its URL (such as time or track in a video, or clipping the resource to certain dimensions.) It's as verbose or as simple as you want it to be, and works with a plain old hash (#) on the URL which will not damage the request if somehow it falls through to the browser, or a user copies the markdown source to use somewhere else.

http://www.w3.org/TR/media-frags/

User agents that support it will ignore declarations they don't understand, meaning you could extend it and use a syntax similar to the following: (while still retaining support for other declarations in the same URI.)

![alt](/images/myimage.jpg#thumb)
![alt](/images/myimage.jpg#full)
![alt](/images/myimage.jpg#poster)

Just a quick thought. :)

@cgiffard
Copy link
Contributor

cgiffard commented Aug 1, 2013

Just realised you wouldn't even need to write JS to provide basic support for it. You could easily match on a CSS attribute selector:

img[src$="#thumb"] {
    float: left;
    clear: right;
    width: 200px;
    height: 200px;
}

@matthojo
Copy link
Contributor

matthojo commented Aug 1, 2013

I really like what @cgiffard is proposing. Could potentially make imports a lot easier too.

@ErisDS
Copy link
Member

ErisDS commented Aug 4, 2013

First of all.. this sounds most excellent. I have never seen it so wanted to take some time to sit down and read the spec & do a bit of research before I responded. Not sure how we're meant to keep up with all these new bits and pieces these days.

So as I understand it, media fragments allow you to define a temporal or spacial dimension of a resource. So what time to go to on a video/audio resource or how to clip an image resource. The spacial dimension is almost exactly what we need - being able to specify: http://placekitten.com/500/500#xywh=160,120,120,140 and get a correctly clipped image, but at the moment although the temporal dimension has been implemented by some browsers, spatial hasn't been implemented by any.

But, your suggestion was to invent our own media fragment uri to specify the "class" or "type" of image we want... allowing us to effectively use fragments to specify a class on an image in markdown. Which is kinda genius, I like it :) We can use css or javascript to target the class and provide functionality.

However, having read the spec I wanted to flag up this:

For media fragment addressing, both approaches - URI query and URI fragment - are useful. The main difference between a URI query and a URI fragment is that a URI query produces a new resource, while a URI fragment provides a secondary resource that has a relationship to the primary resource. URI fragments are resolved from the primary resource without another retrieval action. This means that a user agent should be capable to resolve a URI fragment on a resource it has already received without having to fetch more data from the server.

Therefore, if various sized images are generated on the server side as per John's original description, then media fragments are not what we want because we need to request a different image, not just change the one we have.

If we want to use css / js on the client side to do image processing, we could use fragments. We could even implement the spacial dimension syntax so that if it gets implemented in the future we can just turn our implementation off. There is the css clip property which I think has widespread support.

If we want to resize images on the server and serve the correct one, then we probably want to use standard query strings.

![alt](/images/myimage.jpg?size=thumb)
![alt](/images/myimage.jpg?size=full)
![alt](/images/myimage.jpg?size=poster)

We can of course provide a combination of both

![alt](/images/myimage.jpg?size=thumb#xywh=0,0,50,50)

Where the client side can take a particular sized image and further specify a modification.

Or

![alt](/images/myimage.jpg?size=standard#border)

Where .border is a class that adds a border to the image

Or

![alt](/images/myimage.jpg?size=standard#right)

Where .right is a class that displays the image right-aligned.

I think this opens up a world of possibilities, and whatever we decide is the best implementation, I think using the URI to define additional image properties is definitely the right idea.

@cgiffard
Copy link
Contributor

cgiffard commented Aug 4, 2013

I see no reason why we couldn't parse the URI-fragment data on the server and return a query string version to the client, since native support is a little thin on the ground at the moment. ;)

(That said, if we have a media-query that defines the same resource be downloaded and presented in multiple ways, using the URI-fragments natively on the client would obviously be better since it wouldn't have to download the resource twice.)

I like the idea of supporting the spatial dimension, but think that a shorthand form might be more palatable to most content authors. Mapping non-standard URI fragment parameters to HTML classes soundseasy to do, won't break anything, and totally possible to manage entirely in the markdown parser/HTML compiler without having to write any functionality anywhere else in the app.


With that in mind, for the time being, to recap... I propose we just parse the URI fragment, ignore standard parameters, and map anything else to an HTML class. As far as I've been able to ascertain from the spec, the URI fragment parameters follow exactly the same rules as QueryString params, so we could use the battle-hardened node parser to parse them to a hash, saving ourselves some bother.

The theme author can use the class name to format and/or clip the images accordingly in their CSS.

Then at a later date we can implement both server-side and client side support for sizing an image based on the spatial dimension (whoo cross-application-tier code sharing!)

@ErisDS
Copy link
Member

ErisDS commented Aug 4, 2013

As far as I understand it will depend entirely on the use case. If the media-fragment is added client-side there will be no new request so the client will never know about it in order to be able to parse it and return a query-string version.

For example, during actual image uploads on the editor: once the upload is complete we get given an image source and we place that into the preview. I imagine there will then be a set of icons you can click to decide what size you want the image to display... this adds a media fragment, but will not cause the image to update unless we do some other thing to tell the server.

But to clarify, I'm not disagreeing with anything you've said above, I'm just highlighting what I think might be problems that we would encounter.

@ErisDS
Copy link
Member

ErisDS commented Aug 19, 2013

Another consideration here, is how to handle images that have been uploaded to Ghost, vs images which are linked via a URL.

@cgiffard
Copy link
Contributor

@ErisDS well that would actually be a great use case for fragments that address styling, since you could use them regardless of whether the image was hotlinked or uploaded to Ghost directly.

@ErisDS
Copy link
Member

ErisDS commented Sep 9, 2013

Punting all of this to 0.4

@iraycd
Copy link

iraycd commented Oct 19, 2013

I love @cgiffard idea. But I guess it'll be hard by users.
![alt](src){size: standard, other-attr: other-value} which I think is confusing for users.

Instead, I think why can't user add something ![featured_image]: src like at the end of the document.
Which gives the variable {{feature_image.sizei}} in the template.
Where size = big | small | mini which can be the values set in the settings or in config.json file in the template if that will be implemented in the future.

Please correct me if I'm wrong.

@ErisDS
Copy link
Member

ErisDS commented Nov 19, 2013

No time for the UX work here.. gonna keep this as the main issue for image features and punt to 0.5.

@MikeRatcliffe
Copy link

I hate to point out the obvious here but I don't necessarily want the image I use as a featured image to appear in a post. I would only want to show it in the summary list of all posts.

Also, I use HTML instead of markdown.

@edoardoo
Copy link

Hi,
I've seen that one of the 'scaring' sides about modify the markdown is on UX complexity.
For what is worth, I would propose some suggestions.

About Markdown:
I think that having a markdown like

    ![alt](/images/myimage.jpg?size=thumb)

is a great solutions, which offers a lot of possible developments, although it could drive to some side effects, especially in situations like

![alt](/images/myimage.jpg?size=standard#right)

( just think about how js libraries, as prettyPhoto, implemented permalinks ).
So, IMO is good to think about it a little more before hearing the theme-developer community crying blood.

About the UX:
I think having a parallelism between markdown/HTML and preview is absolutely great and a must-need.
To solve alignment and other properties settings I've thought about an 'on picture' icon/gear which open an on hover menu on the preview picture with some options. (see the picturebelow)
Once clicked the option, it will be reflected on the markdown.

settings menu
settings menu open

About the featured image:
It's a very useful feature and really needed by a lot of theme developers. In the picture below are my two cents about where it could be a nice place to set it. Clicking on the pencil will open a modal window (?) where you can drag the featured picture.

featured menu

Sorry for long post, and excuse me for the intrusion.

@StevenLangbroek
Copy link

Can someone give me a status update on this? Considering Ghost for a client and this is essential for their layout and integrating blog-posts into their main marketing site. (jQuery trickery doesn't work since we need to pull in posts over json).

@ErisDS
Copy link
Member

ErisDS commented Jul 14, 2014

@StevenLangbroek what in particular are you interested in?

@StevenLangbroek
Copy link

Oh sorry, should've been more clear. The "cover / featured image" functionality.

@ErisDS
Copy link
Member

ErisDS commented Jul 14, 2014

There is an undocumented hack/workaround for that, which does have a bit of an explanation here: http://dev.ghost.org/ghost-0-4-themes/#anotetoallthemedevelopers. Despite being a hack, it has a test against it so it won't disappear until it is deprecated in favour of #therealthing.

Here's the plan for how the feature will work in terms of ui: https://github.com/TryGhost/Ghost-UI/issues/36. Roadmap is in a bit of flux at the moment, but it I expect this will land in the next feature release after MU.

@JohnONolan
Copy link
Member Author

Moved on so far from this already. Advanced image controls should still be a thing - but this issue is stagnant and isn't worth keeping around. Future work/discussion can start in a new issue once we circle back around to this sort of concept (which is likely to be significantly different to things proposed here)

@ErisDS ErisDS removed this from the 0.7 Editor milestone Aug 20, 2014
@ErisDS ErisDS added the editor label Aug 20, 2014
daniellockyer pushed a commit that referenced this issue Jul 20, 2022
requires f38d490

- adds `lib/geolocation.js` with `getGeolocationFromIP()` function which uses https://geojs.io to lookup geolocation data from an IPv4 or IPv6 address
- updates `create/updateMember()` functions to work with a `geolocation` property in the passed in object
  - if `geolocation` is `undefined` when updating a member do not reset any existing property
- updates `sendMagicLink` middleware to extract the IP address from the request and stores it as part of the token payload
- updates `getMemberDataFromMagicLinkToken()` method to extract the IP address from the token payload and perform a geolocation lookup if we have an IP address and a matching member does not already have geolocation data
daniellockyer pushed a commit that referenced this issue Oct 5, 2022
refs TryGhost/Product#473
refs 006cf434

Ghost no longer sends back currency symbols from the API, so we calculate the currency
symbol using `Intl.NumberFormat`.

We've also renamed the `currency` property to `currency_symbol` - as it does not store a currency.

Depending on currency and locale, currency symbols can be the currency ISO code (e.g. AED).
In order to style these differently we add a different class to the element.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
affects:editor Work relating to the Koenig Editor
Projects
None yet
Development

No branches or pull requests

8 participants