I went back and forth on this. In the end, I put everything in code. I decided I wanted the minimum amount of stuff configured in jenkins.
I started out with a wrapper pipeline that loaded the "guts" of the job. This was extremely restrictive in that each job had to conform at some level to the expectations of the wrapper. I switched to a library of code and all of my common parameters are stored in the library. I found that this was also easier to debug as I could create a jenkins job that loaded the library and ran the unit tests that I defined inside it.
This is all using multi-branch pipelines, BTW, and my devops code is in the same repo as the product code, so it all gets branched at the same time. This gives me more confidence that I can reproduce any build later, no matter how much my devops code changes. If you store this library in a different repo, then make sure you have some way to select the correct version or else you will have trouble reproducing old builds (I often have 7 or more branches in development so this is important to me).