# Accessing content in a custom field

**URL:** <https://forum.getkirby.com/t/accessing-content-in-a-custom-field/15233>\
**Category:** Questions\
**Tags:** v3\
**Created:** [August 12, 2019, 9:34pm UTC](https://forum.getkirby.com/t/accessing-content-in-a-custom-field/15233 "2019-08-12T21:34:26Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![mshoestrng](https://avatars.discourse-cdn.com/v4/letter/m/ecccb3/32.png) [@mshoestrng](https://forum.getkirby.com/u/mshoestrng)\
**Post date:** [August 12, 2019, 9:34pm UTC](https://forum.getkirby.com/t/accessing-content-in-a-custom-field/15233/1 "2019-08-12T21:34:26Z")

</div>

Hi,

I have a structure field in my blueprint:

```
mitglieder:
        label: Einträge auf der Warteliste
        type: structure
        style: table
        fields:
          vorname:
            type: text
            label: Vorname
          nachname:
            type: text
            label: Name
            # ...

```

As I’m not happy with the way big tables are displayed in the panel, I would like to build my own view for the data in the structure field. I figured that I would probably have to build a custom field plugin.

```
tabellenansicht:
    fields:
      tableview:
        type: tableview

```

In this plugin I would like to loop over the data from the structure field and thus build my table row by row for output in the panel.

1. How can I access the data in the structure field in my custom plugin?
2. Where would I put the looping part? In the index.php or the index.js? What is the code that I need to achieve this? (docs are very sparse on this)
3. I suppose most of my HTML-code should go into the template property in my index.js?! I guess if I have some more lines of HTML code it gets really hard to read if I put it all into the string-value of the template property (quotes in quotes, line breaks etc.). Is there any way to store HTML code separately (e.g. in a \<template\>-tag) where it’s more readable?

Thanks,  
Markus

---

<div class="post-metadata">

**Author:** ![jimbobrjames](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/jimbobrjames/32/5802_2.png) [@jimbobrjames](https://forum.getkirby.com/u/jimbobrjames)\
**Post date:** [August 12, 2019, 10:01pm UTC](https://forum.getkirby.com/t/accessing-content-in-a-custom-field/15233/2 "2019-08-12T22:01:04Z")

</div>

I take it you’ve looked at the plugin kit? [https://github.com/getkirby/pluginkit](https://github.com/getkirby/pluginkit)

Also its probably worth watching Bastian’s live streams on creating a panel plugin. Might clear up a few things for you.

Intro…

Part 2…

---

<div class="post-metadata">

**Author:** ![mshoestrng](https://avatars.discourse-cdn.com/v4/letter/m/ecccb3/32.png) [@mshoestrng](https://forum.getkirby.com/u/mshoestrng)\
**Post date:** [August 13, 2019, 7:29pm UTC](https://forum.getkirby.com/t/accessing-content-in-a-custom-field/15233/3 "2019-08-13T19:29:20Z")

</div>

Still the question is open: how can I access the data in the structure field in my custom plugin?

```
Kirby::plugin('mshoestrng/tableview', [
    'fields' => [
        'tableview' => [
          'computed' => [
            'mytitle' => function() {
              return $page->title();
            }
          ]
        ]
    ]
]);

```

The above gives the error: “Undefined variable: page”. So what’s the correct way to access data in the plugin?

I searched the entire documentation and there is not a single example how to access page data or other data from the PHP API in plugins… (@bastianallgeier @texnixe)

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [August 13, 2019, 7:38pm UTC](https://forum.getkirby.com/t/accessing-content-in-a-custom-field/15233/4 "2019-08-13T19:38:40Z")

</div>

If I remember correctly, you get the page object via `$this->parentModel()`

---

<div class="post-metadata">

**Author:** ![mshoestrng](https://avatars.discourse-cdn.com/v4/letter/m/ecccb3/32.png) [@mshoestrng](https://forum.getkirby.com/u/mshoestrng)\
**Post date:** [August 13, 2019, 7:45pm UTC](https://forum.getkirby.com/t/accessing-content-in-a-custom-field/15233/5 "2019-08-13T19:45:23Z")

</div>

@texnixe thanks! But how can I then access the content of the structure field so I can access the different entries in it in my index.js? Please give a code example. Also is there any way I can debug (e.g. var\_dump()) stuff in index.php and index.js in my component?

It’s very frustrating to develop in Kirby 3 if there is no documentation on this and if one has no way to debug (i.e. echo values) step-by-step in index.php and index.js during development!!

I really don’t want to spend a lot of time reading through all of the Vue documentation etc. So it would be much appreciated if you can give concrete example how I can effectively debug in the new Kirby3/Vue environment.

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [August 13, 2019, 8:00pm UTC](https://forum.getkirby.com/t/accessing-content-in-a-custom-field/15233/6 "2019-08-13T20:00:43Z")

</div>

You can pass your structure items as a query in your field

Then you could fetch the items like this in youur index.php

```auto
      'computed' => [
                'items' => function () {
                    $q = new Kirby\Toolkit\Query($this->query, [
                        'site' => site(),
                        'page' => $this->model(),
                        'pages' => site()->pages()
                    ]);
                    $result = $q->result();
                    return $result->pluck($this->field);
                }
            ]

```

Note that in the example, I only pluck a single field from the structure. The items are then available in your JS.

Unfortunately, I can’t help you a lot with this. My best advice is to look at example plugins. And yes, we have to provide better documentation and I would do it if I knew more about this stuff.

---

<div class="post-metadata">

**Author:** ![mshoestrng](https://avatars.discourse-cdn.com/v4/letter/m/ecccb3/32.png) [@mshoestrng](https://forum.getkirby.com/u/mshoestrng)\
**Post date:** [August 13, 2019, 8:04pm UTC](https://forum.getkirby.com/t/accessing-content-in-a-custom-field/15233/7 "2019-08-13T20:04:11Z")

</div>

@bastianallgeier you pointed me to [https://github.com/getkirby/kirby/blob/master/panel/src/components/Forms/Field/StructureField.vue](https://github.com/getkirby/kirby/blob/master/panel/src/components/Forms/Field/StructureField.vue) the other day for the source of the structure field, but where is the PHP part of it? Maybe this helps me to understand how the data is passed to the vue.

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [August 13, 2019, 8:05pm UTC](https://forum.getkirby.com/t/accessing-content-in-a-custom-field/15233/8 "2019-08-13T20:05:15Z")

</div>

In `/kirby/config/fields/structure.php`

Ok, so you don’t want to build anything that fetches data from a structure field but you want to build a custom structure field, it seems? In that case, forget the above.

Wouldn’t it then make sense to use the structure field as basis and only changed the Vue part that displays the data?

---

<div class="post-metadata">

**Author:** ![mshoestrng](https://avatars.discourse-cdn.com/v4/letter/m/ecccb3/32.png) [@mshoestrng](https://forum.getkirby.com/u/mshoestrng)\
**Post date:** [August 26, 2019, 11:41pm UTC](https://forum.getkirby.com/t/accessing-content-in-a-custom-field/15233/9 "2019-08-26T23:41:47Z")

</div>

Honestly folks, this is so frustrating!!!

![screen1](https://europe1.discourse-cdn.com/flex017/uploads/getkirby/original/2X/8/8acfbc86ed4d2b704e84821ad891b9f45b6a64c9.png)

This is my setup now after installing parcel.js and running `npm run dev` as Bastian suggests in his video above.

index.php

```
<?php

Kirby::plugin('mshoestrng/tableview', [
    'fields' => [
      'tableview' => [

      ]
    ]
]);

?>

```

src/index.js

```
// import TableView from "./components/tableView.vue";

panel.plugin('mshoestrng/tableview', {
  fields: {
    // tableview: TableView
    tableview: {
      template: "<p>hello wor</p>"
    }
  }
});

```

src/components/tableView.vue

```
<template>
  <h1>hello world</h1>
</template>

<script>

</script>

<style>

</style>

```

/site/blueprints/pages/warteliste.yml

```
...
tabellenansicht:
    fields:
      tableview:
        type: tableview
...

```

And all I get is this ridiculous error message:

 ![screen2](https://europe1.discourse-cdn.com/flex017/uploads/getkirby/original/2X/4/446845ee4e506f2327f9344f16b84925fcc14cd0.png)

Are you serious?? How is anyone supposed to do any proper dev work if the error message doesn’t even show the filename and line number where the error occurs??? @bastianallgeier @texnixe

When I uncomment the lines in index.js and remove the “old” `tableview` instead the same error persists.

When I move my index.js (as posted above) to the main directory of my plugin it works just fine.

So what’s the problem here?? How do I get the tableView.vue to work properly?

---

<div class="post-metadata">

**Author:** ![sylvainjule](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/sylvainjule/32/4338_2.png) [@sylvainjule](https://forum.getkirby.com/u/sylvainjule)\
**Post date:** [August 27, 2019, 6:59am UTC](https://forum.getkirby.com/t/accessing-content-in-a-custom-field/15233/10 "2019-08-27T06:59:52Z")

</div>

Avoid closing PHP tags at the end of files, it can cause unwanted output.

Removing `?>` at the end of `index.php` will fix your issue and make everything work as intended.

---

<div class="post-metadata">

**Author:** ![mshoestrng](https://avatars.discourse-cdn.com/v4/letter/m/ecccb3/32.png) [@mshoestrng](https://forum.getkirby.com/u/mshoestrng)\
**Post date:** [August 27, 2019, 6:50pm UTC](https://forum.getkirby.com/t/accessing-content-in-a-custom-field/15233/11 "2019-08-27T18:50:52Z")

</div>

No, I’m afraid, it’s still the same error 😢

---

<div class="post-metadata">

**Author:** ![sylvainjule](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/sylvainjule/32/4338_2.png) [@sylvainjule](https://forum.getkirby.com/u/sylvainjule)\
**Post date:** [August 27, 2019, 7:36pm UTC](https://forum.getkirby.com/t/accessing-content-in-a-custom-field/15233/12 "2019-08-27T19:36:56Z")

</div>

Huh, that was the only thing that went wrong when I tried to reproduce your issue.  
These steps :

1. Download the [pluginkit panel zip](https://github.com/getkirby/pluginkit/archive/4-panel.zip)
2. Unzip in site/plugins
3. Copy/paste your snippets (with import) in `index.php`, `src/index.js` and `src/components/tableView.vue`
4. Run `npm run build`

Give me a h1 “hello world” in the panel…

---

<div class="post-metadata">

**Author:** ![mshoestrng](https://avatars.discourse-cdn.com/v4/letter/m/ecccb3/32.png) [@mshoestrng](https://forum.getkirby.com/u/mshoestrng)\
**Post date:** [August 27, 2019, 8:08pm UTC](https://forum.getkirby.com/t/accessing-content-in-a-custom-field/15233/13 "2019-08-27T20:08:00Z")

</div>

I did exactly what you wrote above (I presume). Same error… Any hints would be greatly appreciated.

Also how I can debug this to find the cause for the error? As I have never worked with Vue.js before and also don’t want to get a lot into it just because I want to use the new version of Kirby any clues would be of great help!

P.S. During build I get the following warning: `npm WARN pluginkit-4-panel No repository field.` What does this mean?

---

<div class="post-metadata">

**Author:** ![sylvainjule](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/sylvainjule/32/4338_2.png) [@sylvainjule](https://forum.getkirby.com/u/sylvainjule)\
**Post date:** [August 27, 2019, 9:29pm UTC](https://forum.getkirby.com/t/accessing-content-in-a-custom-field/15233/14 "2019-08-27T21:29:01Z")

</div>

That’s odd. Latest Kirby version? What’s the output in `index.js`?

The NPM warn shouldn’t worry you, the repository field is an incentive to mention where the code is if public (git repos, etc), if you don’t want to be bothered with this you can add `private: true` somewhere in your package.json

---

<div class="post-metadata">

**Author:** ![mshoestrng](https://avatars.discourse-cdn.com/v4/letter/m/ecccb3/32.png) [@mshoestrng](https://forum.getkirby.com/u/mshoestrng)\
**Post date:** [August 28, 2019, 7:33pm UTC](https://forum.getkirby.com/t/accessing-content-in-a-custom-field/15233/15 "2019-08-28T19:33:16Z")

</div>

Where can I find a non-minified version of /panel/dist/js/app.js so I can actually drill down on what causes the error message to show?

Here is the output if two different index.js:

Following Sylvain’s instructions:

```
(function () {function b(a){return a&&a.__esModule?{d:a.default}:{d:a}}var a={};if(typeof a==="function"){a=a.options}Object.assign(a,function(){var render=function(){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c("h1",[_vm._v("hello world")])};var staticRenderFns=[];return{render:render,staticRenderFns:staticRenderFns,_compiled:true,_scopeId:null,functional:undefined}}());var c=b(a);panel.plugin("mshoestrng/tableview",{fields:{tableview:c.d}});})();

```

Following Bastian’s instructions (from his screen cast):

```
// modules are defined as an array
// [module function, map of requires]
//
// map of requires is short require name -> numeric require
//
// anything defined in a previous bundle is accessed via the
// orig method which is the require for previous bundles
parcelRequire = (function (modules, cache, entry, globalName) {
  // Save the require from previous bundle to this closure if any
  var previousRequire = typeof parcelRequire === 'function' && parcelRequire;
  var nodeRequire = typeof require === 'function' && require;

  function newRequire(name, jumped) {
    if (!cache[name]) {
      if (!modules[name]) {
        // if we cannot find the module within our internal map or
        // cache jump to the current global require ie. the last bundle
        // that was added to the page.
        var currentRequire = typeof parcelRequire === 'function' && parcelRequire;
        if (!jumped && currentRequire) {
          return currentRequire(name, true);
        }

        // If there are other bundles on this page the require from the
        // previous one is saved to 'previousRequire'. Repeat this as
        // many times as there are bundles until the module is found or
        // we exhaust the require chain.
        if (previousRequire) {
          return previousRequire(name, true);
        }

        // Try the node require function if it exists.
        if (nodeRequire && typeof name === 'string') {
          return nodeRequire(name);
        }

        var err = new Error('Cannot find module \'' + name + '\'');
        err.code = 'MODULE_NOT_FOUND';
        throw err;
      }

      localRequire.resolve = resolve;
      localRequire.cache = {};

      var module = cache[name] = new newRequire.Module(name);

      modules[name][0].call(module.exports, localRequire, module, module.exports, this);
    }

    return cache[name].exports;

    function localRequire(x){
      return newRequire(localRequire.resolve(x));
    }

    function resolve(x){
      return modules[name][1][x] || x;
    }
  }

  function Module(moduleName) {
    this.id = moduleName;
    this.bundle = newRequire;
    this.exports = {};
  }

  newRequire.isParcelRequire = true;
  newRequire.Module = Module;
  newRequire.modules = modules;
  newRequire.cache = cache;
  newRequire.parent = previousRequire;
  newRequire.register = function (id, exports) {
    modules[id] = [function (require, module) {
      module.exports = exports;
    }, {}];
  };

  var error;
  for (var i = 0; i < entry.length; i++) {
    try {
      newRequire(entry[i]);
    } catch (e) {
      // Save first error but execute all entries
      if (!error) {
        error = e;
      }
    }
  }

  if (entry.length) {
    // Expose entry point to Node, AMD or browser globals
    // Based on https://github.com/ForbesLindesay/umd/blob/master/template.js
    var mainExports = newRequire(entry[entry.length - 1]);

    // CommonJS
    if (typeof exports === "object" && typeof module !== "undefined") {
      module.exports = mainExports;

    // RequireJS
    } else if (typeof define === "function" && define.amd) {
     define(function () {
       return mainExports;
     });

    // <script>
    } else if (globalName) {
      this[globalName] = mainExports;
    }
  }

  // Override the current require with this new one
  parcelRequire = newRequire;

  if (error) {
    // throw error from earlier, _after updating parcelRequire_
    throw error;
  }

  return newRequire;
})({"index.js":[function(require,module,exports) {
// import TableView from "./components/tableView.vue";
panel.plugin('mshoestrng/tableview', {
  fields: {
    // tableview: TableView
    tableview: {
      template: "<p>hello wor</p>"
    }
  }
});
},{}],"../../../../../../../../../../usr/local/lib/node_modules/parcel-bundler/src/builtins/hmr-runtime.js":[function(require,module,exports) {
var global = arguments[3];
var OVERLAY_ID = ' __parcel__ error __overlay__';
var OldModule = module.bundle.Module;

function Module(moduleName) {
  OldModule.call(this, moduleName);
  this.hot = {
    data: module.bundle.hotData,
    _acceptCallbacks: [],
    _disposeCallbacks: [],
    accept: function (fn) {
      this._acceptCallbacks.push(fn || function () {});
    },
    dispose: function (fn) {
      this._disposeCallbacks.push(fn);
    }
  };
  module.bundle.hotData = null;
}

module.bundle.Module = Module;
var checkedAssets, assetsToAccept;
var parent = module.bundle.parent;

if ((!parent || !parent.isParcelRequire) && typeof WebSocket !== 'undefined') {
  var hostname = "" || location.hostname;
  var protocol = location.protocol === 'https:' ? 'wss' : 'ws';
  var ws = new WebSocket(protocol + '://' + hostname + ':' + "63864" + '/');

  ws.onmessage = function (event) {
    checkedAssets = {};
    assetsToAccept = [];
    var data = JSON.parse(event.data);

    if (data.type === 'update') {
      var handled = false;
      data.assets.forEach(function (asset) {
        if (!asset.isNew) {
          var didAccept = hmrAcceptCheck(global.parcelRequire, asset.id);

          if (didAccept) {
            handled = true;
          }
        }
      }); // Enable HMR for CSS by default.

      handled = handled || data.assets.every(function (asset) {
        return asset.type === 'css' && asset.generated.js;
      });

      if (handled) {
        console.clear();
        data.assets.forEach(function (asset) {
          hmrApply(global.parcelRequire, asset);
        });
        assetsToAccept.forEach(function (v) {
          hmrAcceptRun(v[0], v[1]);
        });
      } else {
        window.location.reload();
      }
    }

    if (data.type === 'reload') {
      ws.close();

      ws.onclose = function () {
        location.reload();
      };
    }

    if (data.type === 'error-resolved') {
      console.log('[parcel] ✨ Error resolved');
      removeErrorOverlay();
    }

    if (data.type === 'error') {
      console.error('[parcel] 🚨 ' + data.error.message + '\n' + data.error.stack);
      removeErrorOverlay();
      var overlay = createErrorOverlay(data);
      document.body.appendChild(overlay);
    }
  };
}

function removeErrorOverlay() {
  var overlay = document.getElementById(OVERLAY_ID);

  if (overlay) {
    overlay.remove();
  }
}

function createErrorOverlay(data) {
  var overlay = document.createElement('div');
  overlay.id = OVERLAY_ID; // html encode message and stack trace

  var message = document.createElement('div');
  var stackTrace = document.createElement('pre');
  message.innerText = data.error.message;
  stackTrace.innerText = data.error.stack;
  overlay.innerHTML = '<div style="background: black; font-size: 16px; color: white; position: fixed; height: 100%; width: 100%; top: 0px; left: 0px; padding: 30px; opacity: 0.85; font-family: Menlo, Consolas, monospace; z-index: 9999;">' + '<span style="background: red; padding: 2px 4px; border-radius: 2px;">ERROR</span>' + '<span style="top: 2px; margin-left: 5px; position: relative;">🚨</span>' + '<div style="font-size: 18px; font-weight: bold; margin-top: 20px;">' + message.innerHTML + '</div>' + '<pre>' + stackTrace.innerHTML + '</pre>' + '</div>';
  return overlay;
}

function getParents(bundle, id) {
  var modules = bundle.modules;

  if (!modules) {
    return [];
  }

  var parents = [];
  var k, d, dep;

  for (k in modules) {
    for (d in modules[k][1]) {
      dep = modules[k][1][d];

      if (dep === id || Array.isArray(dep) && dep[dep.length - 1] === id) {
        parents.push(k);
      }
    }
  }

  if (bundle.parent) {
    parents = parents.concat(getParents(bundle.parent, id));
  }

  return parents;
}

function hmrApply(bundle, asset) {
  var modules = bundle.modules;

  if (!modules) {
    return;
  }

  if (modules[asset.id] || !bundle.parent) {
    var fn = new Function('require', 'module', 'exports', asset.generated.js);
    asset.isNew = !modules[asset.id];
    modules[asset.id] = [fn, asset.deps];
  } else if (bundle.parent) {
    hmrApply(bundle.parent, asset);
  }
}

function hmrAcceptCheck(bundle, id) {
  var modules = bundle.modules;

  if (!modules) {
    return;
  }

  if (!modules[id] && bundle.parent) {
    return hmrAcceptCheck(bundle.parent, id);
  }

  if (checkedAssets[id]) {
    return;
  }

  checkedAssets[id] = true;
  var cached = bundle.cache[id];
  assetsToAccept.push([bundle, id]);

  if (cached && cached.hot && cached.hot._acceptCallbacks.length) {
    return true;
  }

  return getParents(global.parcelRequire, id).some(function (id) {
    return hmrAcceptCheck(global.parcelRequire, id);
  });
}

function hmrAcceptRun(bundle, id) {
  var cached = bundle.cache[id];
  bundle.hotData = {};

  if (cached) {
    cached.hot.data = bundle.hotData;
  }

  if (cached && cached.hot && cached.hot._disposeCallbacks.length) {
    cached.hot._disposeCallbacks.forEach(function (cb) {
      cb(bundle.hotData);
    });
  }

  delete bundle.cache[id];
  bundle(id);
  cached = bundle.cache[id];

  if (cached && cached.hot && cached.hot._acceptCallbacks.length) {
    cached.hot._acceptCallbacks.forEach(function (cb) {
      cb();
    });

    return true;
  }
}
},{}]},{},["../../../../../../../../../../usr/local/lib/node_modules/parcel-bundler/src/builtins/hmr-runtime.js","index.js"], null)
```

---

<div class="post-metadata">

**Author:** ![sylvainjule](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/sylvainjule/32/4338_2.png) [@sylvainjule](https://forum.getkirby.com/u/sylvainjule)\
**Post date:** [August 29, 2019, 4:22pm UTC](https://forum.getkirby.com/t/accessing-content-in-a-custom-field/15233/16 "2019-08-29T16:22:38Z")

</div>

You’d have to dive through the kirby repo to get the app.js source, the error is displayed by [the error-boundary component](https://github.com/getkirby/kirby/blob/80b69380e672565a849037232c9951d1e32774c8/panel/src/components/Misc/ErrorBoundary.vue), but if there’s nothing in the console I’m afraid you’ll find very little by inspecting this one. The error is thrown [here](https://github.com/getkirby/kirby/blob/80b69380e672565a849037232c9951d1e32774c8/src/Form/Field.php#L50), so probably means your PHP file isn’t registered correctly.

The output looks fine, I created a new folder with nothing but your index.php + outputted index.js, **hello world** shows.

I see you have other plugins in the folder, have you tried removing them and keeping only your plugin to see if one is causing interferences?

---

<div class="post-metadata">

**Author:** ![mshoestrng](https://avatars.discourse-cdn.com/v4/letter/m/ecccb3/32.png) [@mshoestrng](https://forum.getkirby.com/u/mshoestrng)\
**Post date:** [August 30, 2019, 10:40pm UTC](https://forum.getkirby.com/t/accessing-content-in-a-custom-field/15233/17 "2019-08-30T22:40:47Z")

</div>

I now went back to the start and installed the Kirby starter kit in a new folder. Afterwards I created a simple plugin extending the text field following this guide: [https://getkirby.com/docs/reference/plugins/extensions/fields#extending-existing-fields](https://getkirby.com/docs/reference/plugins/extensions/fields#extending-existing-fields)

about.yml

```
# ...
blaha:
        label: My plugin
        type: hello
        default: 123
# ....

```

index.php

```
<?php

Kirby::plugin('your/plugin', [
    'fields' => [
        'hello' => [
            'extends' => 'text'
        ]
    ]
]);

```

index.js

```
panel.plugin("your/plugin", {
  fields: {
    hello: {
      extends: "k-text-field",
      template: "<input>whatsup</input>"
    }
  }
});

```

This shows me a clickable/writable input field.

However, when I remove the “template” line it only show this:

![image](https://europe1.discourse-cdn.com/flex017/uploads/getkirby/original/2X/c/cf4e3fa951e69fc320a02d89593139035337097d.png)

…while I would expect it shows a text input (as I’m extending the text field without adding anything).

Why is this not working??

---

<div class="post-metadata">

**Author:** ![sylvainjule](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/sylvainjule/32/4338_2.png) [@sylvainjule](https://forum.getkirby.com/u/sylvainjule)\
**Post date:** [August 31, 2019, 6:54am UTC](https://forum.getkirby.com/t/accessing-content-in-a-custom-field/15233/18 "2019-08-31T06:54:44Z")

</div>

If you haven’t already, you should get the Vue.js devtools extensions, it will help you debug these kind of things.

Put one `text` field next to your `hello` field, and check what differs between the two in your devtools.

What’s happening here: inside the `k-text-field` there’s a `k-text-input` component (the actual input). Kirby automatically deduces the name of the input from the field type, so that `k-select-field` loads a `k-select-input`, etc.

Because your field is called `hello`, the field is trying to load a `k-hello-input`. That doesn’t exist. So nothing shows.

![04](https://europe1.discourse-cdn.com/flex017/uploads/getkirby/original/2X/3/3fb43abb0a0bf068903ad28cda796fd201795695.png)

So, the field will work as planned after creating a `k-hello-input` (or rewriting the text field template so that it always load the `k-text-input` no matter what the field type is, but more tedious overall):

```auto
panel.plugin("your/plugin", {
  fields: {
    hello: { extends: "k-text-field" }
  },
  components: {
    'k-hello-input': { extends: "k-text-input" }
  }
});

```

---

<div class="post-metadata">

**Author:** ![mshoestrng](https://avatars.discourse-cdn.com/v4/letter/m/ecccb3/32.png) [@mshoestrng](https://forum.getkirby.com/u/mshoestrng)\
**Post date:** [September 27, 2019, 7:32pm UTC](https://forum.getkirby.com/t/accessing-content-in-a-custom-field/15233/19 "2019-09-27T19:32:50Z")

</div>

Ok, this worked. Thanks!

Now I tried to take the next step and move this into a component structure.

your-plugin/src/index.js:

```
// import myText from "./components/mytext.vue";

panel.plugin("your/plugin", {
  fields: {
    // hello: myText
    hello: {
      extends: "k-text-field",
      template: "<input>whatsup</input>"
    }
  },
  components: {
    'k-hello-input': { extends: "k-text-input" }
  }
});

```

However, after compiling with `npm run dev`, I still get the error message `The field type "bla" does not exist` in the panel. What am I doing wrong?

**Just to clarify:** all I’m looking for is a way to extend/ **modify the template** (looks) of the **structure field**. So I need a setup where my field plugin provides me with a vue-component where I can paste/extend the original template code of the structure field.

@sylvainjule: would it be possible that you provide me with a skeleton for this purpose? Otherwise I think it will take many more posts for me to move from my simple text field plugin via a component-type plugin extending the text field to finally a component-type plugin extending the structure field without any proper debugging tools in the Kirby panel…

Your or anyone else’s help would be much appreciated! Thanks!

---

<div class="post-metadata">

**Author:** ![mshoestrng](https://avatars.discourse-cdn.com/v4/letter/m/ecccb3/32.png) [@mshoestrng](https://forum.getkirby.com/u/mshoestrng)\
**Post date:** [September 27, 2019, 9:36pm UTC](https://forum.getkirby.com/t/accessing-content-in-a-custom-field/15233/20 "2019-09-27T21:36:14Z")

</div>

Here is another take I tried with still the same error: `The field type "bla2" does not exist`. Any help for this and my post just above would be much appreciated!

about.yml:

```
  bla:
    label: My plugin
    type: myplugtest
  bla2:
    label: My pluginevo
    type: myplugtestevo
  blax:
    type: text

```

index.php:

```
<?php

Kirby::plugin('test/pluginevo', [
    'fields' => [
        'myplugtestevo' => [
            'extends' => 'text'
        ]
    ]
]);

```

src/index.js:

```
import myplugtestevo from "./components/myplugtestevo.vue";

panel.plugin("test/pluginevo", {
  fields: {
    myplugtestevo: myplugtestevo
  },
  components: {
    'k-myplugtestevo-input': { extends: "k-text-input" }
  }
});

```

src/components/myplugtestevo.vue:

```
<template>
  <p>hello</p>

</template>

<script>
  export default {
    extends: "k-text-field"
  }

</script>

<style>

</style>

```

This is what the vue.js devtools are showing me. Again: how the hell is one supposed to deduct any debugging hints from the absence of useful information??

![image](https://europe1.discourse-cdn.com/flex017/uploads/getkirby/original/2X/2/2c628414c5847ee3a6ec3e91990e201b81b40234.png)

[Next page](https://forum.getkirby.com/t/accessing-content-in-a-custom-field/15233.md?page=2)
