How to make custom spawners using NBT

You need

Tile entities are blocks that store data. This ("NBT") data is used by the tile entities to execute their functions. Essentially, almost all blocks that have changable gimmicks to them are considered tile entities: chests, mob spawners, skulls, and so on...

This tutorial assumes you have effect commands activated and know how to use them. If you never heard of that before: it's explained in your

1. How to customize a placed mob-spawner
Find or place down a mob spawner. If you placed the mob spawner yourself you will notice that it automatically has a spinning pig inside, which is some hardcoded Mojang magic. We'll get to that in a bit.

Look at the spawner and use
!send "%targeted block's nbt%"

Which should result in seeing something like this:

I think most of the NBT values that are contained within here are quite self-explanatory. If you're having trouble understanding what any these values mean, please visit this: and check out the section for mob spawners. Explaning everything here is futile, as it would be version dependent (I'm using 1.12 as of writing this).

We're just gonna focus on the fun part and learn how to change the mob that is being spawned by the spawner. For this, again, look at the mob spawner, and try this:
!add "{SpawnData:{id:""minecraft:llama""}}" to targeted block's nbt

And the result should be:

Wasn't that nice and easy?
Depending on your MC version, i recommend changing both "SpawnData" and "SpawnPotentials" to the desired mob to be spawned.

2. Allowing players to place custom mob spawners

On to the more fun stuff.
Mob spawners automatically make all spawners that are placed by players spawn pigs instead of what they originally spawned, as i explained earlier. There is no way to (as far as i know), to stop minecraft from doing that, but we can simply overwrite the data on the spawn event.

First off, let's get a custom spawner:
command /test:

set {_spawner} to spawner with custom nbt "{SpawnData:{id:""minecraft:zombie""},SpawnPotentials:[{Entity:{id:""minecraft:zombie""},Weight:1}]}"
set {_spawner}'s name to "Zombie Spawner"
add 1 of {_spawner} to command sender's inventory

Again, if you place this spawner, it will spawn pigs, so let's add a nice little script:
on place of spawner:
add "%event-player's tool's nbt%" to event-block's nbt

Reload... get the spawner, place it, aaaaaaaaaaaaaand:

Spawners are highly customizable. Have fun with this!

Note: Yes, this also works with ender dragons and withers. Don't accidentally let them destroy your stuff.