statamic / cms

The core Laravel CMS Composer package
https://statamic.com
Other
3.58k stars 490 forks source link

Statamic::tag('collection:external_links')->fetch() returns an empty collection, but Statamic::tag('collection:pages')-fetch() works? #8558

Open Dimchao opened 11 months ago

Dimchao commented 11 months ago

Bug description

I have two Collections created: 1) pages; 2) external_links. The 'pages' collection contains all of page Entries of my site, which includes a route_name field. The external_links collection hold Entries that just have URL values associated with them, plus labels and a rount_name field for using Laravel's named routing system.

In my web/routes.php, I call to grab these collections using the Statamic:tag method. When I use Statamic::tag('collection:pages')->fetch() I receive all of the active pages on the site as expected. However, I receive nothing when I use Statamic::tag('collection:external_links')->fetch(). I cannot for the life of me figure out why this is the case.

How to reproduce

  1. Create two collections: Pages and External Links
  2. In their respective resources/blueprints directories, have a single yaml file for each collection (outlined below).
  3. In the web/routes.php file, write the code (outlined below).

resources/blueprints/pages/page.yaml

tabs:
  main:
    display: Main
    sections:
      -
        fields:
          -
            handle: title
            field:
              type: text
              required: true
              validate:
                - required
  sidebar:
    display: Sidebar
    sections:
      -
        fields:
          -
            handle: slug
            field:
              type: slug
              localizable: true
          -
            handle: route_name
            field:
              from: title
              generate: true
              show_regenerate: false
              type: slug
              display: 'Route Name'
              icon: slug
              instructions: 'This is the Laravel Route Name'
              listable: hidden
              instructions_position: below
              visibility: visible
              hide_display: false
          -
            handle: template
            field:
              hide_partials: false
              blueprint: false
              folder: page-templates
              type: template
              display: 'Page Layout'
              icon: template
              instructions: 'Set the page template to be used for this page (e.g. gallery, hero page, default, etc.)'
              listable: true
              instructions_position: below
              visibility: visible
              hide_display: false
              default: page-templates/default
          -
            handle: layout
            field:
              hide_partials: false
              blueprint: false
              folder: layouts/app
              type: template
              display: 'Application Layout'
              icon: template
              instructions: 'Set the page layout to be used for this page.'
              listable: hidden
              instructions_position: below
              visibility: visible
              hide_display: false
              default: app/default

resources/blueprints/external_links/link.yaml

title: Link
tabs:
  main:
    display: Main
    sections:
      -
        fields:
          -
            handle: title
            field:
              type: text
              required: true
              validate:
                - required
          -
            handle: redirect
            field:
              type: link
              validate:
                - required
              instructions_position: above
              listable: hidden
              visibility: visible
              collections:
                - pages
              hide_display: false
          -
            handle: route_name
            field:
              input_type: text
              antlers: false
              type: text
              display: 'Route Name'
              icon: text
              listable: hidden
              instructions_position: above
              visibility: visible
              hide_display: false

routes/web.php

$pages = Statamic::tag('collection:pages')
            ->fetch();

$externalLinks = Statamic::tag('collection:external_links')
            ->fetch();

dd($pages, $externalLinks);

Logs

log file is empty since the site is running relatively fine except for this issue.

Environment

Environment
Application Name: My Application
Laravel Version: 10.18.0
PHP Version: 8.2.8
Composer Version: 2.5.8
Environment: local
Debug Mode: ENABLED
URL: localhost
Maintenance Mode: OFF

Cache
Config: NOT CACHED
Events: NOT CACHED
Routes: NOT CACHED
Views: CACHED

Drivers
Broadcasting: log
Cache: statamic
Database: mysql
Logs: stack / single
Mail: smtp
Queue: sync
Session: file

Statamic
Addons: 0
Antlers: runtime
Stache Watcher: Enabled
Static Caching: Disabled
Version: 4.16.0 Solo

Installation

Other (please explain)

Antlers Parser

None

Additional details

I install Statamic through your documentation for docker. Which technically mean I installed Laravel first and then Statamic on top of it?

ryanmitchell commented 11 months ago

Thats strange. Are you sure external_links is the handle?

What do you get if you try \Statamic\Facades\Entry::whereCollection('external_links')?

Dimchao commented 11 months ago

That works beautifully!

Yeah, it is a weird bug and I have tried SO many ways of trying to understand what either I was doing wrong, or if my settings/yaml files were corrupted.

I have been wracking my brain over this.

As an aside: A lot of the docs mention that you can do something... but don't actually say how, or it's too cryptic to understand unless you probably made Statamic. It took me several days before I gave up on trying to extend Bard functionality. Another two before I understood that I should work around the Markdown and go straight to CommonMark extensions.

I am mostly working with Blade since this is my first Stamic site and I prefer working with nuts and bolts of Laravel. It's been a bear to say the least. That said, Statamic is freaking incredible! I just wish it was easier to work with as a beginning learning it.

Real examples would help immensly in the documentation. That's why I mentioned CommonMark above. They gave a real world example immediately unlocked understanding.

Sorry... needed to vent. Two days behind on the project now because of the lack of documentation. But seriously, incredible CMS.

ryanmitchell commented 11 months ago

Ouch, sorry to hear that.

There is a very active discord channel you can hop into and ask questions. Also do raise issues on the docs repo to highlight what you think could be better, I'm sure the core team would appreciate the feedback.

Dimchao commented 11 months ago

@ryanmitchell Yeah, I've thought of raising issues on the docs. It's just system wide and I've needed to focus on this project (launch is next week). Not to mention, the CMS is so good. I didn't want anything I said come across like $^!%ing on someone else's baby. It just needs real world examples in the docs...

An example from the Statamic Markdown (i.e. not helpful documentation):

Configuration

You may customize the behavior of the markdown parser by providing a CommonMark config array in config/statamic/markdown.php. All the available options are outlined in the CommonMark docs. You can override the base options as well as any extension’s options.

You only need to provide the specific options you want to override. For example:

'configs' => [
    'default' => [
        'allow_unsafe_links' => false, 
        'heading_permalink' => [
            'symbol' => '#',
        ], 
    ]
]

This is not any more useful than looking at the config file itself. It wasn't until I spent about 10 hours in a full code deepdive and dd'ing everything I could to understand that when you want to extend the Markdown as provided in the docs:

Markdown::extend('special', function ($parser) {
    return $parser
        ->withStatamicDefaults()
        ->addExtensions(...);
});

'special' is the actual named parser which you then need to name and set specifically in the config file and that to mess with the parameters of the commonmark markdown packaged with Statamic, you need to denote that in its own place in the configs as well...

Hopefully more useful example

'configs' => [
    'default' => [
        'allow_unsafe_links' => false, 
        'heading_permalink' => [
            'symbol' => '#',
        ], 
    ],
    'special' => [
        'configuration_value_1' => 'allow_all',
        'configuration_value_2' => 'jump_when_found',
    ],
]

Then of course you'll have no way of extending through Statamic without CommonMark's default's which will abort all markup if there are any html tags included in your passed string. Gah! ANyways... I've built what I needed now (markup to pull in values from Statamic's globals and any values from config files). I was surprised this wasn't a feature already.

Clearly needed to vent... :)

jasonvarga commented 11 months ago

Are the entries in your external_links collection all drafts?

Dimchao commented 11 months ago

@jasonvarga everything is published. Just double checked too.

jasonvarga commented 11 months ago

Can you share content/collections/external_links.yaml?

Dimchao commented 11 months ago

@jasonvarga

title: 'External Links'
template: default
revisions: false
sort_dir: asc
date_behavior:
  past: public
  future: private
preview_targets:
  -
    label: Entry
    url: '{permalink}'
    refresh: true
jasonvarga commented 11 months ago

Seems fine. 🤔

Can you share a couple of the external_links entry md files?

Dimchao commented 11 months ago

@jasonvarga This is directly from my files, but I did need to redact the URL's

volunteer-signup-form.md

---
id: 37a55890-dea9-427a-a3f9-2199a1d3c372
blueprint: link
title: 'Volunteer Signup Form'
redirect: 'https://forms.office.com/Pages/ResponsePage.aspx?id=redacted'
route_name: external.volunteer-signup
updated_by: 2
updated_at: 1691394968
---

instagram.md

---
id: 4cdf1149-7cd7-43d8-acdc-c237ff3a7c12
blueprint: link
title: Instagram
redirect: 'https://www.instagram.com/'
route_name: external.instagram
updated_by: 2
updated_at: 1691637887
---

facebook.md

---
id: dc89df49-b3a4-4774-ac21-0a6bfdef8424
blueprint: link
title: Facebook
redirect: 'https://www.facebook.com/'
route_name: external.facebook
updated_by: 2
updated_at: 1691637940
---
jasonvarga commented 11 months ago

Ah there we go. Redirects are filtered out by the tag by default.

CleanShot 2023-08-10 at 17 59 18

Try adding that parameter:

$externalLinks = Statamic::tag('collection:external_links')
+ ->redirects(true)
  ->fetch();
Dimchao commented 11 months ago

@jasonvarga gotcha... so how can I make an entry and just have the URL be what I set it to be, internal or external? Or, is that not possible and I need to use redirects? I honselty had no idea how this was even set. Still learning Statamic by reading as much as I can and dding everything I can to try and figure it out.

I've been trying to figure out a way to allow my client to register whatever external links they need, so I can run the scripts and templates I need to manage their site. I still find great use using the laravel routing system for a variety of reasons.

Much appreciated for the assist.