vscode-template icon indicating copy to clipboard operation
vscode-template copied to clipboard

A way to ask the user for more variables / values to search and replace for a template?

Open tobiashochguertel opened this issue 4 years ago • 16 comments

I want to be able to search and replace two variables or three per template.

May be make it configurable via template.config.js or per template by having a file in the template folder like template.variables.yml or template.variables.json (more flexible to maybe add default values later or dropdown...) so that visual Studio code ask me also for the value of another variable which I want to search and replace for a template.

I think at the moment it just ask me for variable __templateName__, which value I want to assign.

I have the idea or wish to get asked for 2 or 3 additional variables and use them in my the templates.

Can we get this feature?

tobiashochguertel avatar Mar 21 '21 14:03 tobiashochguertel

Hi @tobiashochguertel It seems like a good idea. However, it will take some time to implement this features 😭

stegano avatar Mar 21 '21 16:03 stegano

What is the part which takes most time? We could find a way which makes it more easier to implement as a basic variant of the feature?

tobiashochguertel avatar Mar 21 '21 16:03 tobiashochguertel

I tried to modify the implementation of renameFileFn in the template.config.js file to receive and process the variable value, but it did not work as expected (contrary to my expectations, the original file name was not passed, so I need to check it again. 😭)

// Snippet of code i tried 
renameFileFn: (fileName, templateName, utils) => {
    const { path } = utils;
    const { base } = path.parse(fileName);
    if(templateName.contains('$')) {
      const [var1, var2] = templateName.split('$');
      return base.replace(RegExp('[var1]', 'gm'), var1 || '')
      .replace(RegExp('[var1]', 'gm'), var2 || '')
    }
    return base.replace(/__templateName__/gm, templateName);
  }
...

I think we need to think a little more about the existing implementation, purpose and compatibility of this extension

Sorry for not being able to quickly fix it. (It’s dawn(UTC+9, in South Korea), so I have to go to work.. 😭)

stegano avatar Mar 21 '21 16:03 stegano

I ask me is that the right starting point? I would start where vscode will ask for the values to replace in templates files. I think to have a fix list of variables which we can use would be okay for the first prototype of this feature.

  • templateName
  • var1
  • var2

then VsCode should ask me for each variable for the value to set (one after one, like it is atm.).

I haven't develop any vscode plugins yet.

tobiashochguertel avatar Mar 22 '21 21:03 tobiashochguertel

Hi @tobiashochguertel Sorry for the late reply, I think your idea is good 😀 (When I made this plugin, I thought about a very simple and reusable way.) In v1.3.0, I'll keep the existing usage and improve it so that the additional variables you suggested can be used. If it can be used with the existing usage, it will be a better plugin!

stegano avatar Mar 28 '21 12:03 stegano

@tobiashochguertel This feature was just released!

stegano avatar Mar 28 '21 17:03 stegano

Rockstar 🤗, amazing. in few hours I will test it. Here in Germany it's night (0:49).

The video is amazing! You should add this or a improved version to the readme file.

Improved version of the video:

  • start with a small overview of a template with 2 or 3 variables ( I mean introduce your template ), beat would be to have a template with one file and 2 or 3 variables in it. By this way you have not to switch to other files in the video. Easier to follow.

  • highlight, like you did it in the end the variables by selecting. So watcher know about what he/she has to give attention.

  • bit slower when you select the variable to define in the next step.

I like such small videos / gif animations to introduce a tool.

tobiashochguertel avatar Mar 28 '21 22:03 tobiashochguertel

Questions:

  • Is Variable Content with space is possible?

Follow up Idea:

  • add a dialog to select variable content transformation, after the input dialog of the variable content.
  1. show available variables, select one variable to fill with content

  2. show input dialog to write down the content for the variable

  3. show a selection dialog to select the transformation of the variable content:

no transformation (*default) Snake case Camel case Kebap case

Next idea:

Can we store the inputs "temporary" in a json file?

I mean, when we spot a mistake after the template creation is done, then we are one step closer for the feature to replay what we filled-in. Because we stored the configuration for a run in a json file, which we could load to prefill the variables.

tobiashochguertel avatar Mar 28 '21 23:03 tobiashochguertel

ah yeah code looks great 👍 I checked and read it 👨‍💻. Looks like that I can implement also some of these features over the week.

I like this simple plugin ;)

tobiashochguertel avatar Mar 28 '21 23:03 tobiashochguertel

This is amazing! I found your extension about a month ago and was learning more about VS Code extensions so I could fork the repository to do exactly what this new feature does.

I love it!

The $$var_ matching pattern is a good choice and I can't think of a case where it would conflict with any scripting language.

I was thinking about how to incorporate different changeCase options to a single set of the same variable. For instance reusing the variable for a widget name such as 'Video Testimonial' but transformed with change-case utility.

Maybe something like after the matched pattern $$var_name check for the same double $ regex immediately after for the transformation.

$$var_name$$ToParamCase

Example:

/*
Widget Name: Video Testimonial
*/
class Widget_Video_Testimonial extends SiteOrigin_Widget {
    function __construct() {
        ...
    }
    siteorigin_widget_register( 'video-testimonial', __FILE__, 'Widget_Video_Testimonial');
}

Would be:

/*
Widget Name: $$var_name
*/
class Widget_$$var_name$$ToConstantCase extends SiteOrigin_Widget {
    function __construct() {
        ...
    }
    siteorigin_widget_register( '$$var_name$$ToParamCase', __FILE__, 'Widget_$$var_name$$ToConstantCase');
}

parsepixel avatar Apr 05 '21 03:04 parsepixel

Rockstar 🤗, amazing. in few hours I will test it. Here in Germany it's night (0:49).

The video is amazing! You should add this or a improved version to the readme file.

Improved version of the video:

  • start with a small overview of a template with 2 or 3 variables ( I mean introduce your template ), beat would be to have a template with one file and 2 or 3 variables in it. By this way you have not to switch to other files in the video. Easier to follow.
  • highlight, like you did it in the end the variables by selecting. So watcher know about what he/she has to give attention.
  • bit slower when you select the variable to define in the next step.

I like such small videos / gif animations to introduce a tool.

Thanks for the great ideas and advice 😀 Although this feature has already been released, we will improve it a bit and include an explanation

stegano avatar Apr 09 '21 15:04 stegano

This is amazing! I found your extension about a month ago and was learning more about VS Code extensions so I could fork the repository to do exactly what this new feature does.

I love it!

The $$var_ matching pattern is a good choice and I can't think of a case where it would conflict with any scripting language.

I was thinking about how to incorporate different changeCase options to a single set of the same variable. For instance reusing the variable for a widget name such as 'Video Testimonial' but transformed with change-case utility.

Maybe something like after the matched pattern $$var_name check for the same double $ regex immediately after for the transformation.

$$var_name$$ToParamCase

Example:

/*
Widget Name: Video Testimonial
*/
class Widget_Video_Testimonial extends SiteOrigin_Widget {
    function __construct() {
        ...
    }
    siteorigin_widget_register( 'video-testimonial', __FILE__, 'Widget_Video_Testimonial');
}

Would be:

/*
Widget Name: $$var_name
*/
class Widget_$$var_name$$ToConstantCase extends SiteOrigin_Widget {
    function __construct() {
        ...
    }
    siteorigin_widget_register( '$$var_name$$ToParamCase', __FILE__, 'Widget_$$var_name$$ToConstantCase');
}

Thanks for using this extension and suggesting great ideas. 😀

There are cases where variable names and regular strings are mixed, and to solve this problem, it seems that you need to include $$ signs before and after as follows. 🤔

function getUser$$var_userFuncName$$Func() {  // it can be `getUserNameFunc` or getUserAgeFunc`
  ...             
}

Actually, your suggested feature is intended not only to change the existing string case, but also to be freely converted and used. Although it is a slightly different method, i'm considering improving it so that you can change the string case or etc.. by additionally selecting predefined functions. 😀

For example, you can define a macro in the template.config.js file, change the variable, and select a predefined macro to do additional work as follows.

// template.config.js
...
macro: {
  enable: true,
  define: {
    changePascalCase: () => { ... },
    changeCamelCase: () => { ... }
  }
}

Steps

It's the same https://github.com/stegano/vscode-template/issues/20#issuecomment-808975624

  1. Choose Template
  2. Select variable and input value
  3. Select Macro name(changePascalCase or changeCamelCase) or Skip
  4. Create file from template

If I included too much information in the file name, it would be confusing, so I thought about it as follows. Do you have any good opinions?

stegano avatar Apr 09 '21 16:04 stegano

@stegano I had that very concern myself about including too much information in the file name. Although I could not come up with a better possible solution and why I wanted to start the conversation with everyone.

I like the idea presented in #20. Correct me if I'm wrong with my logic in walking through the steps. Why would the user need to choose step 3 and select a macro to change the case. The replace action is global and all instances of $$var_[...] will become the input value. So if the user wants to transform Video Testimonial to camel case, why wouldn't they just input videoTestimonial in step 2?

The current solution would be for the user to set up multiple variable for each case type.
 $$var_name -> Video testimonial$$var_class -> Video Testimonial 
$$var_file -> _video-testimonial
_ etc..

What I was purposing was a way to indicate in the template itself at each instance of the $$var a way to know that in this location it should be transformed into the proper case. So one $$var_[...] prompt is displayed once and in each of the locations get transformed as needed by the template, not in the step 3 prompt.

For an example using the string "Video testimonial"
 After getting the input for the variable $$var_name the extension would check for a wrapper or for a following case change function. 
$$var_name$$changePascalCase -> VideoTestimonial
 $$var_name$$changeParamCase -> video-testimonial
 $$var_name$$changeCamelCase -> videoTestimonial

and without any transformation just replace as is
 $$var_name -> Video testimonial

I do agree the additional characters would be visually confusing for someone who is first trying to use the extension but I don't know how else to do it.

The problem is trying to regex pattern what follows the variable for the transformation can't possibly be mistaken as part of the template.

$$var_name(changePascalCase) could potentially be overwrite what was intended as a function(changePascalCase) for some reason.

parsepixel avatar Apr 10 '21 17:04 parsepixel

I came up with an idea as I disliked the visually messy $$_var$$caseChange$$. By using the more natural and common use of () every developer will instinctually understand the passing of parameters!

$$var_name would be straight find and replace. 
$$var_(name, transform) that passes two parameters would perform a different method of the find and replace with a case change.

First check if the second parameter is one of the possible case changes and then execute the transform. If not it would just be replaced as is from the input.

From my previous comment made up scenario

/*
Widget Name: $$var_name
*/
class Widget_$$var_(name, constantCase) extends SiteOrigin_Widget {
    function __construct() {
        ...
    }
    siteorigin_widget_register( '$$var_(name, paramCase)', __FILE__, 'Widget_$$var_(name, constantCase)');
}

Thoughts? This way the user is only prompted once for the input for the variable name and then gets transformed as needed throughout the template.

Or just keep the pattern $$var_(x, null) so that $$var_(x) is how the extension currently functions with the optional second parameter for the transform?

parsepixel avatar Apr 10 '21 17:04 parsepixel

@stegano I had that very concern myself about including too much information in the file name. Although I could not come up with a better possible solution and why I wanted to start the conversation with everyone.

I like the idea presented in #20. Correct me if I'm wrong with my logic in walking through the steps. Why would the user need to choose step 3 and select a macro to change the case. The replace action is global and all instances of $$var_[...] will become the input value. So if the user wants to transform Video Testimonial to camel case, why wouldn't they just input videoTestimonial in step 2?

The current solution would be for the user to set up multiple variable for each case type.
 $$var_name -> Video testimonial$$var_class -> Video Testimonial 
$$var_file -> _video-testimonial
_ etc..

What I was purposing was a way to indicate in the template itself at each instance of the $$var a way to know that in this location it should be transformed into the proper case. So one $$var_[...] prompt is displayed once and in each of the locations get transformed as needed by the template, not in the step 3 prompt.

For an example using the string "Video testimonial"
 After getting the input for the variable $$var_name the extension would check for a wrapper or for a following case change function. 
$$var_name$$changePascalCase -> VideoTestimonial
 $$var_name$$changeParamCase -> video-testimonial
 $$var_name$$changeCamelCase -> videoTestimonial

and without any transformation just replace as is
 $$var_name -> Video testimonial

I do agree the additional characters would be visually confusing for someone who is first trying to use the extension but I don't know how else to do it.

The problem is trying to regex pattern what follows the variable for the transformation can't possibly be mistaken as part of the template.

$$var_name(changePascalCase) could potentially be overwrite what was intended as a function(changePascalCase) for some reason.

Hi, @parsepixel 😀 Thanks for your opinion!

Q: if the user wants to transform Video Testimonial to camel case, why wouldn't they just input videoTestimonial in step 2? A: The function defined in macro may not be the function to change the string case! The original function of this template extension is designed to be able to change the string of the pattern specified in template.config.js.

For example, it might be possible to use it like this (I came up with it on the fly).

// tempate.config.js
....
marco: {
  ...
  // Can be processed differently depending on the file name, directory name, and file contents. This functionality is very similar to the existing functionality provided by existing templates.
  ChangeNameFromMyPorjectConvention: (type, variable) => {
     switch(type) {
       case'FILENAME':
       case'DIRECTORY_NAME':
         return change KebabCase(variable);
     }
     return changeCamelCase(variable);
   }
}

I think the macro function can use the existing functions (replaceFileTextFn, replaceFileNameFn) more easily and flexibly. 😀

stegano avatar Apr 11 '21 09:04 stegano

I came up with an idea as I disliked the visually messy $$_var$$caseChange$$. By using the more natural and common use of () every developer will instinctually understand the passing of parameters!

$$var_name would be straight find and replace. 
$$var_(name, transform) that passes two parameters would perform a different method of the find and replace with a case change.

First check if the second parameter is one of the possible case changes and then execute the transform. If not it would just be replaced as is from the input.

From my previous comment made up scenario

/*
Widget Name: $$var_name
*/
class Widget_$$var_(name, constantCase) extends SiteOrigin_Widget {
    function __construct() {
        ...
    }
    siteorigin_widget_register( '$$var_(name, paramCase)', __FILE__, 'Widget_$$var_(name, constantCase)');
}

Thoughts? This way the user is only prompted once for the input for the variable name and then gets transformed as needed throughout the template.

Or just keep the pattern $$var_(x, null) so that $$var_(x) is how the extension currently functions with the optional second parameter for the transform?

That's right, I thought about programming-friendly patterns like $$var_(x, null) like you do.

However, those who actually use it can think of the selection dialog more easily 😭 (I think the reason most people use this extension is because it's easy to use.)

However, I agree that the selection dialog can feel uncomfortable for users who are proficient in programming.

And the following problems may occur, so it would be good to think a little more.

  1. A problem that is difficult to parse is expected because the grammar used in the template extension and the grammar of the actual development code are mixed.

  2. Since the string of the $$var_xxx pattern is composed of valid strings that can be used in actual code, it does not affect code reforming, which I think is a big advantage.

  3. Although incredibly simple, users need to learn the pattern (programming) for template extensions.

  4. If a user-defined name such as ToParamCase is included in the template code, a strong dependency occurs on template.config.js (depending on the usage method, but it would be better to reduce the degree of coupling if possible).

It may be difficult right now, but I will try to think more in a possible way. Thank you so much for the good opinion 😀

stegano avatar Apr 11 '21 10:04 stegano