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

How does one generate a Nova resource link...? #345

Closed
telkins opened this issue Aug 30, 2018 · 29 comments
Closed

How does one generate a Nova resource link...? #345

telkins opened this issue Aug 30, 2018 · 29 comments

Comments

@telkins
Copy link

telkins commented Aug 30, 2018

The docs show me how to make a computed field: https://nova.laravel.com/docs/1.0/resources/fields.html#computed-fields

I'd like to know how I can do this while also providing a Nova resource link to a specific resource.

For example, in my current project I have the normal timestamps on each model. I'm also using Laravel Manageable (https://github.com/signifly/laravel-manageable) to track the creator and the editor of each record. This is nice information to display on the resource details page, for example, but I don't want to have four lines for this. I'd rather use a computed field to combine creator/created-at and editor/updated-at....but I'd like to link the creator/editor to their respective Nova resources.

It's easy enough to display the data, but I'd like to be able to add a link. Yes, I can figure out how to do it on my own, but I'd rather know if there's a built-in way of doing so....now or in the future.

I hope that makes sense.

Thanks...! :-)

@webspectyler
Copy link

webspectyler commented Aug 30, 2018

I'm trying to put a link in the index table to the row's resource - but when I include the <a href.. <a/> markup, those tags appear as text in the table cell instead of as rendered links. Any way to override the string escaping?
Text::make('Linked Name', function () { return '<a href="'.$this->path().'">'.$this->name.'</a>'; }),

href-example

@David-Griffiths
Copy link

There's a URL field package here.

This should be in the core however.

@webspectyler
Copy link

@Andy-Baker I can't figure out how to use a model attribute as the Label when using this package. The label() method seems to only accept a string (not a closure where a dynamic title could be returned).

@jannaahs
Copy link

@webspectyler I had the same issue with the mentioned package.

Now I use this package: https://github.com/pdewit/nova-external-url

@telkins
Copy link
Author

telkins commented Aug 30, 2018

@Andy-Baker @jannaahs Thanks for your input, both of you. Although I only glanced quickly through each packages readme files, neither appears to resolve the specific problem that I'm trying to solve.

I want to be able to add a computed field where some/all of the result is a link.

My example would have creator/created-at data as one field with the data being the creator which would also be a link to that particular nova user resource followed by a simple date/time (so only the user part would be a clickable link):

Creator/created at: my.username / 2018-08-30 17:51:51

@davidhemphill davidhemphill added the request Feature Request label Aug 31, 2018
@davidhemphill
Copy link
Contributor

Working on this. You can follow along here: #280

@telkins
Copy link
Author

telkins commented Aug 31, 2018

Nice...! Thx....

@davidhemphill
Copy link
Contributor

Closing this since we just released the asHtml method on computed fields. Thanks!

@telkins
Copy link
Author

telkins commented Sep 5, 2018

@davidhemphill Thx for your fix, especially as it pertains to allowing users to add HTML.

My original issue still stands, however, at least in part. I'd like to be able to generate a link to a Nova resource. So, if I have a Nova User resource, then I'd like to be able to make a link to it. If it's a "simple" model attribute, then it can be done via a relationship. This is easy enough. If, however, I want to "mix" data, then I can use the new asHtml method, but I'm still left without a "supported" way to link to a Nova resource.

Perhaps I've missed something in the docs or elsewhere....which, if this is the case, someone can point me in the right direction. Otherwise, I'm still at a loss. Btw, I think I can figure out how to make a link, but I would feel much more comfortable if Nova provides the link for me in case something changes going forward.

Does this make sense?

Thanks in advance. :-)

@davidhemphill
Copy link
Contributor

@telkins I'm really trying to understand what you're wanting, but not quite getting it. What's wrong with the current methods? :-)

@telkins
Copy link
Author

telkins commented Sep 19, 2018

@davidhemphill Thx for your response. Perhaps I'm not 100% certain myself. ;-) At least, I haven't thought all the way through what I think a "good" solution might look like.

First, you've introduced a method that allows one to create custom HTML. This is great. It doesn't completely address my specific use-case, though, which isn't terribly important, admittedly...but similar use-cases may be.

So, let me try to explain using my example. Many people have created_at and updated_at fields on their models. I have these on most models as well. For certain models, I've also added created_by and edited_by fields, which reference the standard, out-of-the-box Laravel User model. In Nova, for these four Eloquent fields, I would like to have two Nova fields: created-by/created-at and edited-by/updated-at.

Now, the new asHtml() method allows me to display these two Nova fields, but not in the complete fashion that I have in mind. I would like the created-by and edited-by users to be clickable/links....taking the Nova user to the particular Nova User resource page that they click on. To do this, I need to make a link. I am sure that I can hand-code something that will work, but if Nova changes how it links to resources, then my code breaks.

So, I guess I was thinking I might be able to do something like this (using some of your sample code from #280):

Text::make('Created by/at', function () {
    return view('managed-by-at', [
        'manager' => $this->creator,
        'manager_link' => $this->getResourceLink(UserResource::class, $this->creator->id),
        'managed_at' => $this->created_at,
    ])->render();
})->asHtml(),

And, I'm thinking that it would yield something that would look similar to this: <a href="nova-resource-link-goes-here">Creator Username</a> | 2018-09-19 12:34:56 UTC

It's this part that I'm interested in: $this->getResourceLink(UserResource::class, $this->creator->id). I want something that's guaranteed to give me the right url regardless of how Nova might change over time. It might be nice to have a property/method on the individual resources that return links to themselves. It is obviously nice to have a method like I mentioned above that returns one given some more dynamic input...like the Nova resource class and its identifier.

Does this clear things up? I hope I've made it a bit easier to understand, at least. Also, it's possible there's already a solution and I've somehow managed to miss it, in which case I apologize for wasting everyone's time. ;-)

Anyway, I think it's clearer now, but please feel free to ask more questions. Also, while this is a pretty big nice-to-have for me, there are other issues that are actually much more critical and one in particular that is making it impossible for me to use Nova to manage my resources. :-(

Thanks again...! :-)

@davidhemphill
Copy link
Contributor

Couldn't edited_by and created_by just be BelongsTo relations? Those would get links to the related User resource.

@telkins
Copy link
Author

telkins commented Sep 20, 2018

@davidhemphill Yes, edited_by and created_by could just be BelongsTo relations. This is what I did initially, of course. I just think it's a lot of space for two generally uninteresting pieces of data. I thought combining them would look quite a bit nicer while still providing the same -- or similar, at least -- functionality. This is why I said that it's a nice-to-have feature. ;-)

@swapnilmonad
Copy link

There is a method called "->asHtml()"

Text::make('Display Name', function () {
    return '<a href="' . $this->getAdminLink() . '">' . $this->getFriendlyName() . '</a>';
})->asHtml()

@telkins
Copy link
Author

telkins commented Jan 25, 2019

@swapnilmonad Thanks for your suggested help, but I believe you've missed the point. If you read through the part of the conversation between @davidhemphill and myself, you'll better understand what my goal/intent was. If, however, I've missed your point, then please feel free to let me know. :-)

@idragon81
Copy link

idragon81 commented Feb 18, 2019

I believe what you want is router link.
Given that we already have asHtml
You can just use something like this in your html

<router-link
    class="cursor-pointer text-70 hover:text-primary mr-3"
    :to="{
	    name: 'detail',
	    params: {
	        resourceName: 'user',
		resourceId: 'userId',
	       },
         }"
    :title="Created By username">
</router-link>

I'm not sure if this will work as I have not tested it. But I don't see any reason why this wouldn't.

@dillingham
Copy link
Contributor

dillingham commented Feb 18, 2019

This package works for that
https://github.com/dillingham/nova-button

@dengsauve
Copy link

@idragon81 thanks for the suggestion, it worked for me!

@yurii-github
Copy link

i guess the main question here is - how to generate link FROM RESOURCE file not at frontend via its router but within PHP. And no, it's not possible, because there's no route for it

only hardcode like

<a href="{{url('resources/{your-resource-name}', ['resourceId' => YOUR_ID]}}">some text</a>

at least I didnt find any solution

@mgussekloo
Copy link

A bit late to the party, but my solution ended up being:

Text::make('Title', function () {
    $url = \Nova::path() . "/resources/{$this->uriKey()}/{$this->id}";
    return "<a class=\"no-underline dim text-primary font-bold\" href=\"{$url}\">{$this->title}</a>";
})->asHtml();

@crynobone crynobone removed the request Feature Request label Dec 24, 2020
@nikans
Copy link

nikans commented Mar 20, 2021

I've created a custom text field, so you can edit your ID fields or link a title field on the index screen.

https://github.com/nikans/text-linked

@orrd
Copy link

orrd commented Jun 3, 2021

@telkins It looks like no one really had any solutions for your actual problem? There are a lot of people talking about a different problem involving fields like Text fields, but I don't see any solutions to your actual question. We're also looking for a way to generate Nova resource URLs.

@cja-github
Copy link

Is there still no way to generate a URI for a Nova resource?

My use case is that I am exporting Laravel records to another system and I want to give that other system a URI for the Nova resource for each record so that users can click a link in the other system to open the resource in Nova.

@spire-mike
Copy link

spire-mike commented Dec 27, 2021

I believe what you want is router link. Given that we already have asHtml You can just use something like this in your html

<router-link
    class="cursor-pointer text-70 hover:text-primary mr-3"
    :to="{
	    name: 'detail',
	    params: {
	        resourceName: 'user',
		resourceId: 'userId',
	       },
         }"
    :title="Created By username">
</router-link>

I'm not sure if this will work as I have not tested it. But I don't see any reason why this wouldn't.

@idragon81 @dengsauve did you actually use this method successfully? When I try it, I just end up with a router-link being rendered in the html:

This is my field definition:

Text::make('Order', function () {
    return "
        <router-link
            :to=\"{name: 'detail', params: {resourceName: 'orders', resourceId: $this->id}}\"
            class='dim font-bold no-underline text-primary'
        >
            $this->name
        </router-link>
    ";
})->asHtml(),

The resulting output:

image

Am I missing something that should make this work?

@Pamposgsk
Copy link

Hi this approach doesn't work on nova v4.
How can we achieve the same?

@sfinktah
Copy link

sfinktah commented Jan 20, 2023

Well, this is how it appears to be done with-in Nova itself... CreateResourceButton.vue

    <component
      :is="component"
      class="flex-shrink-0"
      v-else-if="shouldShowCreateButton"
      dusk="create-button"
      :href="
        $url(`/resources/${resourceName}/new`, {
          viaResource: viaResource,
          viaResourceId: viaResourceId,
          viaRelationship: viaRelationship,
          relationshipType: relationshipType,
        })
      "
    >

Which appears to create a button with a href. Maybe there's some inertia-esque magic somewhere, but that should work none-the-less.

What I mean from the above, is that you can literally write this (ripped directly my live code):

        <dropdown-menu :hover="true">
            <ul tabindex="0" class="dropdown-content menu menu-compact shadow bg-base-100 rounded-box w-44">
<!--
http://localhost/nova/resources/our-articles/new?
    viaResource=articles
    viaResourceId=2156
    viaRelationship=ourArticles
    relationshipType=hasMany
-->
                <li><a :href="$url(`/resources/our-articles/new`, {
                          viaResource: 'articles',
                          viaResourceId: article.id,
                          viaRelationship: 'ourArticles',
                          relationshipType: 'hasMany',
                        })
                    ">Repost</a></li>
                <li><a>.. unused</a></li>
                <li><a>.. unused</a></li>
            </ul>
        </dropdown-menu>

@syntheticminds
Copy link

syntheticminds commented Feb 10, 2023

For Nova v4:

use Nova;
$path = Nova::url('/resources/' . \App\Nova\User::uriKey() . '/' . $user_id);

@sfinktah
Copy link

@syntheticminds

Are you are saying that @mgussekloo's solution:

Text::make('Title', function () {
    $url = \Nova::path() . "/resources/{$this->uriKey()}/{$this->id}";
    return "<a class=\"no-underline dim text-primary font-bold\" href=\"{$url}\">{$this->title}</a>";
})->asHtml();

Could be better expressed as:

Text::make('Title', function () {
    // $url = \Nova::path() . "/resources/{$this->uriKey()}/{$this->id}";
    $url = Nova::url('/resources/' . \App\Nova\User::uriKey() . '/' . $this->id /* $user_id */);
    return "<a class=\"no-underline dim text-primary font-bold\" href=\"{$url}\">{$this->title}</a>";
})->asHtml();

?

Though that assumes it is the User resource, but obviously that's minor, and the Nova::url part is the magic. Makes sense :)

@syntheticminds
Copy link

@sfinktah Yes. My example comes from outside a resource class so $this was not available.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests