Skip to content

Commit 006eb1e

Browse files
committed
add name resolving for template file in a overwritten context of "bundle" or "app" #437
1 parent 48d74e5 commit 006eb1e

File tree

5 files changed

+126
-1
lines changed

5 files changed

+126
-1
lines changed

src/fr/adrienbrault/idea/symfony2plugin/TwigHelper.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ private static Collection<PsiFile> getTemplateOverwrites(@NotNull Project projec
273273

274274
// find parent bundles
275275
for (SymfonyBundle symfonyBundle : new SymfonyBundleUtil(project).getBundles()) {
276-
String parentBundle = PhpElementsUtil.getMethodReturnAsString(symfonyBundle.getPhpClass(), "getParent");
276+
String parentBundle = symfonyBundle.getParentBundleName();
277277
if(parentBundle != null && bundle.equals(parentBundle)) {
278278
relativeFile = symfonyBundle.getRelative(String.format("Resources/views/%s", templatePath.substring(i + 7)));
279279
if(relativeFile != null) {

src/fr/adrienbrault/idea/symfony2plugin/templating/util/TwigUtil.java

+50
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,11 @@ public static Map<String, VirtualFile> getTemplateName(TwigFile twigFile, Map<St
363363
}
364364
}
365365

366+
String templateNameByOverwrite = getTemplateNameByOverwrite(twigFile.getProject(), twigFile.getVirtualFile());
367+
if(templateNameByOverwrite != null) {
368+
map.put(templateNameByOverwrite, twigFile.getVirtualFile());
369+
}
370+
366371
return map;
367372
}
368373

@@ -612,4 +617,49 @@ public static String buildStringFromTwigCreateContainer(@NotNull Project project
612617

613618
}
614619

620+
/**
621+
* Gets a template name from "app" or bundle getParent overwrite
622+
*
623+
* app/Resources/AcmeBlogBundle/views/Blog/index.html.twig
624+
* src/Acme/UserBundle/Resources/views/index.html.twig
625+
*/
626+
@Nullable
627+
public static String getTemplateNameByOverwrite(@NotNull Project project, @NotNull VirtualFile virtualFile) {
628+
629+
String relativePath = VfsUtil.getRelativePath(virtualFile, project.getBaseDir());
630+
if(relativePath == null) {
631+
return null;
632+
}
633+
634+
// app/Resources/AcmeBlogBundle/views/Blog/index.html.twig
635+
Matcher matcher = Pattern.compile("app/Resources/([^/]*Bundle)/views/(.*)$").matcher(relativePath);
636+
if (matcher.find()) {
637+
return TwigHelper.normalizeTemplateName(matcher.group(1) + ":" + matcher.group(2));
638+
}
639+
640+
// src/Acme/UserBundle/Resources/views/index.html.twig
641+
SymfonyBundleUtil symfonyBundleUtil = new SymfonyBundleUtil(project);
642+
SymfonyBundle containingBundle = symfonyBundleUtil.getContainingBundle(virtualFile);
643+
if(containingBundle == null) {
644+
return null;
645+
}
646+
647+
String relative = containingBundle.getRelative(virtualFile);
648+
if(relative == null) {
649+
return null;
650+
}
651+
652+
if(!relative.startsWith("Resources/views/")) {
653+
return null;
654+
}
655+
656+
String parentBundleName = containingBundle.getParentBundleName();
657+
if(parentBundleName == null) {
658+
return null;
659+
}
660+
661+
return TwigHelper.normalizeTemplateName(containingBundle.getName() + ":" + relative.substring("Resources/views/".length(), relative.length()));
662+
}
663+
664+
615665
}

src/fr/adrienbrault/idea/symfony2plugin/util/SymfonyBundleUtil.java

+14
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package fr.adrienbrault.idea.symfony2plugin.util;
22

33
import com.intellij.openapi.project.Project;
4+
import com.intellij.openapi.vfs.VirtualFile;
45
import com.intellij.psi.PsiDirectory;
56
import com.intellij.psi.PsiFile;
67
import com.jetbrains.php.PhpIndex;
78
import com.jetbrains.php.lang.psi.elements.PhpClass;
89
import fr.adrienbrault.idea.symfony2plugin.util.dict.SymfonyBundle;
10+
import org.jetbrains.annotations.NotNull;
911
import org.jetbrains.annotations.Nullable;
1012

1113
import java.util.Collection;
@@ -96,6 +98,18 @@ public SymfonyBundle getContainingBundle(PsiFile psiFile) {
9698
return null;
9799
}
98100

101+
@Nullable
102+
public SymfonyBundle getContainingBundle(@NotNull VirtualFile virtualFile) {
103+
104+
for(SymfonyBundle bundle : this.getBundles()) {
105+
if(bundle.isInBundle(virtualFile)) {
106+
return bundle;
107+
}
108+
}
109+
110+
return null;
111+
}
112+
99113
@Nullable
100114
public SymfonyBundle getContainingBundle(PsiDirectory directory) {
101115

src/fr/adrienbrault/idea/symfony2plugin/util/dict/SymfonyBundle.java

+6
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import com.intellij.psi.search.GlobalSearchScope;
88
import com.intellij.psi.search.GlobalSearchScopes;
99
import com.jetbrains.php.lang.psi.elements.PhpClass;
10+
import fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil;
1011
import org.jetbrains.annotations.Nullable;
1112

1213
public class SymfonyBundle {
@@ -171,4 +172,9 @@ public boolean isTestBundle() {
171172
return directory.getVirtualFile().toString().contains("/Tests/");
172173
}
173174

175+
@Nullable
176+
public String getParentBundleName() {
177+
return PhpElementsUtil.getMethodReturnAsString(this.getPhpClass(), "getParent");
178+
}
179+
174180
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package fr.adrienbrault.idea.symfony2plugin.tests.templating.util;
2+
3+
import com.intellij.openapi.vfs.VfsUtil;
4+
import com.jetbrains.twig.TwigFileType;
5+
import fr.adrienbrault.idea.symfony2plugin.templating.util.TwigUtil;
6+
import fr.adrienbrault.idea.symfony2plugin.tests.SymfonyLightCodeInsightFixtureTestCase;
7+
import java.io.File;
8+
9+
public class TwigUtilIntegrationTest extends SymfonyLightCodeInsightFixtureTestCase {
10+
11+
public void setUp() throws Exception {
12+
super.setUp();
13+
14+
createDummyFiles(
15+
"app/Resources/TwigUtilIntegrationBundle/views/layout.html.twig",
16+
"app/Resources/TwigUtilIntegrationBundle/views/Foo/layout.html.twig",
17+
"app/Resources/TwigUtilIntegrationBundle/views/Foo/Bar/layout.html.twig"
18+
);
19+
}
20+
21+
protected String getTestDataPath() {
22+
return new File(this.getClass().getResource("fixtures").getFile()).getAbsolutePath();
23+
}
24+
25+
/**
26+
* @see fr.adrienbrault.idea.symfony2plugin.templating.util.TwigUtil#getTemplateNameByOverwrite
27+
*/
28+
public void testTemplateOverwriteNameGeneration() {
29+
assertEquals(
30+
"TwigUtilIntegrationBundle:layout.html.twig",
31+
TwigUtil.getTemplateNameByOverwrite(getProject(), VfsUtil.findRelativeFile(getProject().getBaseDir(), "app/Resources/TwigUtilIntegrationBundle/views/layout.html.twig".split("/")))
32+
);
33+
34+
assertEquals(
35+
"TwigUtilIntegrationBundle:Foo/layout.html.twig",
36+
TwigUtil.getTemplateNameByOverwrite(getProject(), VfsUtil.findRelativeFile(getProject().getBaseDir(), "app/Resources/TwigUtilIntegrationBundle/views/Foo/layout.html.twig".split("/")))
37+
);
38+
39+
assertEquals(
40+
"TwigUtilIntegrationBundle:Foo/Bar/layout.html.twig",
41+
TwigUtil.getTemplateNameByOverwrite(getProject(), VfsUtil.findRelativeFile(getProject().getBaseDir(), "app/Resources/TwigUtilIntegrationBundle/views/Foo/Bar/layout.html.twig".split("/")))
42+
);
43+
}
44+
45+
/**
46+
* @see fr.adrienbrault.idea.symfony2plugin.templating.util.TwigUtil#getTemplateNameByOverwrite
47+
* @see fr.adrienbrault.idea.symfony2plugin.templating.util.TwigUtil#getTemplateName
48+
*/
49+
public void testTemplateOverwriteNavigation() {
50+
assertNavigationContainsFile(TwigFileType.INSTANCE, "{% extends '<caret>TwigUtilIntegrationBundle:layout.html.twig' %}", "/views/layout.html.twig");
51+
assertNavigationContainsFile(TwigFileType.INSTANCE, "{% extends '<caret>TwigUtilIntegrationBundle:Foo/layout.html.twig' %}", "/views/Foo/layout.html.twig");
52+
assertNavigationContainsFile(TwigFileType.INSTANCE, "{% extends '<caret>TwigUtilIntegrationBundle:Foo/Bar/layout.html.twig' %}", "/views/Foo/Bar/layout.html.twig");
53+
}
54+
55+
}

0 commit comments

Comments
 (0)