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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Website does not produce expected static badge outputs #9852

Open
ascopes opened this issue Dec 29, 2023 · 4 comments
Open

Website does not produce expected static badge outputs #9852

ascopes opened this issue Dec 29, 2023 · 4 comments
Labels
question Support questions, usage questions, unconfirmed bugs, discussions, ideas

Comments

@ascopes
Copy link

ascopes commented Dec 29, 2023

Are you experiencing an issue with...

shields.io

馃悶 Description

If I go to the website and ask it to generate a static badge, I get a 404 not found badge instead unless I add a hyphen to the badge name.

image

Additionally, the example states the following is valid:

Label, message and color separated by a dash -. For example:
Static Badge - https://img.shields.io/badge/any_text-you_like-blue

But if I enter any_text-you_like for the badge content, and blue for the color, it generates the following:

![Static Badge](https://img.shields.io/badge/any_text-you_like?color=blue)

which does not render as expected: Static Badge, despite the docs saying badgeContents consists of a label and optional message.

馃挕 Possible Solution

Add a hyphen.

This should be clearly validated or if possible, fixed internally where possible. The docs should prevent me from making invalid badges but ideally it would be better if it just fixed it with the intention of making a single-colour badge instead. While the docs state that hyphen separators are acceptable, it is not clear that they are mandatory to stop things breaking.

@ascopes ascopes added the question Support questions, usage questions, unconfirmed bugs, discussions, ideas label Dec 29, 2023
@ascopes ascopes changed the title Static badges silently render a 404 badge if no hyphen is provided in the name Website does not produce expected static badge outputs Dec 29, 2023
@chris48s
Copy link
Member

chris48s commented Jan 1, 2024

This is going to be a bit of a long rambly reply

First off, I'll explain the behaviour you're seeing:

With all shields badges, you can override the label and color with URL parameters. This is broadly sensible. It allows you to take a badge like

https://img.shields.io/npm/dt/badge-maker
and customise it to
https://img.shields.io/npm/dt/badge-maker?label=custom%20label&color=white
or whatever.

The format of the badgeContent param for the static badge is either: label-message-color (label, message and color, seperated by a dash) or message-color (message and color, seperated by a dash).

e.g:

https://img.shields.io/badge/any_text-you_like-blue
or
https://img.shields.io/badge/just%20the%20message-8A2BE2

The static badge also supports all of the same standard params as every other shields badge. It is kind of pointless to set the label or color to one value in one part of the badge URL and then override it again in another, but you can do it. So I can do

https://img.shields.io/badge/any_text-you_like-blue?label=custom%20label (which renders the same thing as https://img.shields.io/badge/custom_label-you_like-blue )
or
https://img.shields.io/badge/just%20the%20message-8A2BE2?color=white (which renders the same thing as https://img.shields.io/badge/just%20the%20message-white )

You still need to set everything in the badgeContent part of the route even if you then want to override it with another value in a query param though. As I say, this is mostly pointless but we just blanket support the same customisations on every route.

So that's why you're seeing the behaviour you're seeing. We do try to explain how to construct a valid static badge URL in the screenshot you've posted:

Screenshot at 2023-12-31 20-04-32

That said, I think we are not communicating this well, or what we're providing users with doesn't match expectations. Here's a couple of similar queries to this on discord:

Screenshot at 2023-12-31 19-45-41

Screenshot at 2023-12-31 19-46-53

..and a similar-ish GitHub issue:

#9679

So I think at this point it is reasonable to ask: How can we do this better?

One approach would be to try and document what we have more clearly. Is there content we could add to https://shields.io/badges/static-badge to help clarify?

Another thing we could do would be to hide the label and color override query params on https://shields.io/badges/static-badge We'd still support them to avoid making a breaking change, but maybe hiding them in the frontend for this route might help make this page less confusing.

Could we improve the error handling so that something like https://img.shields.io/badge/foo gives a more helpful error message than just 404?

All of that possibly amounts to papering over the cracks though.

I think fundamentally, what users really want/expect (and why some people struggle, particularly if they just do what they think is the most obvious thing) is a page with 3 input boxes: 1 for label, 1 for message and 1 for color. This is not unreasonable. On every single other page on our site, there is one textbox for one route param. This is the only situation where we ask the user to mash multiple params into a single input box according to a format. The issue is that the route for the static badge (which pre-dates the current frontend by many many years)

static route = {
base: '',
format: '(?::|badge/)((?:[^-]|--)*?)-?((?:[^-]|--)*)-((?:[^-.]|--)+)',
capture: ['label', 'message', 'color'],
}
doesn't really lend itself to being expressed as an Open Api route, which is why we've ended up mashing that regex pattern into one param called badgeContent
'/badge/{badgeContent}': {

I think if we really want to solve this mismatch, we would probably need to make a new static badge route (obviously we'll have to keep the existing syntax working as there are a zillion badges using the existing format out there) that is more conducive to to providing a builder page in the current frontend that matches user expectations. 3 textboxes: 1 for label, 1 for message, 1 for color.

Otherwise, we might just be answering similar questions forever.

@jNullj
Copy link
Collaborator

jNullj commented Feb 21, 2024

I want to give that a try

@chris48s
Copy link
Member

I've actually thought about this a bit more recently, but I hadn't taken the time to write it all down.

One of the interesting things about working on a codebase that has over 10 years of history to it is that there's all kinds of stuff in here. Sometimes even I can't remember everything that is in here.

As noted above, one of the things that is kind of weird and derpy about the existing badge is that label, message and color can be specified both in the main part of the route and also as query params. So going to back to an example from above, you can do https://img.shields.io/badge/any_text-you_like-blue?label=custom%20label to specify the label once and then override the label.

In this case, I'd completely lost sight of it when I originally wrote the post above but we actually already have a badge route that attempts to solve this problem by just doing everything using query params.

See #2673 and #3024 for the history.

So using that route, you can construct a static badge like this:

https://img.shields.io/static/v1?label=any%20text&message=you%20like&color=blue

and that gives you one and only one way to specify label, message and color: In the query params.

We seem to have added that route, and then just not documented it 馃檭
I don't think it is very widely used.

Conveniently for this situation, query params also already work exactly how we want for documentation/builder purposes.

So.. problem solved, right? Just switch to /static/v1 as the default badge route, document that and we're good? Well, there are a few problems..

One of them is that the /static/v1 route has some slightly strange behaviours. For example:

Those are both fix-able. I'd quite like to fix them first if we're going to make this the default, but it is not a big deal.

More of an issue is:

  • Required query params are shown by default. Optional query params are hidden.
  • If a param is required, you have to put a value in it before the "execute" button is press-able. You can't leave a required param empty.

The only thing that is actually required is message. Both label and color are optional. I feel like the optimal user experience is that label, message and color are all visible (in that order) when you first load the page, but I don't think we can do that while also allowing the label-less badge ( https://img.shields.io/static/v1?label=&message=message&color=blue ) and avoid overriding more frontend components (I really don't want to override more frontend components if we can avoid it).

One thing we can probably do is fiddle with the code we use to assemble the list of standard query params so that for this badge, label and color appear at the top of the list of optional params.

That feels like the least-worst solution I can think of, but I still don't love it.

@KernelDeimos
Copy link

KernelDeimos commented Mar 26, 2024

This just confused me also. I missed some of the instructions at the top because the form looked really simple (I also had the vertical layout for the page, so by the time I scrolled to the form that information wasn't in view)

technically, you could ignore all the logic in the handler for this and just put something like this at the top, right?

badgeContent = (str => str.indexOf('-') >= 0 ? str : str + '-lightgrey')(badgeContent);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Support questions, usage questions, unconfirmed bugs, discussions, ideas
Projects
None yet
Development

No branches or pull requests

4 participants